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
| State | Set By | Meaning |
|---|---|---|
| CREATED | P402 API | Escrow record created in DB. Awaiting on-chain funding. |
| FUNDED | Payer | USDC locked in P402Escrow contract. Provider notified. |
| ACCEPTED | Provider | Provider has acknowledged the job and committed to deliver. |
| IN_PROGRESS | Provider | Active work underway. Dispute window not yet open. |
| DELIVERED | Provider | Provider marked delivery. 48-hour dispute window opens. |
| SETTLED | Payer | Payer confirmed delivery. USDC released: 99% to provider, 1% fee to treasury. |
| DISPUTED | Payer | Payer raised a dispute within the window. Admin review triggered. |
| RESOLVED | P402 Admin | Admin resolved dispute — funds sent to provider or refunded to payer. |
| EXPIRED | System | Escrow expired without delivery. Payer can reclaim funds. |
| CANCELLED | Either | Cancelled 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 → DISPUTEDAPI Reference
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v2/escrow | List escrows by address or state |
| POST | /api/v2/escrow | Create 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.