Skip to content

Add Peer Cash action provider - #1438

Open
ADWilkinson wants to merge 2 commits into
coinbase:mainfrom
ADWilkinson:feat/peer-cash-action-provider
Open

Add Peer Cash action provider#1438
ADWilkinson wants to merge 2 commits into
coinbase:mainfrom
ADWilkinson:feat/peer-cash-action-provider

Conversation

@ADWilkinson

@ADWilkinson ADWilkinson commented Aug 13, 2026

Copy link
Copy Markdown

Description

Adds a Peer Cash action provider to the TypeScript AgentKit package.

What is Peer Cash

Peer Cash is our offramp SDK for the Peer P2P protocol (peer.xyz), live in production today. An agent's Base USDC becomes fiat in the user's payment app: Venmo, Revolut, Wise, Zelle and more. It is non-custodial: funds only ever sit in the user's wallet or the protocol escrow contract, and orders fill at the live Chainlink rate with zero spread. No API key is required.

What this PR adds

A peerCash action provider with eight actions:

  • estimate: fiat amount for a USDC amount at the live oracle rate. It is an estimate, not a locked quote. The binding rate resolves when a buyer fills.
  • capabilities: payout platforms and their currencies, payee format hints, amount bounds, optional 30 day fill stats.
  • cashout: moves USDC into the escrow contract and creates the order. Handles the follow-up access policy transaction for Venmo, Cash App and PayPal automatically.
  • order_status: lifecycle state by deposit id, with a plain language explanation and the allowed next actions.
  • list_orders: orders owned by a wallet.
  • withdraw: the single unwind verb. Partial with an amount, full close without. Expired buyer intents get pruned automatically.
  • top_up: add USDC to a live order.
  • configure_access_policy: recovery only. Used when a cashout created the deposit but the policy transaction failed, so the agent never doubles up a cash-out.

Plus the provider README, 43 focused unit tests, the package README table entry, a changeset, and the @zkp2p/cash dependency.

Design notes

  • Wallet abstraction: the SDK's signed path wants a viem WalletClient, which an EvmWalletProvider is not guaranteed to expose (CDP server and smart wallets sign remotely). So the provider uses the SDK's unsigned prepare path and submits each returned transaction through walletProvider.sendTransaction in step order, waiting for each receipt. Every agentkit wallet provider works unchanged and signing never leaves your wallet abstraction.
  • Network gating: supportsNetwork is Base mainnet only. The preproduction and staging environments also settle on Base mainnet with separate contracts, so the gate holds for all three.
  • Errors: the SDK throws typed errors with a stable code, a retryable flag and a remediation sentence. The provider surfaces all of it so the agent can recover instead of guessing. A reverted step is reported with its step kind and hash, and a failed access policy points at the recovery action instead of letting the agent create a second deposit for the same funds.
  • @zkp2p/cash declares node >= 22, same as this repo's dev requirement. The unit tests mock the SDK, so the node 18/20 CI matrix is unaffected.
  • The lockfile regen also drops a stale examples/register importer that no longer exists in the tree. Any pnpm install reproduces that, and the check-package-lock job wants it committed.

Config

const provider = peerCashActionProvider({
  environment: "production", // default; also "preproduction" | "staging"
  referralCode: "ABC123", // optional, earns the integration share
  referrer: "acme-app", // optional, analytics-only attribution
  rpcUrl: "https://mainnet.base.org", // optional Base RPC override
});

No API keys required. The provider works with zero config.

How integrators earn

referralCode is the six character code from the Peer mobile or web app. When set, every deposit carries ERC-8021 attribution (peer-ref-ABC123) and the code owner earns 50 bps each time an order fills. The mapping is permanent. referrer is separate: analytics-only attribution, no revenue share.

Tests

From typescript/:

  • pnpm install: lockfile stable, no diff after install
  • pnpm run test (turbo, all packages): 11/11 tasks pass

From typescript/agentkit:

  • pnpm test: 61 suites, 900 tests pass on the initial integration revision
  • 43 focused Peer Cash tests pass on the current head
  • pnpm run lint: pass
  • pnpm run format:check: pass
  • pnpm run check: pass
  • pnpm run build: pass

Live read-only smoke test of the built provider against production (no wallet or keys needed):

Network: Base Mainnet
Setup: production environment, read actions only

estimate 250 USDC -> EUR:
Approximately 216.8 EUR for 250 USDC at the current oracle rate of 0.8672161926607495
(zero spread). This is not a locked quote; the binding rate resolves when a buyer fills.
Estimated time to first fill: Usually starts in about 1 hr.

estimate with an unsupported currency:
Error (ORACLE_UNSUPPORTED_CURRENCY) while estimating the cash-out: XXX has no live
Chainlink oracle feed; Peer Cash is market-rate only. Remediation: Pick a currency
listed in capabilities() - each one is priced by a live oracle feed. Retryable: no.

capabilities with fill stats:
"revolut:EUR": { "fills": 518, "medianFillSeconds": 3142 }, ...

The mutating actions (cashout, withdraw, top_up, configure_access_policy) are covered by unit tests against a mocked SDK and wallet provider, including transaction order, reverted steps and the access policy failure path.

Checklist

  • Added documentation to all relevant README.md files
  • Added a changelog entry

Links

SDK → https://www.npmjs.com/package/@zkp2p/cash
Docs → https://docs.peer.xyz/developer/peer-cash
Prompt → https://peer.xyz/cash-sdk
Builders Club → https://t.me/zk_p2p/167174

Support

Support is available through the Builders Club above or @AndrewWilkinson on X.

@cb-heimdall

cb-heimdall commented Aug 13, 2026

Copy link
Copy Markdown

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

@github-actions github-actions Bot added documentation Improvements or additions to documentation action provider New action provider typescript labels Aug 13, 2026
@ADWilkinson
ADWilkinson force-pushed the feat/peer-cash-action-provider branch from d5271e4 to 16ad580 Compare August 13, 2026 10:11
@ADWilkinson
ADWilkinson force-pushed the feat/peer-cash-action-provider branch from f3f5d01 to e07535c Compare August 14, 2026 13:20
@ADWilkinson

Copy link
Copy Markdown
Author

Quality review update:

  • hardened transaction recovery so receipt timeouts preserve submitted hashes and never trigger a blind duplicate cash-out
  • preserved confirmed prior steps across partial failures, including access-policy recovery after deposit confirmation
  • distinguished smart-wallet submission hashes from Base transaction hashes and record the mined Base hash when the receipt exposes it
  • tightened deposit ID and positive-amount validation

Current validation: 43 focused tests pass, plus TypeScript, ESLint, and Prettier. Both commits are GitHub-verified. The PR is mergeable; the remaining gates are maintainer review and the external StepSecurity check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action provider New action provider documentation Improvements or additions to documentation typescript

Development

Successfully merging this pull request may close these issues.

2 participants