Chio/Docs

Settlement

Every tool invocation in chio has a cost. Settlement is the process of moving capital from the caller to the provider to pay for that cost. chio supports seven settlement rails from CapitalExecutionRailKind (Manual, Api, Ach, Wire, Ledger, Sandbox, Web3), a payment adapter abstraction for off-chain flows, and a full on-chain escrow system for trustless settlement via smart contracts.


Settlement Rails

A settlement rail is the mechanism used to move capital between counterparties. Each rail is represented by a CapitalExecutionRailKind variant in the chio kernel:

RailDescription
ManualHuman-initiated transfers outside the system (invoices, checks). Settlement is recorded manually.
ApiPayment processor integrations (Stripe, Adyen). Pre-authorization and capture via the PaymentAdapter trait.
AchACH bank transfers. Lower cost, higher latency. Suitable for batch settlement.
WireWire transfers for high-value settlements with same-day finality.
LedgerInternal ledger entries between accounts within the same operator. No external capital movement.
SandboxTest rail for development. Simulates settlement without moving real capital.
Web3On-chain settlement. Supports EVM (Base / Arbitrum) via chio-settle/evm.rs, Solana (Ed25519 memo program) via chio-settle/solana.rs, and Chainlink CCIP cross-chain coordination via chio-settle/ccip.rs.

The rail is selected per-invocation based on the operator's configuration, the counterparty's supported rails, and the settlement amount. Most operators start with Sandbox during development and graduate to Api or Web3 in production.


Payment Adapter Integration

For off-chain rails (Api, Ach, Wire), settlement flows through the PaymentAdapter trait. This trait provides a four-method lifecycle for payment processing:

rust
pub trait PaymentAdapter {
    /// Pre-authorize a maximum amount before invocation begins
    async fn authorize(&self, amount: Money, metadata: PaymentMetadata)
        -> Result<PaymentAuthorization>;

    /// Capture the actual cost after invocation completes
    async fn capture(&self, auth: &PaymentAuthorization, amount: Money)
        -> Result<CaptureReceipt>;

    /// Release unused authorization (overage)
    async fn release(&self, auth: &PaymentAuthorization)
        -> Result<ReleaseReceipt>;

    /// Refund a previously captured amount
    async fn refund(&self, capture: &CaptureReceipt, amount: Money)
        -> Result<RefundReceipt>;
}

The authorization object tracks the state of each payment flow:

rust
pub struct PaymentAuthorization {
    pub authorization_id: String,
    pub settled: bool,
    pub metadata: PaymentMetadata,
}

Pre-authorization flow

The standard pattern is: pre-authorize for max_cost_per_invocation before the tool call, capture the actual cost after the call completes, then release the overage. If the actual cost is zero (for example, a cached result), the entire authorization is released with no capture.

Here's the full authorize-capture-release cycle:

rust
// 1. Pre-authorize the maximum possible cost
let auth = adapter.authorize(
    max_cost_per_invocation,
    PaymentMetadata { invocation_id, tool_id, .. }
).await?;

// 2. Execute the tool invocation
let result = invoke_tool(&request).await?;

// 3. Capture the actual cost
let actual_cost = result.metered_cost();
if actual_cost.is_zero() {
    // No cost incurred, release the full authorization
    adapter.release(&auth).await?;
} else {
    adapter.capture(&auth, actual_cost).await?;
    // Overage is automatically released on capture
}

On-Chain Settlement (Web3 Rail)

The Web3 rail settles tool invocation costs on-chain using a suite of smart contracts. This provides trustless settlement where neither party needs to trust the other or a centralized intermediary.

rendering…
Escrow lock, then settle via DualSignature (fast) or MerkleProof (trustless fallback).

Smart Contracts

The on-chain settlement system is composed of five contracts:

ContractRole
ChioEscrowHolds funds in escrow during tool invocations. Supports ERC-20 tokens with permit.
ChioBondVaultManages collateral bonds for credit facilities and autonomous agent execution.
ChioRootRegistryStores merkle roots published by the kernel for checkpoint anchoring.
ChioIdentityRegistryMaps did:chio identifiers to on-chain addresses for settlement routing.
ChioPriceResolverIntegrates oracle price feeds for cross-currency settlement and FX verification.

