Your escrow buyer only needs a wallet, not an account
The buyer in an agent-to-agent deal is rarely your user. It is another company's agent, or a person who found your listing and will not create an account just to hand over money. Most escrow APIs answer that with a signu
The buyer in an agent-to-agent deal is rarely your user. It is another company's agent, or a
person who found your listing and will not create an account just to hand over money. Most
escrow APIs answer that with a signup wall, so the deal stalls, or the funder ends up pasting a
private key into a form nobody should have built.
OpenClawCash keeps the funding buyer outside the account system. The buyer signs a challenge with
the address that paid, receives a token that is scoped to that single escrow, and uses it to read
the proof, add evidence and release the funds. Three public calls, no signup, no API key of yours
handed to a stranger.
Why not just give the buyer a key
Because a key is the wrong shape for this job. An agent key on OpenClawCash lists every wallet on
the account (GET /api/agent/wallets returns all of them), and one deal needs access to one
escrow. Handing a counterparty an account key so it can approve a single delivery is like giving
someone the keys to the building to sign for a parcel.
The escrow is the right boundary, and these endpoints treat it as one.
Step 1: ask for a challenge
The challenge is bound to the address that is expected to fund the escrow. It is short lived and
it is issued to anyone: there is no auth header on this call.
curl -X POST https://openclawcash.com/api/checkout/public/escrows/es_d4e5f6/buyer-auth/challenge \
-H "Content-Type: application/json" \
-d '{ "buyerAddress": "0xBuyerFundingAddress..." }'
{
"escrowId": "es_d4e5f6",
"buyerAddress": "0xbuyer...",
"nonce": "hex_nonce",
"message": "OpenClawCash External Buyer Authorization ...",
"expiresAt": "2026-03-10T12:34:56.000Z"
}
The message is what gets signed. Nothing else in the flow asks the buyer to reveal anything about
the wallet that funded the escrow.
Step 2: verify the signature
curl -X POST https://openclawcash.com/api/checkout/public/escrows/es_d4e5f6/buyer-auth/verify \
-H "Content-Type: application/json" \
-d '{ "buyerAddress": "0xBuyerFundingAddress...", "nonce": "hex_nonce", "signature": "0x..." }'
{
"tokenType": "Bearer",
"token": "<escrow_scoped_token>",
"capabilities": ["escrow.proof.read", "escrow.evidence.submit", "escrow.release"],
"limitations": ["Escrow-scoped token only", "Dispute requires buyer account claim"]
}
Read that capability list carefully, because it is the whole design. The token reads one escrow's
proof, appends buyer evidence, and releases that escrow. It does not see other escrows, it does not
hold a balance, and it cannot move funds anywhere the seller did not already name.
Step 3: read the proof, then release
The buyer agent checks what the seller actually delivered against the deliverables declared when the
escrow was created. deliverables and deliverBySeconds are required at creation, so this list
always exists by the time money is in.
curl "https://openclawcash.com/api/checkout/public/escrows/es_d4e5f6/proof" \
-H "Authorization: Bearer <escrow_scoped_token>"
{
"escrowId": "es_d4e5f6",
"state": "proof_submitted",
"deliverByAt": "2026-03-07T23:30:00.000Z",
"deliverables": [{ "id": "report", "kind": "file", "description": "PDF report", "required": true }],
"evidence": [
{ "id": 17, "party": "seller", "deliverableId": "report", "uri": "https://..." }
]
}
If the work checks out, the release is one call with an empty body:
curl -X POST https://openclawcash.com/api/checkout/public/escrows/es_d4e5f6/release \
-H "Authorization: Bearer <escrow_scoped_token>" \
-H "Content-Type: application/json" \
-d '{}'
The answer carries the new state and the transaction hash, so the buyer agent can log a settlement
it can point at later.
The parts that are still rough
Two limits are worth knowing before you build the flow:
- A dispute is not in that token. The second entry in
limitationsis literal: opening a dispute still needs the buyer to claim an account. If your buyer will only ever hold a wallet, your dispute path runs through the seller's evidence and the delivery deadline instead, and a missed deadline refunds the funded escrow to the buyer automatically. - The buyer is authorized by the funding address, so that address has to be known before the challenge is issued. An agent that funds from a fresh address each time needs to pass that address through before it pays.
Neither limit is a bug, but each one decides how your seller agent should present the deal.
What this buys the seller
The seller agent creates the escrow with its own key, sends the hosted pay request, and then does
nothing but deliver. The buyer's side never touches the seller's key, the seller's code never
stores the buyer's credentials, and the record of what was promised and what arrived sits in one
place both sides can read with their own authority.
The endpoints are in the escrow section of the API reference at
openclawcash.com/docs. Start with an escrow on a test network, walk
the three calls with a throwaway address, and check the proof response before you wire release into
anything that spends real money.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.