EconomyCost & Settlement
On-Chain Settlement
Web3 settlement uses five contracts, two release paths, and a nine-state escrow lifecycle on EVM and Solana.
Use this page when
Where this fits
economy view of on-chain settlement. The chain-by-chain integration reference (which networks, which assets, gas profiles) lives in Integrations / Settlement. The chio-side rail abstraction lives in Settlement Rails.The Five Contracts
Every chio Web3 deployment ships the same five interfaces, addressed as Web3ContractKind in chio-web3. Chain-specific addresses live in the per-chain Web3ChainDeployment, but the ABI and the role of each contract are stable.
| Contract | Role |
|---|---|
ChioRootRegistry | Anchors checkpoint roots published by the kernel. Every merkle release verifies a leaf against a root that has already been registered here. |
ChioEscrow | Locks funds against a capability commitment. Holds the dispatch reference, the agreed amount, and the lifecycle state. Settles via dual signature or merkle proof. |
ChioBondVault | Holds bonds (operator collateral, agent collateral) that back high-trust capabilities. Bonds can be released, expired, or impaired against a slashing event. |
ChioIdentityRegistry | Binds chio public keys to on-chain settlement addresses. The contract checks that the binding the operator presents has the correct purpose (“settle”, “publish”) and chain scope. |
ChioPriceResolver | Returns FX prices from the configured oracle when a receipt is denominated in a non-native asset. Used by escrow on release to compute the settlement amount in the chain's settlement token. |
Bindings ship as Rust types in chio-web3-bindings, with Solidity ABIs versioned alongside the kernel. The chio-settle/src/evm/ module drives these contracts and records on-chain state in the receipt records.
Payment Channels build on this same ChioEscrow: one bounded deposit is funded up front, many high-frequency low-value calls stream against a single cumulative signed amount, and the channel settles once at cooperative or contested close rather than dispatching a separate escrow per call.
Two Settlement Paths
Once an escrow is locked, releasing it is a choice between two paths. The kernel encodes the choice in Web3SettlementPath:
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Web3SettlementPath {
DualSignature,
MerkleProof,
}DualSignature (Fast Path)
Both parties sign the release. The provider signs an EIP-712 digest binding the receipt hash, the observed amount, and the escrow id; the contract recovers the signature and credits the beneficiary. Latency is a single block confirmation; gas matches a normal token transfer plus a digest verification.
Use when the buyer remains online and cooperative. This is the common path: agent calls tool, tool returns, buyer counter-signs the release, funds settle, total wall-clock is one block.
MerkleProof (Trustless Fallback)
The provider produces an inclusion proof: this receipt is a leaf in a published merkle tree, the root of which has been registered in ChioRootRegistry. The escrow contract verifies the proof against the root and releases without ever needing the buyer's signature.
Use when the buyer has gone offline, is uncooperative, or simply cannot sign within the dispute window. The trade is a heavier transaction (one merkle verification plus a root lookup) and a longer wall-clock (the receipt has to be in a checkpoint that has already been published, which is bounded by the operator's checkpoint cadence).
The roots themselves are anchored by the chio-anchor crate, which publishes signed checkpoint statements containing checkpoint_seq, batch_start_seq, batch_end_seq, tree_size, and the merkle root. A merkle release proof can be verified from the chain-registered root and the receipt's leaf hash; the verifier does not need to trust the operator.
Settlement path is chosen per dispatch
Escrow Lifecycle States
The kernel's view of an escrow's state is Web3SettlementLifecycleState in chio-web3. Nine variants:
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Web3SettlementLifecycleState {
PendingDispatch,
EscrowLocked,
PartiallySettled,
Settled,
Reversed,
ChargedBack,
TimedOut,
Failed,
Reorged,
}| State | Meaning |
|---|---|
pending_dispatch | A signed dispatch record exists; no on-chain transaction has been observed. |
escrow_locked | Funds locked in ChioEscrow; awaiting release. |
partially_settled | A partial release has paid out; remainder still locked. |
settled | Release executed; funds delivered to beneficiary; finality confirmed. |
reversed | Refund executed before release; funds returned to depositor. |
charged_back | Post-settlement reversal; an off-chain dispute clawback has been recorded. |
timed_out | Dispute window expired without release; refund recovery is the next action. |
failed | On-chain submission reverted; the dispatch needs to be retried or escalated. |
reorged | A previously confirmed settlement has been undone by a chain reorg; resubmission required. |
On-chain terminal states and kernel records
ChioEscrow contract itself has two predeclared, price-free terminal outcomes: release-on-proof (either settlement path above) or refund-after-deadline. The contract has no admin, pause, or emergency path. The nine-variant Web3SettlementLifecycleState above, including ChargedBack and Reversed, is kernel-side records of settlement outcomes, including off-chain disputes and reorg handling. They do not give the escrow contract discretionary power. charged_back is not an on-chain clawback: the contract has already reached a terminal outcome when the kernel records that state. Web3SettlementSupportBoundary.real_dispatch_supported defaults to false, and no mainnet deployment is authorized while it does.Lifecycle Diagram
EVM Support
EVM coverage lives in the chio-settle/src/evm/ module, organized into mod.rs, types.rs (the Prepared* request and response types), prepare.rs (the prepare_* constructor), and finalize.rs (the confirm and finality helpers). Dispatch and release calls are constructed as PreparedEvmCall values (from_address, to_address, data, optional gas limit) ready for an external signer to sign and broadcast.
The supported entry points cover the full lifecycle:
prepare_web3_escrow_dispatch: build aPreparedEscrowCreatefrom a signed capital-execution instruction.prepare_dual_sign_release: build aPreparedDualSignReleasewith the EIP-712 digest pre-signed by the operator key.prepare_merkle_release: build aPreparedMerkleReleasecarrying the receipt leaf hash, the root, and the proof path.prepare_escrow_refund: build the refund call once the dispute window expires.prepare_bond_lock/prepare_bond_release/prepare_bond_impair: drive theChioBondVaultover its lifecycle.prepare_erc20_approval: emit the ERC-20approve()call needed before the escrow can pull tokens.
State-changing calls are signed by an external wallet or signer service; the Chio kernel does not hold transaction private keys. The exception is the operator's signing key for dual-signature digests, which is presented as a hex-encoded private key only at the call site that produces the digest.
The shipped deployment templates target two EVM environments: Base (eip155:8453) as the primary execution and anchoring environment, and Arbitrum One (eip155:42161) as the bounded secondary. The integration page lists per-chain details. Finality is captured as Web3FinalityMode (OptimisticL2, L1Finalized, SolanaConfirmed) per deployment, with a minimum-confirmation count attached.
No mainnet deployment is authorized yet
Solana Support
Solana support covers local verification and instruction preparation. chio-settle does not broadcast a Solana transaction, run an on-chain Solana program, or index the cluster. Code lives in chio-settle/src/solana.rs.
The dispatch model is narrower than EVM: there is no escrow contract holding funds during execution. prepare_solana_settlement verifies the receipt and binding, then emits a PreparedSolanaSettlement carrying the receipt signature, the Ed25519 program id (Ed25519SigVerify111111111111111111111111111), the chio public key, and a canonical chio.settle.solana-release.v1 instruction payload in instruction_data_hex. An external submitter assembles and broadcasts the transaction that pairs the native Ed25519 signature check with the SPL token transfer; chio-settle prepares and verifies the transaction but does not broadcast it. compare_commitments reconciles the prepared commitment against the observed one and reports a CommitmentConsistencyReport for parity checks.
pub struct PreparedSolanaSettlement {
pub dispatch_id: String,
pub chain_id: String,
pub cluster: String,
pub program_id: String,
pub payer_address: String,
pub beneficiary_address: String,
pub settlement_mint: String,
pub capability_commitment: String,
pub receipt_hash: String,
pub settlement_amount_minor_units: u64,
pub recent_blockhash: String,
pub ed25519_program_id: String,
pub ed25519_signature: String,
pub chio_public_key: String,
pub instruction_data_hex: String,
pub note: Option<String>,
}The kernel-side helper verify_solana_binding_and_receipt confirms the binding has the settle purpose, the chain scope covers the target chain, and the settlement address decodes as a valid base58 Solana address before allowing the dispatch to be prepared.
Cross-Chain via Chainlink CCIP
For settlements that span chains (settle on Base, but the depositor funded escrow from Arbitrum, say) the kernel ships a CCIP message envelope in chio-settle/src/ccip.rs. It is not a bridge; it is a typed coordination layer over Chainlink's Cross-Chain Interoperability Protocol that lets a settlement event on one chain to be reconciled with state on another.
pub struct CcipLaneConfig {
pub source_chain_id: String,
pub destination_chain_id: String,
pub router_address: String,
pub max_payload_bytes: usize,
pub max_execution_gas: u64,
pub expected_latency_secs: u64,
}
pub enum CcipMessageStatus {
Prepared,
Reconciled,
DuplicateSuppressed,
Delayed,
Unsupported,
}prepare_ccip_settlement_message validates the lane (source != destination, payload bounds non-zero, validity window at least twice the expected latency), then assembles a payload containing the dispatch id, execution receipt id, settlement reference, lifecycle state, settled amount, and beneficiary address. reconcile_ccip_delivery cross-checks the SHA-256 digest of the delivered payload against the digest the kernel originally signed.
Use CCIP when:
- The escrow chain and the bond vault chain are different (operator on Ethereum, escrow on Base).
- A multi-chain operator needs one settlement event delivered to several treasury locations.
- The integration partner already speaks CCIP and won't accept a bespoke bridge.
For typical single-chain flows, plain EVM dispatch on the same chain is simpler and cheaper. The full Chainlink integration view lives at Integrations / Chainlink.
Worked Example
An agent calls a tool that costs 1.50 USDC. The capability is bound to the Web3 rail on Base with aDualSignature path.
Happy Path: DualSignature
- Kernel signs a capital-execution instruction for 1.50 USDC.
prepare_web3_escrow_dispatchbuilds aPreparedEscrowCreate. - Operator's signer broadcasts the dispatch tx. The escrow contract locks 1.50 USDC. State:
EscrowLocked. - Tool runs. Observed cost matches the quoted 1.50 USDC.
- Operator presents
prepare_dual_sign_releaseto the buyer. Buyer counter-signs the EIP-712 digest. - Combined signatures broadcast to the contract; release executes; funds credited to beneficiary. State:
Settledafter the configured confirmation count is reached.
Total wall-clock from tool completion to settled status: a single block confirmation on Base, typically two seconds.
Fallback: MerkleProof
Same scenario, but the buyer goes offline before counter-signing.
- State remains
EscrowLockeduntil the dispute window opens for an alternate release. - The kernel publishes a checkpoint covering the receipt; the merkle root is registered in
ChioRootRegistryby the anchor pipeline. - Operator calls
prepare_merkle_releasewith the receipt leaf hash, the registered root, and the proof path computed against the checkpoint tree. - Contract verifies the proof against the registered root, confirms inclusion, and releases funds. State:
Settled. - If the dispute window expires without either path succeeding, the watchdog flips the state to
TimedOutand the next recovery action isExecuteRefund(the depositor gets their funds back).
Fallback latency is bounded by checkpoint cadence
Checkpoint Anchoring
A Merkle release proof depends on the root it verifies. Roots come from chio-anchor: the kernel publishes batched checkpoints as Web3CheckpointStatement statements containing batch bounds, tree size, root, kernel public key, and signature. The anchor publishes those statements to theChioRootRegistry on each target chain so that any verifier (regulator, auditor, dispute resolver) can independently verify the inclusion proof.
ChioRootRegistry is one of four anchoring methods in chio-anchor ships. A merkle release depends only on the EVM registry, but the same batched checkpoint can be anchored by several methods for defense in depth:
- EVM root registry (
evm.rs):prepare_root_publication/confirm_root_publicationagainst theChioRootRegistrycontract. A Merkle release verifies against this method. - Bitcoin via OpenTimestamps (
bitcoin.rs):prepare_ots_submission/verify_ots_proof_for_submission. - Solana memo (
solana.rs):prepare_solana_memo_publication/verify_solana_anchor. - Chainlink Functions (
functions.rs): an off-chain attestation fallback.
Proof-bundle verification fails closed. verify_proof_bundle rejects the whole bundle if any single lane is bad; verify_proof_bundle_with_discovery adds freshness checks. A bad anchor invalidates the bundle; there is no partial pass.
The receipt-side proof record is Web3ReceiptInclusion with checkpoint_seq, merkle_root, and the proof path. verify_anchor_inclusion_proof in chio-web3 (the anchors module) is the authoritative verifier; Web3CheckpointStatement and Web3ReceiptInclusion are chio-web3 types re-exported through chio-anchor.
Finality and Recovery
Finality is observed via SettlementFinalityAssessment in chio-settle/src/observe.rs. Each chain configures a required confirmation count and a dispute window in seconds. Status is one of:
awaiting_confirmations: tx mined but not yet at the required depth.awaiting_dispute_window: confirmed, but the optimistic challenge window is open.finalized: confirmation count and dispute window both satisfied.reorged: a previously confirmed tx is no longer in the canonical chain.
Recovery actions (SettlementRecoveryAction, seven variants) map onto the finality assessment and lifecycle state. While a tx is short of the required depth the action is WaitForConfirmations; while the optimistic challenge window is open it is WaitForDisputeWindow. Failed suggests RetrySubmission; TimedOut suggests ExecuteRefund; Reorged suggests ResubmitAfterReorg. The remaining variants are ManualReview and ExpireBond for the bond-vault lifecycle. The watchdog (next page) drives this automation.
Payments and Operational Controls
The escrow lifecycle above is the on-chain settlement core, but chio-settle carries two more settlement-adjacent modules in the same crate.
The payments module prepares the account-level payment rails that sit beside escrow dispatch:
build_x402_payment_requirements: assemble an x402 HTTP-402 payment requirement.prepare_transfer_with_authorization: build an EIP-3009 transfer-with-authorization call.evaluate_circle_nanopayment: evaluate a Circle nanopayment.prepare_paymaster_compatibility: check ERC-4337 paymaster compatibility.
The ops module gates settlement operations behind an emergency-mode switch. SettlementEmergencyMode has five states ( Normal, DispatchPaused, RefundOnly, RecoveryOnly, and Halted) and ensure_settlement_operation_allowed checks the requested operation against the active mode before any dispatch, release, or refund is permitted. An operator can freeze new dispatches while still allowing refunds, or halt the rail entirely, without touching signed receipt truth.
See Also
- Settlement Rails for the full rail enum and the off-chain alternatives.
- Reconciliation & Watchdog for the cycle that closes out partially-settled and timed-out escrows.
- Receipts for the receipt fields that participate in merkle inclusion.
- Chainlink for the CCIP integration in depth.
- Integrations / Settlement for chain-by-chain configuration and finality details.