Settlement Paths

Once funds are locked in ChioEscrow, they can be released through two settlement paths:

  • DualSignature (two-party signed): the operator signs a release message authorizing the provider to withdraw. This is the fast path: settlement completes in a single transaction once both parties agree on the amount.
  • MerkleProof(inclusion-proof from the receipt log): the provider submits a merkle proof showing that the invocation receipt was included in a published checkpoint. This is the trustless path: settlement does not require the operator's cooperation, only a valid proof against a root in ChioRootRegistry.

Choosing a settlement path

DualSignature is preferred for speed. Most settlements complete in seconds. MerkleProof is the fallback for disputes or when the operator is unresponsive. The escrow contract supports both paths on every escrow, so the provider can always escalate to MerkleProof if needed.

Escrow Lifecycle

The lifecycle flows PendingDispatch -> EscrowLocked -> PartiallySettled / Settled / Reversed / ChargedBack / TimedOut:

StateMeaning
PendingDispatchEscrow created but funds not yet locked on-chain
EscrowLockedFunds locked in the ChioEscrow contract, invocation can proceed
PartiallySettledSome funds released to the provider, remainder still held
SettledFull settlement complete, all funds distributed
ReversedEscrow reversed, funds returned to the caller
ChargedBackDispute resolved in caller's favor after settlement
TimedOutEscrow expired without settlement, funds returned to caller

ERC-20 token support uses the EIP-2612 permit pattern, allowing callers to approve and deposit in a single transaction without a separate approval step.


Setting Up an Escrow

Here is a complete example of creating an escrow, executing a tool invocation, and settling via the DualSignature path:

rust
use chio_settlement::{EscrowRequest, SettlementPath, DualSignatureRelease};

// 1. Create and fund the escrow
let escrow = chio_escrow.create_escrow(EscrowRequest {
    caller: caller_address,
    provider: provider_address,
    token: usdc_address,
    amount: max_cost,
    timeout_seconds: 3600,
    invocation_id: invocation_id.clone(),
}).await?;
// State: PendingDispatch -> EscrowLocked

// 2. Execute the tool invocation
let receipt = invoke_tool(&request).await?;
let actual_cost = receipt.metered_cost();

// 3. Operator signs the release for the actual cost
let release = DualSignatureRelease {
    escrow_id: escrow.id,
    amount: actual_cost,
    receipt_hash: receipt.content_hash(),
};
let operator_sig = operator_key.sign(&release.signing_payload());

// 4. Provider submits the dual-signed release on-chain
chio_escrow.settle_dual_sig(release, operator_sig, provider_sig).await?;
// State: EscrowLocked -> Settled

Settling via Merkle Proof

If the operator is unresponsive, the provider can settle using a merkle proof once the receipt has been included in a published checkpoint:

rust
use chio_settlement::{MerkleProofRelease, MerkleInclusionProof};

// 1. Wait for the receipt to be checkpointed
let checkpoint = wait_for_checkpoint(&receipt.id).await?;

// 2. Generate the merkle inclusion proof
let proof = checkpoint.prove_inclusion(&receipt.content_hash())?;

// 3. Submit the proof to the escrow contract
let release = MerkleProofRelease {
    escrow_id: escrow.id,
    amount: actual_cost,
    receipt_hash: receipt.content_hash(),
    proof: MerkleInclusionProof {
        leaf: receipt.content_hash(),
        siblings: proof.siblings,
        index: proof.index,
    },
    checkpoint_root: checkpoint.root,
};

chio_escrow.settle_merkle_proof(release).await?;
// State: EscrowLocked -> Settled

Checkpoint Anchoring

Checkpoints are periodic commitments of receipt history to on-chain registries. The kernel publishes merkle roots to the ChioRootRegistry contract, creating an immutable anchor for the receipt log.

Checkpoint anchoring uses three lanes for defense in depth:

  • EVM primary: merkle root published to ChioRootRegistry on an EVM chain (Ethereum L1 or L2)
  • Bitcoin OpenTimestamps: OpenTimestamps proof anchored to the Bitcoin blockchain for calendar-independent timestamping
  • Solana memo: checkpoint hash written as a Solana memo transaction for fast, low-cost redundancy

