KeyStone uses smart contract escrow with a commitment-based deposit scheme to ensure atomic settlement while preserving pre-execution privacy. Parties deposit their assets directly to the escrow contract using a deposit secret. The contract detects when all deposits are complete, notifies the SettlementCoordinator, and the coordinator callsDocumentation Index
Fetch the complete documentation index at: https://docs.keystoneos.xyz/llms.txt
Use this file to discover all available pages before exploring further.
executeSettlement with recipient addresses (revealed only at execution time) to release deposits autonomously.
How it works
1. Settlement reaches AWAITING_DEPOSITS
After compliance clears, the settlement advances toAWAITING_DEPOSITS. At this point, the API response includes a deposit_secret and deposit_key for each leg with direction: "deliver".
2. Parties deposit using their secret
Each party deposits to the escrow contract on-chain by callingdepositLeg(settlementId, legIndex, depositSecret). The platform’s backend uses its custody provider (such as MPC wallets or any signing solution) to construct and sign the deposit transaction.
KeyStone is NOT involved in deposits. The escrow contract handles everything:
- Verifies
keccak256(depositSecret) == leg.depositKey- the caller knows the secret - Validates the leg has not already been deposited
- Validates token allowance is sufficient
- Emits a
LegDepositedevent
Deposit authorization is based on knowledge of the deposit secret, not on
msg.sender. Any address that knows the secret and has sufficient token balance can deposit for that leg. This preserves pre-execution privacy on public chains - party addresses are only revealed on-chain at deposit time, not at settlement creation.3. Escrow auto-notifies coordinator
When the escrow contract detects that all legs for a settlement have been deposited, it automatically notifies the SettlementCoordinator:- Same-chain: Direct call to
notifyDepositsComplete() - Cross-chain: LayerZero message
4. Coordinator auto-executes with recipient reveal
The coordinator verifies the atomicity gate (allLegsDeposited == true) and calls executeSettlement(settlementId, recipients[]) on the escrow contract. Recipient addresses are revealed only at this point - they are not stored on-chain during settlement registration. This means:
- Tokens from the seller’s leg go to the buyer’s wallet
- Tokens from the buyer’s leg go to the seller’s wallet
- Fees (if configured) are sent to fee recipient addresses
5. Rollback protection
If the settlement times out or fails:- The coordinator dispatches rollback instructions to all escrow contracts
- All deposits are returned to their original depositors (the address that submitted the deposit transaction)
- No partial execution is possible
- Anyone can trigger timeout permissionlessly after the deadline
Commitment scheme overview
The commitment scheme replaces address-based deposit authorization with cryptographic secrets:| Concept | Description |
|---|---|
deposit_secret | Random 32-byte hex string generated by the API per leg |
deposit_key | keccak256(deposit_secret) - stored on-chain at registration |
| Authorization | keccak256(callerSecret) == storedDepositKey |
| Privacy benefit | Party addresses are hidden until deposit transaction. Recipient addresses are hidden until execution. |
Deposit flow for platforms
From your platform’s perspective:- You receive a webhook:
settlement.state.awaiting_deposits - Query the settlement via
GET /v1/settlements/{id}- the response includesdeposit_secretanddeposit_keyon each leg - For each leg where your party has
direction: "deliver", construct a deposit transaction:- Approve the escrow contract to spend the token
- Call
depositLeg(settlementId, legIndex, depositSecret)on the escrow contract
- Your custody provider signs and broadcasts the transaction
- The escrow contract verifies the secret and accepts the deposit
- When all deposits are complete, contracts auto-execute
- You receive a webhook:
settlement.state.finalized
Integration example
Monitoring deposit status
Check deposit progress by querying the settlement:Timeout behavior
Every settlement has atimeout_at deadline. If all deposits are not received by this time:
- Settlement transitions to
TIMED_OUT - Escrow contract returns any received deposits to their original depositors
- All platforms are notified via webhook
claimTimeout() on the KeystoneEscrow after the deadline, regardless of whether KeyStone’s services are running.
Fees
If the platform has a fee agreement configured, fees are included in the on-chain leg registration asFeeSpec entries. The escrow contract deducts fees during execution and transfers them to the configured recipients. See Smart Contracts - KeystoneEscrow for details on how fees work at the contract level.
Token standards
| Standard | Support | Release mechanism |
|---|---|---|
| ERC-20 | Full | Standard transfer() |
| ERC-3643 | Full | forcedTransfer() via transfer agent role |