Custody model
Ripar is non-custodial, and in a stronger sense than the word usually carries: there is no Ripar-operated service in the payment path at all. The SDK is a library you run, and settlement is a direct USDC transfer between two Algorand addresses.
Where funds actually sit
| Moment | Who holds the funds |
|---|---|
| Before a call | The caller's wallet |
| While the endpoint quotes | Still the caller's wallet — nothing has moved |
| While the facilitator verifies | Still the caller's wallet |
| On settlement | The payTo address, directly |
| If the handler fails | The caller's wallet — nothing was ever taken |
The last row is the one worth internalising. @x402/express buffers the response and
only settles after the handler returns a success status; a 4xx or 5xx cancels
settlement. So a failed call is not refunded, it is never charged in the first place.
What holds no funds
- Your agent process. It needs no wallet and no signing key. A compromised container cannot move your money, because the money never passes through it.
- The registries. The three Algorand contracts — identity, reputation, validation —
hold no assets. The ValidationRegistry records a job's
budget_microas a number in a box; it never receives, holds or transfers USDC. - The facilitator. It verifies and submits the transfer the caller signed. It is not a destination.
Everywhere else in Ripar, settlement is direct and nothing takes custody. Job escrow is
the exception, and it only happens if the client calls fund_job.
When they do, the ValidationRegistry's own account holds the asset until
release_escrow pays the assignee on a passing verdict, or refund_escrow returns it
on a failed or cancelled one. The amount is read off a transfer in the same atomic
group rather than trusted from an argument, and the escrow box is cleared before the
transfer is submitted, so the same escrow cannot be paid twice.
After the dispute window, anyone may release. That path is the point: a validator who never returns would otherwise freeze the worker's money for good, and a lock with no key is not escrow, it is confiscation.
A job with no fund_job behind it holds nothing, and its budget stays what it always
was — a stated intention. See Jobs & validation.
What Ripar does hold
Nothing of yours. There is no account, no session token and no server-side record — because there is no server. The metadata that exists is either in your own process (the run buffer, the metrics counters) or on a public chain (the registry boxes), and the latter is readable by anyone, including you, without going through us.
Keys
Signing happens where the key already is:
- Earning side: no key.
serve()never signs anything. - Paying side:
RiparClientsigns in your process, from a mnemonic or secret key you supply through the environment. - On-chain writes: the MCP server composes transactions and returns them unsigned. A human or wallet signs and broadcasts.
Non-custodial means nobody can take your funds or lose them in someone else's failure.
It does not mean an agent you configured badly cannot spend them, and it does not mean
a wrong payTo can be recovered — defineAgent checks that an address is 58 base32
characters, not that it is yours. Paste it from your wallet, never retype it. See
spend caps, and note where they are enforced.