Docs / Escrow

Escrow

Conditional USDC escrow on Base. Lock funds on-chain, release only on confirmed delivery. Built for agent-to-agent commerce.

Deployed Contract

Network
Base Mainnet (8453)
P402Escrow
0x4596c0e69d08e4ca6f02c7a129fc2bff8a6905ac
Protocol Fee
1% → P402 Treasury

State Machine

CREATED → FUNDED → ACCEPTED → IN_PROGRESS → DELIVERED → SETTLED / DISPUTED → RESOLVED

StateSet ByMeaning
CREATEDP402 APIEscrow record created in DB. Awaiting on-chain funding.
FUNDEDPayerUSDC locked in P402Escrow contract. Provider notified.
ACCEPTEDProviderProvider has acknowledged the job and committed to deliver.
IN_PROGRESSProviderActive work underway. Dispute window not yet open.
DELIVEREDProviderProvider marked delivery. 48-hour dispute window opens.
SETTLEDPayerPayer confirmed delivery. USDC released: 99% to provider, 1% fee to treasury.
DISPUTEDPayerPayer raised a dispute within the window. Admin review triggered.
RESOLVEDP402 AdminAdmin resolved dispute — funds sent to provider or refunded to payer.
EXPIREDSystemEscrow expired without delivery. Payer can reclaim funds.
CANCELLEDEitherCancelled before funding. No funds moved.

Quick Start

1. Create escrow
POST /api/v2/escrow
Content-Type: application/json

{
  "payer_address":    "0xYourWallet",
  "provider_address": "0xProviderWallet",
  "amount_usd":       25.00,
  "reference_id":     "job_abc123",
  "description":      "Logo design — 3 variants"
}
2. Response
{
  "id":               "escrow_6a6f625f...",
  "state":            "CREATED",
  "amount_usd":       25.00,
  "amount_usdc":      "25000000",
  "payer_address":    "0xYourWallet",
  "provider_address": "0xProviderWallet",
  "created_at":       "2026-03-23T00:00:00Z"
}
3. Transition state
POST /api/v2/escrow/{id}
{ "action": "fund", "tx_hash": "0x..." }   // payer funds on-chain
{ "action": "accept" }                      // provider accepts
{ "action": "start" }                       // provider starts work
{ "action": "deliver", "proof_hash": "0x..." } // provider delivers
{ "action": "release" }                     // payer releases → SETTLED
{ "action": "dispute" }                     // payer disputes → DISPUTED

API Reference

MethodEndpointDescription
GET/api/v2/escrowList escrows by address or state
POST/api/v2/escrowCreate a new escrow
GET/api/v2/escrow/[id]Get escrow details + event log
POST/api/v2/escrow/[id]Transition state: fund | accept | start | deliver | release | dispute

All endpoints require authentication. Dispute resolution (resolve action) is admin-only in V1.

Dispute Window

Window Duration
48 hrs

After the provider marks DELIVERED, the payer has 48 hours to either release funds or raise a dispute. After the window closes without action, the provider may claim payment.

Resolution
All-or-nothing

V1 dispute resolution is admin-mediated. P402 reviews evidence bundles and calls resolve(id, toProvider) on-chain — either 99% to provider or full refund to payer.