Skip to main content

Peer Cash SDK

@zkp2p/cash is Peer's opinionated, offramp-only TypeScript SDK. It lets a wallet, application, Node service, or agent route a supported EVM asset into Base USDC and offer that USDC to buyers who pay the cashing-out user through supported fiat payment platforms.

The package deliberately compresses the protocol into a small lifecycle: discover, estimate, cash out, observe, top up, or withdraw. It is built for products that need cash-out without taking ownership of the full maker, taker, proof, vault, and rate-management surface in @zkp2p/sdk.

UPI on staging

UPI cash-out accepts any syntactically valid UPI ID, regardless of the seller's bank. The seller does not connect a bank account, install an extension, or complete an account-registration flow. Buyers currently prove UPI payments from HDFC Bank through read-only Gmail access. UPI remains staging-only and must stay behind the product's UPI rollout flag until production contracts support it.

The cashing-out user is the maker

Peer Cash does not reverse the protocol. The user creates a Base USDC deposit at the live market rate. A buyer signals an intent, pays the user fiat, and proves that payment with TEE-TLS. The protocol releases the corresponding USDC after the proof is verified.

Peer Cash SDK or ZKP2P SDK?

The two packages serve different integration depths.

Peer Cash SDKZKP2P SDK
Package@zkp2p/cash@zkp2p/sdk
Best forA focused crypto-to-fiat cash-out productA custom integration with the Peer protocol
User roleMaker onlyMaker, taker, or both
PricingLive Chainlink rate at fill, always zero spreadApplication-controlled protocol configuration
Asset pathBase USDC by default; optional Relay-supported EVM source into Base USDCDirect protocol and API primitives selected by the integrator
WorkflowOpinionated order lifecycle and recovery modelDeposits, intents, fulfillment, quotes, proofs, vaults, rate managers, hooks, referrals, and helpers
Signingviem signer or unsigned Base-USDC transaction plansDirect and prepared protocol transactions
React@zkp2p/cash/react@zkp2p/sdk/react
Agent toolingJSON-schema manifest from @zkp2p/cash/toolsBuild the tool surface you need from the general SDK

Choose Peer Cash when cash-out is the product. Choose the ZKP2P SDK when your application needs to compose protocol operations or control behavior that Peer Cash intentionally does not expose.

How a cash-out works

Optional EVM source asset

│ Relay route

Base USDC deposit at zero spread

│ buyer signals an intent

Buyer pays the maker through a supported fiat app

│ TEE-TLS payment proof

Protocol releases USDC to the buyer

The destination is always canonical USDC on Base. Starting with Base USDC is the minimal path. When the user starts elsewhere, Peer Cash discovers and executes a live Relay route before creating the Base USDC order.

Funds are held by the protocol contracts, not by the SDK or a hosted off-ramp provider. The SDK never holds keys. The maker can withdraw unmatched funds; if a buyer intent expires unpaid, withdraw() handles the required pruning before returning the available USDC.

Installation

Install Peer Cash with viem:

npm install @zkp2p/cash viem
# or
yarn add @zkp2p/cash viem
# or
pnpm add @zkp2p/cash viem
# or
bun add @zkp2p/cash viem

Install @zkp2p/cash@latest. Node integrations require Node 22 or newer. React 18 or newer is an optional peer dependency used only by @zkp2p/cash/react.

Quick start

import { createCashClient, usdc } from "@zkp2p/cash";

const cash = createCashClient({ environment: "production" });

const capabilities = cash.capabilities();
const chime = capabilities.platforms.find(
({ platform }) => platform === "chime",
);

if (!chime?.currencies.includes("USD")) {
throw new Error("Chime USD is not available in this environment");
}

const estimate = await cash.estimate({
amount: usdc(100),
currency: "USD",
platform: "chime",
});

console.log(`Approximately ${estimate.receiveAmount} USD`);

const result = await cash.cashout(
{
amount: usdc(100),
receive: {
platform: "chime",
currency: "USD",
payee: { offchainId: "$your-chime-sign" },
},
},
{ signer },
);

