feat: Peer Cash actions for non-custodial USDC to fiat on Base - #33
Open
ADWilkinson wants to merge 1 commit into
Open
feat: Peer Cash actions for non-custodial USDC to fiat on Base#33ADWilkinson wants to merge 1 commit into
ADWilkinson wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
@zkp2p/cash, MIT, https://github.com/zkp2p/peer-cash#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_cashoutthat submits throughwallet.sendTransaction, say so on the issue and I will add it here.Custody
Every mutating verb returns UNSIGNED
{ to, data, value, chainId }forsend_transactionto submit. No action in this PR accepts, reads, derives, or stores a private key, and@zkp2p/cashexposes no signing path in the surface these actions use. The order belongs to whichever address submits the transactions.Files
agentkit-core/src/actions/PeerCashAction/client.tscapabilities.tspeer_cash_capabilitiesestimate.tspeer_cash_estimateprepareCashout.tspeer_cash_prepare_cashout[approve, createDeposit]prepareAccessPolicy.tspeer_cash_prepare_access_policyorder.tspeer_cash_orderorders.tspeer_cash_ordersprepareTopUp.tspeer_cash_prepare_topup[approve, addFunds]prepareWithdraw.tspeer_cash_prepare_withdrawindex.tsPEER_CASH_ACTIONSAll eight are
walletOptional: trueandsmartAccountRequired: false, so they run in platform mode, self-custody mode, and with no wallet configured.peer_cash_ordersis the only one that reads the wallet, and only to default the address.Also changed:
agentkit-core/src/actions/index.ts: registersPEER_CASH_ACTIONS.agentkit-core/package.json: adds@zkp2p/cash, and runs the new smoke test fromtest:smoke.agentkit-core/tsconfig.json:"target": "es2022". The neweroxthat viem resolves to ships.tssources needingString.replaceAlland theErrorcauseoption, sobun run checkfails ates2020. Scoped to this file rather thantsconfig.base.json.agentkit-core/test/peer-cash.smoke.mjs: new, in the style ofplatform.smoke.mjs.bun.lock.Test plan
bun run check: exit 0bun run build: exit 0biome lintandbiome checkon the new directory: cleanbun run lint: same 30 pre-existing errors asmain, none inPeerCashActionbun run test:smoke: bothPLATFORM SMOKEandPEER CASH SMOKEpassPEER_CASH_SMOKE_LIVE=1 node test/peer-cash.smoke.mjs: passes against Peer productionThe new smoke test is offline by default, covering registration, wallet-optional dispatch, argument schemas, and the typed error surface.
PEER_CASH_SMOKE_LIVE=1adds production reads and one unsigned cash-out plan;PEER_CASH_SMOKE_ORDER_IDadds 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_cashoutreturned[approve, createDeposit]both withchainId: 8453;peer_cash_prepare_topupreturned[approve, addFunds];peer_cash_prepare_withdrawreturned a singlewithdrawDeposit;peer_cash_prepare_access_policyreturned one transaction; a nonexistent order id returnedError: Peer Cash order failed. [ORDER_NOT_FOUND] ... This error is retryable.Notes
supportedChainswith USDC intokenMappings. Prepared transactions carrychainId: 8453, so submitting them needs an agent configured on Base. The read actions work on any chain.referrer: "0xgasless-agentkit", an ERC-8021 analytics marker appended to the calldata suffix beside thepeer-cashmarker the SDK adds regardless. It carries no funds and grants no permissions. Happy to drop it.PEER_CASH_RPC_URLoverrides the public Base RPC, which is rate limited.PEER_CASH_REFERRAL_CODEis the operator's own six-character Peer code. Both are optional and read the same waysxt.tsreadsSXT_API_KEY.