Skip to content

feat: Peer Cash actions for non-custodial USDC to fiat on Base - #33

Open
ADWilkinson wants to merge 1 commit into
0xgasless:mainfrom
ADWilkinson:peer-cash-actions
Open

feat: Peer Cash actions for non-custodial USDC to fiat on Base#33
ADWilkinson wants to merge 1 commit into
0xgasless:mainfrom
ADWilkinson:peer-cash-actions

Conversation

@ADWilkinson

Copy link
Copy Markdown

Implements #32. Adds eight Peer Cash actions so an agent can turn its Base USDC into fiat.

Peer Cash is an offramp protocol on Base. The agent's wallet is the maker: its USDC becomes a protocol-held order, a buyer pays fiat to the agent's own Venmo, Revolut, Wise, Zelle, PayPal, Cash App, Chime, or Monzo handle and proves the payment with TEE-TLS, and the escrow releases the USDC at the live Chainlink oracle rate with zero spread.

#32 asks whether you want prepare-only or an additional signing verb. This PR is the prepare-only shape. If you would rather have a one-shot peer_cash_cashout that submits through wallet.sendTransaction, say so on the issue and I will add it here.

Custody

Every mutating verb returns UNSIGNED { to, data, value, chainId } for send_transaction to submit. No action in this PR accepts, reads, derives, or stores a private key, and @zkp2p/cash exposes no signing path in the surface these actions use. The order belongs to whichever address submits the transactions.

Files

agentkit-core/src/actions/PeerCashAction/

File Action What it does
client.ts shared client, typed error formatting, USDC amount parsing
capabilities.ts peer_cash_capabilities platforms, currencies, payee formats, amount bounds
estimate.ts peer_cash_estimate fiat at the live oracle rate, plus a 30-day median fill ETA
prepareCashout.ts peer_cash_prepare_cashout unsigned [approve, createDeposit]
prepareAccessPolicy.ts peer_cash_prepare_access_policy the follow-up Venmo, Cash App, and PayPal orders require
order.ts peer_cash_order one order's state, fills, and next actions
orders.ts peer_cash_orders orders for an address, defaulting to the agent's own
prepareTopUp.ts peer_cash_prepare_topup unsigned [approve, addFunds]
prepareWithdraw.ts peer_cash_prepare_withdraw unsigned transactions that unwind an order
index.ts barrel and PEER_CASH_ACTIONS

All eight are walletOptional: true and smartAccountRequired: false, so they run in platform mode, self-custody mode, and with no wallet configured. peer_cash_orders is the only one that reads the wallet, and only to default the address.

Also changed:

  • agentkit-core/src/actions/index.ts: registers PEER_CASH_ACTIONS.
  • agentkit-core/package.json: adds @zkp2p/cash, and runs the new smoke test from test:smoke.
  • agentkit-core/tsconfig.json: "target": "es2022". The newer ox that viem resolves to ships .ts sources needing String.replaceAll and the Error cause option, so bun run check fails at es2020. Scoped to this file rather than tsconfig.base.json.
  • agentkit-core/test/peer-cash.smoke.mjs: new, in the style of platform.smoke.mjs.
  • bun.lock.

Test plan

  • bun run check: exit 0
  • bun run build: exit 0
  • biome lint and biome check on the new directory: clean
  • bun run lint: same 30 pre-existing errors as main, none in PeerCashAction
  • bun run test:smoke: both PLATFORM SMOKE and PEER CASH SMOKE pass
  • PEER_CASH_SMOKE_LIVE=1 node test/peer-cash.smoke.mjs: passes against Peer production

The new smoke test is offline by default, covering registration, wallet-optional dispatch, argument schemas, and the typed error surface. PEER_CASH_SMOKE_LIVE=1 adds production reads and one unsigned cash-out plan; PEER_CASH_SMOKE_ORDER_ID adds order and list reads. It never signs or broadcasts.

Live results from getAllAgentkitActions() with no wallet configured: discovery returned 8 payout platforms across 13 currencies on chain 8453 at 0 bps spread; a 250 USDC estimate returned 215.67 EUR at 0.8627 with a 40 minute ETA; peer_cash_prepare_cashout returned [approve, createDeposit] both with chainId: 8453; peer_cash_prepare_topup returned [approve, addFunds]; peer_cash_prepare_withdraw returned a single withdrawDeposit; peer_cash_prepare_access_policy returned one transaction; a nonexistent order id returned Error: Peer Cash order failed. [ORDER_NOT_FOUND] ... This error is retryable.

Notes

  • Peer Cash settles on Base (8453) only, which is already in supportedChains with USDC in tokenMappings. Prepared transactions carry chainId: 8453, so submitting them needs an agent configured on Base. The read actions work on any chain.
  • The client is constructed with referrer: "0xgasless-agentkit", an ERC-8021 analytics marker appended to the calldata suffix beside the peer-cash marker the SDK adds regardless. It carries no funds and grants no permissions. Happy to drop it.
  • PEER_CASH_RPC_URL overrides the public Base RPC, which is rate limited. PEER_CASH_REFERRAL_CODE is the operator's own six-character Peer code. Both are optional and read the same way sxt.ts reads SXT_API_KEY.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant