> ## 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.

# Settlement integration

> Registry discovery, signed init, approval retrieval, vault execution, and event confirmation.

Settlement lets an approved executor use vault liquidity atomically: one token leaves the vault, the executor performs venue logic, and the expected token returns to the vault.

## Flow

1. Discover vaults and assets through OMS registry endpoints, especially `GET /registry/vaults`.
2. Build and sign a settlement init request.
3. Submit `POST /settlement/init`.
4. Read the approval from the `POST /settlement/init` response, or fetch outstanding user signatures with `GET /settlement/signatures/{user_id}`.
5. Executor calls `executeAtomicSettlement(...)` on the vault.
6. Reconcile the vault `Settled` event and OMS inventory/account events.

## Raw init

Settlement request amounts are hex integer strings without a `0x` prefix. Use the live [OMS reference](https://oms.tplus.cx/api-reference) for exact current wrappers.
Populate `signature` with the Ed25519 signature bytes over compact `inner` before sending.

```json theme={null}
{
  "inner": {
    "tplus_user": "<user public key>",
    "sub_account_index": 1,
    "settler": "<settler public key>",
    "mode": "margin",
    "asset_in": "<32-byte token-in id>",
    "amount_in": "de0b6b3a7640000",
    "asset_out": "<32-byte token-out id>",
    "amount_out": "de0b6b3a7640000",
    "chain_id": "<chain id>"
  },
  "signature": [],
  "nonce": null,
  "additional_signers": []
}
```

If outer `nonce` is omitted or `null`, the backend selects the next managed settlement nonce for that `(user, sub_account, chain)`. If you set one explicitly, it must not collide with an in-flight lock, and the single-settlement vault call requires the exact current `(user, account)` settlement counter.

## tpluspy

```python theme={null}
from tplus.client import OrderBookClient
from tplus.model.settlement import InnerSettlementRequest, TxSettlementRequest

inner = InnerSettlementRequest.from_raw(
    tplus_user=user.public_key,
    sub_account_index=1,
    settler=settler.public_key,
    mode="margin",
    asset_in=asset_in_32,
    amount_in=10**18,
    decimals_in=18,
    asset_out=asset_out_32,
    amount_out=10**18,
    decimals_out=18,
    chain=chain_id,
)
request = TxSettlementRequest.create_signed(inner, user)

async with OrderBookClient("https://oms.tplus.cx", default_user=user) as oms:
    response = await oms._request(
        "POST",
        "/settlement/init",
        json_data=request.model_dump(mode="json", exclude_none=True),
    )
    approval = response["approval"]
```

## Approval delivery

`POST /settlement/init` returns an `approval` object on success. `GET /settlement/signatures/{user_id}` returns outstanding approval signatures for that user.
Use the REST response or the signatures endpoint as the public integration path. There is no public settlement-approval WebSocket route today.

## Vault execution

The caller must be the executor registered for the `settler` id. The vault verifies expiry, settler approval, executor binding, nonce, and the CE approval signature, then increments the settlement nonce before the callback. It then calls the executor callback:

```solidity theme={null}
function onAtomicSettlement(address token, uint256 amount, bytes calldata data)
    external returns (uint256);
```

After the callback returns `expectedAmountIn`, the vault pulls `tokenIn` from the executor with `transferFrom`, then transfers `tokenOut` to the executor. The executor must approve the vault for at least the returned `tokenIn` amount before or during callback execution.

```solidity theme={null}
tokenIn.approve(address(vault), expectedAmountIn);
vault.executeAtomicSettlement(order, settler, data, signature);
```

Single atomic settlement is the available production flow. The vault ABI includes batch and squashing functions, but batch/squashing settlement is planned and not available through the public integration path today; use `executeAtomicSettlement`.
