> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tplus.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# Deposit and withdrawal reconciliation

> Match vault events, account events, inventory snapshots, and nonce counters.

Deposits and withdrawals reconcile across three surfaces:

1. Onchain vault event.
2. OMS account-activity event.
3. Inventory delta from `GET /inventory/user/{user_id}`.

## Deposit join keys

Vault deposit events include user, nonce, token address, and amount. OMS account activity emits:

```json theme={null}
{
  "DepositLanded": {
    "user": "<user public key>",
    "asset": "200",
    "amount": "1000000000000000000",
    "chain_id": "<chain id>",
    "deposit_nonce": 12,
    "timestamp_ns": 1760000000000000000
  }
}
```

Stable join key: `(user, chain_id, deposit_nonce)`. Compare the account event `amount` against the inventory delta in 18-decimal internal units. Use the registry decimals to convert onchain token base units to internal units.

Raw reconciliation:

```bash theme={null}
curl -H "Authorization: Bearer $TOKEN" -H "User-Id: $USER_ID" \
  https://oms.tplus.cx/inventory/user/$USER_ID
```

```text theme={null}
wss://oms.tplus.cx/account/events/<user_id>
```

## Withdrawal join keys

A withdrawal starts with `POST /withdrawal/init`, enters `GET /withdrawal/queue/{user_id}`, receives quorum approvals, then the user submits `withdraw(...)` on the vault. Completion emits:

```json theme={null}
{
  "WithdrawalCompleted": {
    "user": "<user public key>",
    "asset": "200",
    "amount": "1000000000000000000",
    "chain_id": "<chain id>",
    "withdrawal_nonce": 7,
    "timestamp_ns": 1760000000000000000
  }
}
```

Stable join key: `(user, chain_id, withdrawal_nonce)`. The vault call carries token address, amount, nonce, target, `validUntil`, `epochHash`, and approval signatures; get exact fields from the live [OMS reference](https://oms.tplus.cx/api-reference) and [Deposit Vault](/contracts/deposit-vault#withdrawals).

## tpluspy

```python theme={null}
from tplus.client import OrderBookClient

async with OrderBookClient(user=user, base_url="https://oms.tplus.cx") as oms:
    before = await oms.get_user_inventory()
    async for event in oms._stream_ws(f"/account/events/{user.public_key}", lambda data: data):
        after = await oms.get_user_inventory()
        reconcile(before, event, after)
        before = after

    queued = await oms._request("GET", f"/withdrawal/queue/{user.public_key}")
```

If a submission times out, do not assume failure. Read the queue, account events, and inventory before retrying with a new nonce.