A complete proof bundle chains from the individual receipt all the way to the chain anchor:

bash
Receipt (content hash)
  -> Merkle inclusion proof (siblings + index)
    -> Checkpoint statement (root + timestamp + lane)
      -> Chain anchor (tx hash on EVM / BTC / Solana)

Verification is offline-capable

Once you have the proof bundle, verification requires only the chain anchor's transaction data and the merkle math. No kernel access, no API calls: just cryptographic verification against the published root.

Settlement Finality

Settlement finality depends on the chain where the escrow or checkpoint is anchored. Each chain has its own finality semantics:

Finality LevelChainMeaning
L1FinalizedEthereum mainnetTransaction included in a finalized epoch (~12 minutes)
OptimisticL2Optimism, Arbitrum, BaseSoft-confirmed on L2, subject to challenge window for full finality
SolanaConfirmedSolanaConfirmed by supermajority of validators (~400ms)

Dispute windows vary by settlement path:

  • DualSignature: no dispute window. Both parties signed, settlement is final on chain confirmation.
  • MerkleProof: configurable challenge period (default 24 hours) during which the operator can dispute the proof before funds are released.

The full set of settlement lifecycle states covers both successful and exceptional flows:

rust
pub enum SettlementState {
    PendingDispatch,     // Created, awaiting on-chain funding
    EscrowLocked,        // Funded, invocation in progress
    PartiallySettled,    // Partial release completed
    Settled,             // Fully settled
    Reversed,            // Funds returned before settlement
    ChargedBack,         // Dispute resolved post-settlement
    TimedOut,            // Escrow expired without action
    Failed,              // Settlement transaction failed
    Reorged,             // Chain reorganization invalidated settlement
}

Reorg handling

The Reorged state is rare but important. If a chain reorganization invalidates a settlement transaction, the escrow reverts to EscrowLocked and settlement must be retried. The kernel monitors for reorgs on all supported chains and automatically re-submits affected settlements.

Oracle Price Verification

When tool costs are denominated in one currency but settlement occurs in another (for example, costs in USD, settlement in USDC or ETH), the ChioPriceResolver contract provides verified exchange rates via Chainlink price feeds for the USDC/USD, ETH/USD, and BTC/USD pairs.

The price resolver applies several safety mechanisms:

  • Staleness checks: prices older than a configured threshold (for example, 1 hour for major pairs) are rejected. The contract reverts if the feed's latest update is stale.
  • L2 sequencer protection: on L2 chains (Optimism, Arbitrum, Base), the contract checks the Chainlink sequencer uptime feed. If the sequencer was recently down, a grace period is enforced before prices are considered valid.
  • FX evidence: cross-currency settlements must include an FxEvidence record with the rate, source, and timestamp. This evidence is stored on the receipt for auditability.
rust
// Query the on-chain price resolver
let rate = chio_price_resolver.get_rate(
    token_pair,       // e.g., USDC/ETH
    max_staleness,    // e.g., 3600 seconds
).await?;

// Attach FX evidence to the settlement
let fx_evidence = FxEvidence {
    rate: rate.price,
    source: "chainlink".into(),
    feed_address: rate.feed,
    timestamp: rate.updated_at,
    sequencer_status: rate.sequencer_ok,
};

Summary

ConceptDescription
Settlement RailsSeven rails (Manual, Api, Ach, Wire, Ledger, Sandbox, Web3) as CapitalExecutionRailKind variants
PaymentAdapterauthorize, capture, release, refund lifecycle for off-chain rails
On-Chain EscrowChioEscrow contract with DualSignature (fast) and MerkleProof (trustless) settlement paths
Checkpoint AnchoringMulti-lane proofs: EVM primary + Bitcoin OTS + Solana memo
FinalityL1Finalized, OptimisticL2, SolanaConfirmed with chain-specific rules
Price OracleChioPriceResolver with Chainlink feeds, staleness checks, and L2 sequencer protection

Next Steps