await saveCashOrder({
userId,
depositId: result.depositId,
transactionHash: result.txHash,
});

For a flagged staging UPI cash-out, discover upi/INR from capabilities() and pass the seller's normal VPA directly:

const cash = createCashClient({
environment: "staging",
features: { upi: true },
});
const upi = cash
.capabilities()
.platforms.find(({ platform }) => platform === "upi");

if (!upi?.currencies.includes("INR")) throw new Error("UPI is not enabled");

await cash.cashout(
{
amount: usdc(25),
receive: {
platform: "upi",
currency: "INR",
payee: "seller@bank",
},
},
{ signer },
);

signer is a viem WalletClient connected to Base with an account. Persist the returned depositId immediately. It is the durable resume key for order(), watch(), topUp(), and withdraw().

Every Peer Cash deposit uses the paid intent guardian. Venmo and PayPal additionally restrict intent signaling to Peer Pay merchants. Generic cashout() creates the deposit and then confirms one method-scoped access policy per restricted payout method. The custody-separated prepare() path returns the same methods in accessPolicyPaymentMethods for the host to submit after finalization. requiresAtomicAccessPolicy is retained only for wire compatibility and is always false; do not use it for control flow. Peer web can batch deposit creation and policy setup atomically through Curator.

Access restriction and dispute protection are separate. Protection defaults on only for methods whose live on-chain risk window is nonzero. That currently means Venmo and PayPal. Cash App is non-chargebackable, stays public, and does not use stake-backed admission.

A single order can offer more than one way to get paid: a leg can list several currencies (currencies: ["EUR", "GBP"]), and receive accepts an array of legs across different platforms, each platform at most once. Every option fills at the live zero-spread oracle rate. See the integration guide for the multi-leg example.

An estimate is not a locked quote

estimate() reads the relevant Chainlink feed and may include a historical fill-time estimate. The binding exchange rate is the oracle rate when a buyer fills the order. Display the value as approximate, honor estimate.stale, and do not present the ETA as a guarantee.

The lifecycle

Every order state is reconstructed from protocol data.

StateMeaningTypical next action
awaiting-buyerThe deposit is live and no buyer has an active intentWait, top up, or withdraw
matchedA buyer has signaled and the relevant USDC is lockedWait for payment and proof, or for the intent to expire
deliveringPart of the order has been fulfilled while more remains activeContinue observing
deliveredFiat was proven and the filled USDC was releasedReconcile the verified fill data
returnedRemaining funds were withdrawn to the makerTerminal

Use order.nextActions and order.explain() rather than inventing local state transitions. watch(depositId) streams changes until the order becomes terminal or the watch is stopped. orders(owner, { inFlight: true }) rebuilds an active-order list for a wallet.

Purpose-built entry points

Entry pointUse it for
@zkp2p/cashDiscovery, estimates, signed operations, unsigned plans, order reads, codecs, and typed errors
@zkp2p/cash/reactuseEstimate, useCashout, useOrder, and useOrders
@zkp2p/cash/toolsJSON-schema tool definitions for an agent host, CLI, or policy-controlled signer

Peer Cash also applies ERC-8021 attribution to every protocol transaction. Pass your own analytics code with createCashClient({ referrer: "your-app" }); the SDK retains peer-cash as the first attribution code. To earn the deposit-level integration share, pass the six-character code from your Peer referral screen as referralCode. See Earn from the flow you bring.

What Peer Cash intentionally does not expose

Peer Cash has no API for custom spreads, buyer-side intents or proofs, disputes, Seller Autopilot, vaults, delegated rate management, or arbitrary contract operations. Those are not missing features in the cash-out SDK; they are the boundary that keeps it safe and predictable.

For those integrations, use the ZKP2P SDK overview and client reference.

Next step

Continue to the Peer Cash integration guide for signed and unsigned transaction paths, Relay source routing, React hooks, error recovery, and staging verification.

Resources: