← Back to dashboard
02 Protocol Pattern

Escrow & Refund

Ravi hires an AI video editor through a marketplace. The agent quotes 2.40 USDC for a 90-second cut. Ravi’s phone agent doesn’t just pay and hope — it locks 2.40 into an on-chain escrow with a 2-hour deadline. The editor agent delivers. Ravi’s agent verifies the output, and the escrow releases. If the editor had ghosted? The funds refund automatically after the deadline. No dispute form. No support ticket. Just math.

Trustless escrow is how agents do business with strangers. Lock, deliver, settle — or refund. The native-ETH variant is formalized as an EIP draft.

Four Phases

From deposit to settlement, every escrow follows the same four-phase lifecycle.

Escrow Lifecycle
Phase 1
Deposit & Lock
Caller locks funds into the escrow contract with a deadline and challenge period.
Phase 2
Work Performed
Provider delivers the requested service. Both parties can observe progress on-chain.
Phase 3
Claim or Dispute
Provider claims with a signed receipt. If contested, either side files evidence.
Phase 4
Settlement
Funds release to the provider, or refund if unclaimed past deadline + challenge.

Solidity Surface

Contract Functions

Four entry points

deposit(provider, deadline, challenge)  // lock funds
claim(escrowId, receipt)                 // provider claims
dispute(escrowId, evidence)              // contest delivery
refund(escrowId)                         // after deadline
cancelMutual(escrowId, peerSig)         // mutual cancel
Properties

Trustless by Design

Timeoutconfigurable
Challenge periodconfigurable
Mutual cancelsupported
Oracle releasevia OracleAggregator
Native ETHno wrapper needed
EIP statusdraft submitted

Async Interface

from switchboard.escrow import AgentEscrow

esc = AgentEscrow(network="base-sepolia", contract="0x...")

# caller: lock 0.01 ETH, 1 hour deadline + 1 hour challenge
escrow_id = await esc.deposit(
    provider="0xPeer...",
    value=eth("0.01"),
    deadline=hours("1"),
    challenge=hours("1"),
)

# provider: claim with receipt
await esc.claim(escrow_id, receipt=signed_receipt)