Prerequisites
- Authenticated with M2M token (Authentication)
- A DvP settlement template available (browse via
GET /v1/settlement-templates)
Flow overview
Step 1: Submit the seller instruction
Provide the seller’s party details and their legs:trade_reference for the next step.
Step 2: Submit the buyer instruction
Submit the buyer’s counterpart instruction with the same trade reference:status: "matched" and a settlement_id. The settlement is created on-chain and the engine begins processing.
Step 3: Compliance screening
The engine automatically screens all parties through LSEG World-Check (entity) and CipherOwl (wallet). Results are attested to the ComplianceRegistry on-chain. In ~95% of cases, this completes automatically and the settlement advances toCOMPLIANCE_CLEARED.
If a party is flagged, the settlement pauses. Submit a compliance decision to continue:
Step 4: Parties deposit to escrow
Once compliance clears, the settlement reachesAWAITING_DEPOSITS. Both parties deposit their assets directly to the escrow smart contract on-chain. Fetch each deliver leg’s deposit transaction from POST /v1/settlements/{id}/legs/{leg_index}/deposit-calldata - the response carries pre-encoded depositLeg calldata with that leg’s deposit secret embedded - and submit it via your custody provider (such as MPC wallets or any signing infrastructure). The secret is served per leg by this endpoint only; it does not appear in settlement reads.
KeyStone is not involved in the deposit step. The escrow contract verifies keccak256(abi.encode(msg.sender, depositSecret)) == depositKey to authorize each deposit - the key binds both the depositor wallet and the secret, so it can only be redeemed from the wallet it was computed for.
Step 5: Contracts auto-execute and finalize
When all deposits are confirmed, the contracts take over autonomously:- The last deposit triggers execution inline once the compliance gate passes
- The contract verifies the compliance gate and pays every leg to its recipient bound at registration
- Tokens go to the buyer’s wallet, USDC goes to the seller’s wallet
- Settlement transitions to
FINALIZED - Your webhook endpoint receives
settlement.state.finalized