@zkp2p/cash 0.1.0-dev.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -28,7 +28,7 @@ the Base builder code.
28
28
 
29
29
  - **Wise and PayPal** carry `requiresIdentityAttestation: true`. Their curator
30
30
  registration needs a signed maker identity attestation this SDK cannot mint
31
- (it comes from the ZKP2P app/extension). A bare-handle `cashout()` to these
31
+ (it comes from the Peer app/extension). A bare-handle `cashout()` to these
32
32
  fails fast with `PAYEE_VERIFICATION_REQUIRED` before any transaction.
33
33
  - **Venmo, Revolut, Cash App, Monzo** validate the handle against the live
34
34
  platform at registration - the account must exist. The rest (Zelle, Chime,
@@ -98,7 +98,7 @@ Every `CashError` carries `code`, `retryable`, `remediation`. Behavior:
98
98
  | `ORACLE_UNSUPPORTED_CURRENCY` | no | Re-pick currency from `capabilities()` |
99
99
  | `UNSUPPORTED_PLATFORM` | no | Re-pick platform from `capabilities()` |
100
100
  | `AMOUNT_BELOW_MINIMUM` | no | Raise amount (hard floor $0.01, recommended ≥ 1 USDC) |
101
- | `PAYEE_VERIFICATION_REQUIRED` | no | Wise/PayPal need a signed identity attestation - register the payee via the ZKP2P app first |
101
+ | `PAYEE_VERIFICATION_REQUIRED` | no | Wise/PayPal need a signed identity attestation - register the payee via the Peer app first |
102
102
  | `PAYEE_REGISTRATION_FAILED` | yes | Validate handle against `payeeHint`, retry with backoff (curator caps at 20 registrations/min) |
103
103
  | `ALLOWANCE_NOT_VISIBLE` | yes | Approve mined but a stale RPC replica hid it; retry the same call in a few seconds |
104
104
  | `TRANSACTION_FAILED` | no | The on-chain call reverted or was mapped from a raw error; surface to operator; funds unchanged |
package/README.md CHANGED
@@ -6,10 +6,12 @@ provider.
6
6
 
7
7
  Peer Cash is an **offramp-only** SDK for the [ZKP2P](https://peer.xyz)
8
8
  protocol. The cashing-out user is the maker: their USDC becomes a
9
- protocol-held deposit, ZKP2P handles the buyer side, and the SDK gives the
9
+ protocol-held deposit, Peer handles the buyer side, and the SDK gives the
10
10
  integrator a small set of typed verbs plus readable order state. No hosted
11
11
  widget, no provider custody, no quote engine to maintain.
12
12
 
13
+ **[Live demo](https://react-cashout-demo.vercel.app)** · **[Product page](https://peer.xyz/cash)**
14
+
13
15
  ```ts
14
16
  import { createCashClient, usdc } from '@zkp2p/cash';
15
17
 
@@ -39,7 +41,6 @@ for await (const order of cash.watch(depositId)) {
39
41
  | `capabilities()` | Sync discovery: platforms × currencies × payee format hints × amount bounds |
40
42
  | `estimate({ amount, currency })` | Live oracle rate - no payee, no side effects, idempotent |
41
43
  | `cashout(input, { signer })` | Registers your payee, creates the protocol-held order, returns the `depositId` |
42
- | `prepare(input)` | Same as cashout but returns unsigned `txs[]` + readable `steps[]` - agent wallets, AA, server keys |
43
44
  | `order(depositId)` / `orders(owner)` | Resume any order from its id alone; list all orders for a wallet |
44
45
  | `watch(depositId)` | Async iterator: yields on every state change until terminal, abort, or timeout |
45
46
  | `withdraw(depositId, { signer, amount? })` | The ONE unwind verb - partial with an `amount` (live intents don't block it), full close without (prunes expired intents first) |
@@ -71,7 +72,7 @@ awaiting-buyer ──────────► matched ───────
71
72
  ```
72
73
 
73
74
  - **You are the maker.** Your deposit is priced by the live Chainlink oracle
74
- with `spreadBps: 0`, making it the best offer on the book by construction.
75
+ with `spreadBps: 0`, making it the best price a rational maker can offer.
75
76
  - **There is no quote.** The binding rate resolves at the oracle when a buyer
76
77
  fills. `estimate()` says "approximately"; nothing in this API pretends to
77
78
  lock a price.
@@ -121,9 +122,16 @@ options. v1 is same-chain only: Base USDC in.
121
122
  ## Install
122
123
 
123
124
  ```sh
124
- npm install @zkp2p/cash@dev viem
125
+ npm install @zkp2p/cash viem
125
126
  ```
126
127
 
128
+ ## Examples
129
+
130
+ Runnable first-party examples in [`examples/`](examples):
131
+
132
+ - [`node-cashout.ts`](examples/node-cashout.ts) - server-side cash-out with a private-key signer, plus order tracking.
133
+ - [`agent-tool-use.ts`](examples/agent-tool-use.ts) - wiring the verbs into an agent tool-use loop with host-side signing.
134
+
127
135
  ## Trust model, honestly
128
136
 
129
137
  This SDK is open source, so the code that constructs the parameters moving
package/dist/tools.cjs CHANGED
@@ -137,7 +137,7 @@ var cashTools = [
137
137
  ];
138
138
  var cashToolManifest = {
139
139
  name: "@zkp2p/cash",
140
- version: "0.1.0-dev.0",
140
+ version: "0.1.1",
141
141
  description: "Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.",
142
142
  tools: cashTools
143
143
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tools/index.ts"],"names":[],"mappings":"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","file":"tools.cjs","sourcesContent":["/**\n * `@zkp2p/cash/tools` - JSON-schema tool definitions of the verbs, so\n * agent hosts (peer-cli, zkp2p-mcp, any MCP server or tool-use loop) adopt\n * Peer Cash without re-deriving schemas.\n *\n * Design rules:\n * - Mutating verbs default to the **prepare path**: the tool returns unsigned\n * transactions plus readable step labels; signing stays host-side, where key\n * custody and policy live.\n * - Every input/output is plain JSON (bigints as decimal strings) - see the\n * codecs exported from the package root for lossless (de)serialization.\n * - `watch` is intentionally not a tool: agents poll `cash_order` between\n * other work instead of holding a streaming connection open.\n */\n\nexport interface CashToolDefinition {\n name: string;\n description: string;\n /** JSON Schema (draft-07 compatible) for the tool input. */\n inputSchema: Record<string, unknown>;\n}\n\nconst bigintString = {\n type: 'string',\n pattern: '^[0-9]+$',\n description: 'USDC base units (6 decimals) as a decimal string, e.g. \"1000000000\" for 1000 USDC',\n} as const;\n\nconst depositId = {\n type: 'string',\n description: 'Composite deposit id (escrow_onchainId) returned by cash_cashout - the resume key',\n} as const;\n\nexport const cashTools: CashToolDefinition[] = [\n {\n name: 'cash_capabilities',\n description:\n 'Discover what Peer Cash can do: payout platforms, oracle-priced currencies per platform, payee handle format hints, and amount bounds. Static and side-effect free - call this first.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n },\n {\n name: 'cash_estimate',\n description:\n 'Estimate fiat received for a USDC amount at the live oracle market rate. No payee, no side effects, no expiry - the binding rate resolves at the oracle when a buyer fills, so this is always \"approximately\", never a committed quote.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n currency: {\n type: 'string',\n description: 'Fiat currency code from cash_capabilities, e.g. \"USD\"',\n },\n },\n required: ['amount', 'currency'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_cashout',\n description:\n 'Start a cash-out: registers the payee with the curator and returns UNSIGNED transactions plus same-index steps [approve, createDeposit] for the host to sign and submit (prepare path - signing stays host-side). After submission, parse the depositId from the DepositReceived event or find it via cash_orders, then track with cash_order.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n receive: {\n type: 'object',\n description: 'Where the fiat should arrive',\n properties: {\n platform: {\n type: 'string',\n description: 'Platform id from cash_capabilities, e.g. \"venmo\"',\n },\n currency: { type: 'string', description: 'Fiat currency code, e.g. \"USD\"' },\n payee: {\n type: 'object',\n description: 'Payee handle for the platform',\n properties: {\n offchainId: {\n type: 'string',\n description:\n 'The handle, e.g. \"@andrew\" for Venmo - see payeeHint in cash_capabilities',\n },\n },\n required: ['offchainId'],\n additionalProperties: true,\n },\n },\n required: ['platform', 'currency', 'payee'],\n additionalProperties: false,\n },\n },\n required: ['amount', 'receive'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_order',\n description:\n 'Observe one cash-out order by depositId - fully resumable, no session state. Returns state (awaiting-buyer | matched | delivering | delivered | returned), amounts, fills, and nextActions (wait | withdraw). Errors are typed with retryable + remediation; ORDER_NOT_FOUND right after cashout means indexer lag - retry in a few seconds.',\n inputSchema: {\n type: 'object',\n properties: { depositId },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_orders',\n description:\n 'List all cash-out orders for a wallet address (the chain is the database - a cash order IS a deposit, keyed by depositor). Use inFlight=true for only the orders still needing attention.',\n inputSchema: {\n type: 'object',\n properties: {\n owner: { type: 'string', description: 'The maker wallet address (0x...)' },\n inFlight: {\n type: 'boolean',\n description: 'Only awaiting-buyer / matched / delivering orders',\n },\n limit: { type: 'number', description: 'Max deposits to scan (default 100)' },\n },\n required: ['owner'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_buyer',\n description:\n 'Look up a buyer\\'s protocol track record from their full intent history: lifetime intents, fulfilled vs pruned counts, success rate (bps), first/last seen. Use during the matched state to answer \"who just committed to my order?\".',\n inputSchema: {\n type: 'object',\n properties: {\n address: { type: 'string', description: 'The buyer (taker) wallet address (0x...)' },\n },\n required: ['address'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_withdraw',\n description:\n 'Unwind a cash-out: returns UNSIGNED transaction(s) plus same-index steps (prepare path - signing stays host-side). With amount: partial withdrawal of the unlocked balance (a live buyer intent does not block it). Without amount: closes the order fully, state-aware - when the only live intents have expired it includes a pruneExpiredIntents transaction first; while a live buyer intent locks funds it fails with ACTIVE_INTENT_BLOCKS_WITHDRAWAL (retryable - wait for expiry).',\n inputSchema: {\n type: 'object',\n properties: {\n depositId,\n amount: {\n ...bigintString,\n description:\n 'Optional partial amount (USDC base units, decimal string). Omit to close the order fully.',\n },\n },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_topup',\n description:\n 'Add USDC to a live cash-out order (same payee, same market rate). Returns UNSIGNED transactions plus same-index steps [approve, addFunds] for the host to sign and submit in order. Fails with ORDER_NOT_ACTIVE if the order is already delivered or returned.',\n inputSchema: {\n type: 'object',\n properties: { depositId, amount: bigintString },\n required: ['depositId', 'amount'],\n additionalProperties: false,\n },\n },\n];\n\n/** Manifest wrapper with versioning for host registries. */\nexport const cashToolManifest = {\n name: '@zkp2p/cash',\n version: '0.1.0-dev.0',\n description:\n 'Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.',\n tools: cashTools,\n} as const;\n\nexport type CashToolName = (typeof cashTools)[number]['name'];\n"]}
1
+ {"version":3,"sources":["../src/tools/index.ts"],"names":[],"mappings":"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","file":"tools.cjs","sourcesContent":["/**\n * `@zkp2p/cash/tools` - JSON-schema tool definitions of the verbs, so\n * agent hosts (peer-cli, zkp2p-mcp, any MCP server or tool-use loop) adopt\n * Peer Cash without re-deriving schemas.\n *\n * Design rules:\n * - Mutating verbs default to the **prepare path**: the tool returns unsigned\n * transactions plus readable step labels; signing stays host-side, where key\n * custody and policy live.\n * - Every input/output is plain JSON (bigints as decimal strings) - see the\n * codecs exported from the package root for lossless (de)serialization.\n * - `watch` is intentionally not a tool: agents poll `cash_order` between\n * other work instead of holding a streaming connection open.\n */\n\nexport interface CashToolDefinition {\n name: string;\n description: string;\n /** JSON Schema (draft-07 compatible) for the tool input. */\n inputSchema: Record<string, unknown>;\n}\n\nconst bigintString = {\n type: 'string',\n pattern: '^[0-9]+$',\n description: 'USDC base units (6 decimals) as a decimal string, e.g. \"1000000000\" for 1000 USDC',\n} as const;\n\nconst depositId = {\n type: 'string',\n description: 'Composite deposit id (escrow_onchainId) returned by cash_cashout - the resume key',\n} as const;\n\nexport const cashTools: CashToolDefinition[] = [\n {\n name: 'cash_capabilities',\n description:\n 'Discover what Peer Cash can do: payout platforms, oracle-priced currencies per platform, payee handle format hints, and amount bounds. Static and side-effect free - call this first.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n },\n {\n name: 'cash_estimate',\n description:\n 'Estimate fiat received for a USDC amount at the live oracle market rate. No payee, no side effects, no expiry - the binding rate resolves at the oracle when a buyer fills, so this is always \"approximately\", never a committed quote.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n currency: {\n type: 'string',\n description: 'Fiat currency code from cash_capabilities, e.g. \"USD\"',\n },\n },\n required: ['amount', 'currency'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_cashout',\n description:\n 'Start a cash-out: registers the payee with the curator and returns UNSIGNED transactions plus same-index steps [approve, createDeposit] for the host to sign and submit (prepare path - signing stays host-side). After submission, parse the depositId from the DepositReceived event or find it via cash_orders, then track with cash_order.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n receive: {\n type: 'object',\n description: 'Where the fiat should arrive',\n properties: {\n platform: {\n type: 'string',\n description: 'Platform id from cash_capabilities, e.g. \"venmo\"',\n },\n currency: { type: 'string', description: 'Fiat currency code, e.g. \"USD\"' },\n payee: {\n type: 'object',\n description: 'Payee handle for the platform',\n properties: {\n offchainId: {\n type: 'string',\n description:\n 'The handle, e.g. \"@andrew\" for Venmo - see payeeHint in cash_capabilities',\n },\n },\n required: ['offchainId'],\n additionalProperties: true,\n },\n },\n required: ['platform', 'currency', 'payee'],\n additionalProperties: false,\n },\n },\n required: ['amount', 'receive'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_order',\n description:\n 'Observe one cash-out order by depositId - fully resumable, no session state. Returns state (awaiting-buyer | matched | delivering | delivered | returned), amounts, fills, and nextActions (wait | withdraw). Errors are typed with retryable + remediation; ORDER_NOT_FOUND right after cashout means indexer lag - retry in a few seconds.',\n inputSchema: {\n type: 'object',\n properties: { depositId },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_orders',\n description:\n 'List all cash-out orders for a wallet address (the chain is the database - a cash order IS a deposit, keyed by depositor). Use inFlight=true for only the orders still needing attention.',\n inputSchema: {\n type: 'object',\n properties: {\n owner: { type: 'string', description: 'The maker wallet address (0x...)' },\n inFlight: {\n type: 'boolean',\n description: 'Only awaiting-buyer / matched / delivering orders',\n },\n limit: { type: 'number', description: 'Max deposits to scan (default 100)' },\n },\n required: ['owner'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_buyer',\n description:\n 'Look up a buyer\\'s protocol track record from their full intent history: lifetime intents, fulfilled vs pruned counts, success rate (bps), first/last seen. Use during the matched state to answer \"who just committed to my order?\".',\n inputSchema: {\n type: 'object',\n properties: {\n address: { type: 'string', description: 'The buyer (taker) wallet address (0x...)' },\n },\n required: ['address'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_withdraw',\n description:\n 'Unwind a cash-out: returns UNSIGNED transaction(s) plus same-index steps (prepare path - signing stays host-side). With amount: partial withdrawal of the unlocked balance (a live buyer intent does not block it). Without amount: closes the order fully, state-aware - when the only live intents have expired it includes a pruneExpiredIntents transaction first; while a live buyer intent locks funds it fails with ACTIVE_INTENT_BLOCKS_WITHDRAWAL (retryable - wait for expiry).',\n inputSchema: {\n type: 'object',\n properties: {\n depositId,\n amount: {\n ...bigintString,\n description:\n 'Optional partial amount (USDC base units, decimal string). Omit to close the order fully.',\n },\n },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_topup',\n description:\n 'Add USDC to a live cash-out order (same payee, same market rate). Returns UNSIGNED transactions plus same-index steps [approve, addFunds] for the host to sign and submit in order. Fails with ORDER_NOT_ACTIVE if the order is already delivered or returned.',\n inputSchema: {\n type: 'object',\n properties: { depositId, amount: bigintString },\n required: ['depositId', 'amount'],\n additionalProperties: false,\n },\n },\n];\n\n/** Manifest wrapper with versioning for host registries. */\nexport const cashToolManifest = {\n name: '@zkp2p/cash',\n version: '0.1.1',\n description:\n 'Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.',\n tools: cashTools,\n} as const;\n\nexport type CashToolName = (typeof cashTools)[number]['name'];\n"]}
package/dist/tools.d.cts CHANGED
@@ -22,7 +22,7 @@ declare const cashTools: CashToolDefinition[];
22
22
  /** Manifest wrapper with versioning for host registries. */
23
23
  declare const cashToolManifest: {
24
24
  readonly name: "@zkp2p/cash";
25
- readonly version: "0.1.0-dev.0";
25
+ readonly version: "0.1.1";
26
26
  readonly description: "Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.";
27
27
  readonly tools: CashToolDefinition[];
28
28
  };
package/dist/tools.d.ts CHANGED
@@ -22,7 +22,7 @@ declare const cashTools: CashToolDefinition[];
22
22
  /** Manifest wrapper with versioning for host registries. */
23
23
  declare const cashToolManifest: {
24
24
  readonly name: "@zkp2p/cash";
25
- readonly version: "0.1.0-dev.0";
25
+ readonly version: "0.1.1";
26
26
  readonly description: "Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.";
27
27
  readonly tools: CashToolDefinition[];
28
28
  };
package/dist/tools.js CHANGED
@@ -135,7 +135,7 @@ var cashTools = [
135
135
  ];
136
136
  var cashToolManifest = {
137
137
  name: "@zkp2p/cash",
138
- version: "0.1.0-dev.0",
138
+ version: "0.1.1",
139
139
  description: "Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.",
140
140
  tools: cashTools
141
141
  };
package/dist/tools.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tools/index.ts"],"names":[],"mappings":"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","file":"tools.js","sourcesContent":["/**\n * `@zkp2p/cash/tools` - JSON-schema tool definitions of the verbs, so\n * agent hosts (peer-cli, zkp2p-mcp, any MCP server or tool-use loop) adopt\n * Peer Cash without re-deriving schemas.\n *\n * Design rules:\n * - Mutating verbs default to the **prepare path**: the tool returns unsigned\n * transactions plus readable step labels; signing stays host-side, where key\n * custody and policy live.\n * - Every input/output is plain JSON (bigints as decimal strings) - see the\n * codecs exported from the package root for lossless (de)serialization.\n * - `watch` is intentionally not a tool: agents poll `cash_order` between\n * other work instead of holding a streaming connection open.\n */\n\nexport interface CashToolDefinition {\n name: string;\n description: string;\n /** JSON Schema (draft-07 compatible) for the tool input. */\n inputSchema: Record<string, unknown>;\n}\n\nconst bigintString = {\n type: 'string',\n pattern: '^[0-9]+$',\n description: 'USDC base units (6 decimals) as a decimal string, e.g. \"1000000000\" for 1000 USDC',\n} as const;\n\nconst depositId = {\n type: 'string',\n description: 'Composite deposit id (escrow_onchainId) returned by cash_cashout - the resume key',\n} as const;\n\nexport const cashTools: CashToolDefinition[] = [\n {\n name: 'cash_capabilities',\n description:\n 'Discover what Peer Cash can do: payout platforms, oracle-priced currencies per platform, payee handle format hints, and amount bounds. Static and side-effect free - call this first.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n },\n {\n name: 'cash_estimate',\n description:\n 'Estimate fiat received for a USDC amount at the live oracle market rate. No payee, no side effects, no expiry - the binding rate resolves at the oracle when a buyer fills, so this is always \"approximately\", never a committed quote.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n currency: {\n type: 'string',\n description: 'Fiat currency code from cash_capabilities, e.g. \"USD\"',\n },\n },\n required: ['amount', 'currency'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_cashout',\n description:\n 'Start a cash-out: registers the payee with the curator and returns UNSIGNED transactions plus same-index steps [approve, createDeposit] for the host to sign and submit (prepare path - signing stays host-side). After submission, parse the depositId from the DepositReceived event or find it via cash_orders, then track with cash_order.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n receive: {\n type: 'object',\n description: 'Where the fiat should arrive',\n properties: {\n platform: {\n type: 'string',\n description: 'Platform id from cash_capabilities, e.g. \"venmo\"',\n },\n currency: { type: 'string', description: 'Fiat currency code, e.g. \"USD\"' },\n payee: {\n type: 'object',\n description: 'Payee handle for the platform',\n properties: {\n offchainId: {\n type: 'string',\n description:\n 'The handle, e.g. \"@andrew\" for Venmo - see payeeHint in cash_capabilities',\n },\n },\n required: ['offchainId'],\n additionalProperties: true,\n },\n },\n required: ['platform', 'currency', 'payee'],\n additionalProperties: false,\n },\n },\n required: ['amount', 'receive'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_order',\n description:\n 'Observe one cash-out order by depositId - fully resumable, no session state. Returns state (awaiting-buyer | matched | delivering | delivered | returned), amounts, fills, and nextActions (wait | withdraw). Errors are typed with retryable + remediation; ORDER_NOT_FOUND right after cashout means indexer lag - retry in a few seconds.',\n inputSchema: {\n type: 'object',\n properties: { depositId },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_orders',\n description:\n 'List all cash-out orders for a wallet address (the chain is the database - a cash order IS a deposit, keyed by depositor). Use inFlight=true for only the orders still needing attention.',\n inputSchema: {\n type: 'object',\n properties: {\n owner: { type: 'string', description: 'The maker wallet address (0x...)' },\n inFlight: {\n type: 'boolean',\n description: 'Only awaiting-buyer / matched / delivering orders',\n },\n limit: { type: 'number', description: 'Max deposits to scan (default 100)' },\n },\n required: ['owner'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_buyer',\n description:\n 'Look up a buyer\\'s protocol track record from their full intent history: lifetime intents, fulfilled vs pruned counts, success rate (bps), first/last seen. Use during the matched state to answer \"who just committed to my order?\".',\n inputSchema: {\n type: 'object',\n properties: {\n address: { type: 'string', description: 'The buyer (taker) wallet address (0x...)' },\n },\n required: ['address'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_withdraw',\n description:\n 'Unwind a cash-out: returns UNSIGNED transaction(s) plus same-index steps (prepare path - signing stays host-side). With amount: partial withdrawal of the unlocked balance (a live buyer intent does not block it). Without amount: closes the order fully, state-aware - when the only live intents have expired it includes a pruneExpiredIntents transaction first; while a live buyer intent locks funds it fails with ACTIVE_INTENT_BLOCKS_WITHDRAWAL (retryable - wait for expiry).',\n inputSchema: {\n type: 'object',\n properties: {\n depositId,\n amount: {\n ...bigintString,\n description:\n 'Optional partial amount (USDC base units, decimal string). Omit to close the order fully.',\n },\n },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_topup',\n description:\n 'Add USDC to a live cash-out order (same payee, same market rate). Returns UNSIGNED transactions plus same-index steps [approve, addFunds] for the host to sign and submit in order. Fails with ORDER_NOT_ACTIVE if the order is already delivered or returned.',\n inputSchema: {\n type: 'object',\n properties: { depositId, amount: bigintString },\n required: ['depositId', 'amount'],\n additionalProperties: false,\n },\n },\n];\n\n/** Manifest wrapper with versioning for host registries. */\nexport const cashToolManifest = {\n name: '@zkp2p/cash',\n version: '0.1.0-dev.0',\n description:\n 'Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.',\n tools: cashTools,\n} as const;\n\nexport type CashToolName = (typeof cashTools)[number]['name'];\n"]}
1
+ {"version":3,"sources":["../src/tools/index.ts"],"names":[],"mappings":"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","file":"tools.js","sourcesContent":["/**\n * `@zkp2p/cash/tools` - JSON-schema tool definitions of the verbs, so\n * agent hosts (peer-cli, zkp2p-mcp, any MCP server or tool-use loop) adopt\n * Peer Cash without re-deriving schemas.\n *\n * Design rules:\n * - Mutating verbs default to the **prepare path**: the tool returns unsigned\n * transactions plus readable step labels; signing stays host-side, where key\n * custody and policy live.\n * - Every input/output is plain JSON (bigints as decimal strings) - see the\n * codecs exported from the package root for lossless (de)serialization.\n * - `watch` is intentionally not a tool: agents poll `cash_order` between\n * other work instead of holding a streaming connection open.\n */\n\nexport interface CashToolDefinition {\n name: string;\n description: string;\n /** JSON Schema (draft-07 compatible) for the tool input. */\n inputSchema: Record<string, unknown>;\n}\n\nconst bigintString = {\n type: 'string',\n pattern: '^[0-9]+$',\n description: 'USDC base units (6 decimals) as a decimal string, e.g. \"1000000000\" for 1000 USDC',\n} as const;\n\nconst depositId = {\n type: 'string',\n description: 'Composite deposit id (escrow_onchainId) returned by cash_cashout - the resume key',\n} as const;\n\nexport const cashTools: CashToolDefinition[] = [\n {\n name: 'cash_capabilities',\n description:\n 'Discover what Peer Cash can do: payout platforms, oracle-priced currencies per platform, payee handle format hints, and amount bounds. Static and side-effect free - call this first.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n },\n {\n name: 'cash_estimate',\n description:\n 'Estimate fiat received for a USDC amount at the live oracle market rate. No payee, no side effects, no expiry - the binding rate resolves at the oracle when a buyer fills, so this is always \"approximately\", never a committed quote.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n currency: {\n type: 'string',\n description: 'Fiat currency code from cash_capabilities, e.g. \"USD\"',\n },\n },\n required: ['amount', 'currency'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_cashout',\n description:\n 'Start a cash-out: registers the payee with the curator and returns UNSIGNED transactions plus same-index steps [approve, createDeposit] for the host to sign and submit (prepare path - signing stays host-side). After submission, parse the depositId from the DepositReceived event or find it via cash_orders, then track with cash_order.',\n inputSchema: {\n type: 'object',\n properties: {\n amount: bigintString,\n receive: {\n type: 'object',\n description: 'Where the fiat should arrive',\n properties: {\n platform: {\n type: 'string',\n description: 'Platform id from cash_capabilities, e.g. \"venmo\"',\n },\n currency: { type: 'string', description: 'Fiat currency code, e.g. \"USD\"' },\n payee: {\n type: 'object',\n description: 'Payee handle for the platform',\n properties: {\n offchainId: {\n type: 'string',\n description:\n 'The handle, e.g. \"@andrew\" for Venmo - see payeeHint in cash_capabilities',\n },\n },\n required: ['offchainId'],\n additionalProperties: true,\n },\n },\n required: ['platform', 'currency', 'payee'],\n additionalProperties: false,\n },\n },\n required: ['amount', 'receive'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_order',\n description:\n 'Observe one cash-out order by depositId - fully resumable, no session state. Returns state (awaiting-buyer | matched | delivering | delivered | returned), amounts, fills, and nextActions (wait | withdraw). Errors are typed with retryable + remediation; ORDER_NOT_FOUND right after cashout means indexer lag - retry in a few seconds.',\n inputSchema: {\n type: 'object',\n properties: { depositId },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_orders',\n description:\n 'List all cash-out orders for a wallet address (the chain is the database - a cash order IS a deposit, keyed by depositor). Use inFlight=true for only the orders still needing attention.',\n inputSchema: {\n type: 'object',\n properties: {\n owner: { type: 'string', description: 'The maker wallet address (0x...)' },\n inFlight: {\n type: 'boolean',\n description: 'Only awaiting-buyer / matched / delivering orders',\n },\n limit: { type: 'number', description: 'Max deposits to scan (default 100)' },\n },\n required: ['owner'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_buyer',\n description:\n 'Look up a buyer\\'s protocol track record from their full intent history: lifetime intents, fulfilled vs pruned counts, success rate (bps), first/last seen. Use during the matched state to answer \"who just committed to my order?\".',\n inputSchema: {\n type: 'object',\n properties: {\n address: { type: 'string', description: 'The buyer (taker) wallet address (0x...)' },\n },\n required: ['address'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_withdraw',\n description:\n 'Unwind a cash-out: returns UNSIGNED transaction(s) plus same-index steps (prepare path - signing stays host-side). With amount: partial withdrawal of the unlocked balance (a live buyer intent does not block it). Without amount: closes the order fully, state-aware - when the only live intents have expired it includes a pruneExpiredIntents transaction first; while a live buyer intent locks funds it fails with ACTIVE_INTENT_BLOCKS_WITHDRAWAL (retryable - wait for expiry).',\n inputSchema: {\n type: 'object',\n properties: {\n depositId,\n amount: {\n ...bigintString,\n description:\n 'Optional partial amount (USDC base units, decimal string). Omit to close the order fully.',\n },\n },\n required: ['depositId'],\n additionalProperties: false,\n },\n },\n {\n name: 'cash_topup',\n description:\n 'Add USDC to a live cash-out order (same payee, same market rate). Returns UNSIGNED transactions plus same-index steps [approve, addFunds] for the host to sign and submit in order. Fails with ORDER_NOT_ACTIVE if the order is already delivered or returned.',\n inputSchema: {\n type: 'object',\n properties: { depositId, amount: bigintString },\n required: ['depositId', 'amount'],\n additionalProperties: false,\n },\n },\n];\n\n/** Manifest wrapper with versioning for host registries. */\nexport const cashToolManifest = {\n name: '@zkp2p/cash',\n version: '0.1.1',\n description:\n 'Peer Cash - offramp-only: cash out Base USDC to fiat at the live oracle market rate (0% spread). Eight verbs; mutating tools return unsigned transactions plus step labels with ERC-8021 peer-cash attribution.',\n tools: cashTools,\n} as const;\n\nexport type CashToolName = (typeof cashTools)[number]['name'];\n"]}
package/llms.txt ADDED
@@ -0,0 +1,59 @@
1
+ # @zkp2p/cash - Peer Cash
2
+
3
+ > Offramp-only SDK for the ZKP2P protocol: cash out Base USDC to fiat (Venmo,
4
+ > Revolut, Wise, Zelle, ...) at the live Chainlink oracle market rate with zero
5
+ > spread and no centralized off-ramp provider. The user is the maker,
6
+ > Peer handles the buyer side, and eight verbs expose readable order state.
7
+ > Every operation is available as pure serializable data; a React app, a Node service, and an AI agent are equal
8
+ > consumers.
9
+
10
+ Key facts:
11
+
12
+ - The cashing-out user is the MAKER: their USDC becomes a protocol-held order;
13
+ a buyer pays fiat and proves it with TEE-TLS; the protocol releases the USDC.
14
+ - There is NO quote. estimate() reads the oracle; the binding rate resolves
15
+ at fill time. Never present a locked price or an ETA.
16
+ - Resume any order from its depositId alone (composite escrow_onchainId).
17
+ - One unwind verb: withdraw(depositId) - prunes expired intents automatically;
18
+ pass amount for a partial withdrawal of the unlocked balance.
19
+ - topUp(depositId, amount) adds USDC to a live order (same payee, same rate).
20
+ - Mutating verbs have unsigned counterparts (prepare, prepareWithdraw,
21
+ prepareTopUp) for host-side signing; @zkp2p/cash/tools ships a JSON-schema
22
+ tool manifest. Prepare results include `txs[]` plus same-index `steps[]`
23
+ labels so hosts can explain approvals and deposits before signing. Every
24
+ transaction carries ERC-8021 attribution ('peer-cash' plus integrator
25
+ referrer codes).
26
+ - Errors are typed: { code, retryable, remediation }.
27
+ - Everything is decoded to human units: platform ids and currency codes from
28
+ their on-chain hashes, plain-number rates from 1e18 precision.
29
+ - Fills are receipts: locked rate + fiat owed at signal; verified fiat paid,
30
+ payment id, released USDC, and fill latency after the proof.
31
+ - Orders carry their payout legs (platform, currency, payee hash) plus a
32
+ verifiable pricing proof (spreadBps: 0, oracle kind) from indexed data.
33
+ - buyer(address) aggregates a buyer's track record (fulfilled/pruned/success
34
+ rate) from their full intent history.
35
+ - v1 is same-chain only: Base USDC in.
36
+
37
+ ## Links
38
+
39
+ - Live demo: https://react-cashout-demo.vercel.app
40
+ - Product page: https://peer.xyz/cash
41
+ - npm: https://www.npmjs.com/package/@zkp2p/cash
42
+
43
+ ## Docs
44
+
45
+ - [README](README.md): quickstart, verb table, lifecycle diagram
46
+ - [AGENTS.md](AGENTS.md): agent integration manual - decision tree,
47
+ prepare-path patterns, error → remediation table
48
+ - [Lifecycle and recovery](docs/lifecycle-and-recovery.md): states, partial
49
+ fills, honest-ETA principle, unwind, resumability, failure table
50
+ - [Integration skill](skills/peer-cash-integration/SKILL.md): step-by-step
51
+ onboarding for coding agents, with the staging verification checklist
52
+
53
+ ## Source
54
+
55
+ - [Engine](src/engine/): pure order-state derivation and deposit-param
56
+ construction (no I/O)
57
+ - [Client](src/client/createCashClient.ts): the verb facade
58
+ - [Tools manifest](src/tools/index.ts): JSON-schema definitions of the verbs
59
+ - [Codecs](src/codecs/): zod schemas + lossless JSON round-trips
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@zkp2p/cash",
3
- "version": "0.1.0-dev.0",
3
+ "version": "0.1.1",
4
4
  "description": "Peer Cash - offramp-only SDK for the ZKP2P protocol: eight verbs to cash out Base USDC to fiat at the live oracle market rate.",
5
5
  "license": "MIT",
6
+ "author": "Peer (https://peer.xyz)",
6
7
  "type": "module",
7
8
  "sideEffects": false,
8
9
  "publishConfig": {
@@ -16,10 +17,15 @@
16
17
  "bugs": "https://github.com/zkp2p/peer-cash/issues",
17
18
  "keywords": [
18
19
  "zkp2p",
20
+ "peer",
19
21
  "offramp",
20
22
  "usdc",
21
23
  "base",
22
24
  "crypto-to-fiat",
25
+ "venmo",
26
+ "chainlink",
27
+ "viem",
28
+ "agent",
23
29
  "payments",
24
30
  "sdk"
25
31
  ],
@@ -45,9 +51,11 @@
45
51
  },
46
52
  "files": [
47
53
  "dist",
54
+ "skills",
48
55
  "AGENTS.md",
49
56
  "README.md",
50
- "LICENSE"
57
+ "LICENSE",
58
+ "llms.txt"
51
59
  ],
52
60
  "scripts": {
53
61
  "build": "tsup",
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: peer-cash-integration
3
+ description: Integrate Peer Cash (@zkp2p/cash) into any codebase - React app, Node service, or agent runtime. Covers the maker-inversion mental model, oracle-at-fill pricing, the verbs, indexer-native order tracking, the failure playbook, and the maker-side staging verification that proves the integration works. Use when adding crypto-to-fiat cash-out to a product or wiring the cash tools into an agent host.
4
+ ---
5
+
6
+ # Peer Cash integration
7
+
8
+ Onboard this codebase to `@zkp2p/cash`: an offramp-only SDK that cashes out
9
+ Base USDC to fiat at the live Chainlink market rate (0% spread),
10
+ with protocol-held funds and no custodial off-ramp provider.
11
+
12
+ ## 1. Mental model (read before writing code)
13
+
14
+ - **Maker inversion.** The cashing-out user is the _maker_: their USDC becomes
15
+ a protocol-held deposit. A buyer (taker) pays them fiat and proves it
16
+ with TEE-TLS; the protocol releases the USDC. The protocol runs in its normal
17
+ direction - Peer Cash is a lens on it, not a fork of it.
18
+ - **Oracle-at-fill pricing. There is no quote.** The deposit carries
19
+ `oracleRateConfig { spreadBps: 0 }`; the binding rate is whatever the
20
+ Chainlink feed says when a buyer fills. `estimate()` is deliberately named
21
+ - anything in your UI or agent output implying a locked rate is a bug.
22
+ - **Custody story.** Funds are held by the protocol contract only. An unmatched
23
+ deposit is withdrawable by the maker at any time. The SDK never holds keys.
24
+ - **Honest ETA.** Buyer arrival time is unknowable. Use `order.explain()`;
25
+ never render a countdown.
26
+
27
+ ## 2. Decision tree - entry point by runtime
28
+
29
+ | Runtime | Entry | Signer pattern |
30
+ | ------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
31
+ | React app | `@zkp2p/cash/react` hooks + one `createCashClient` in a provider | wagmi/viem `WalletClient` from the connected wallet |
32
+ | Node service | `createCashClient` + `cashout()`/`withdraw()` | `createWalletClient({ account: privateKeyToAccount(...), chain: base, transport })` |
33
+ | Agent host / policy layer | `prepare()` / `prepareWithdraw()` -> unsigned `txs[]` + `steps[]` | Host signs; see `@zkp2p/cash/tools` for the JSON-schema tool manifest |
34
+
35
+ ## 3. Recipes - the verbs
36
+
37
+ Authoritative signatures live in the package's typedoc and `AGENTS.md` - do
38
+ not copy types from here; import them.
39
+
40
+ ```ts
41
+ import { createCashClient, usdc } from '@zkp2p/cash';
42
+
43
+ // env: 'production' | 'preproduction' | 'staging'
44
+ const cash = createCashClient({ environment: 'staging' });
45
+
46
+ const caps = cash.capabilities(); // 0 discover (sync)
47
+ const est = await cash.estimate({ amount: usdc(100), currency: 'USD' }); // 1 estimate
48
+ const res = await cash.cashout(
49
+ {
50
+ // 2 execute
51
+ amount: usdc(100),
52
+ receive: { platform: 'venmo', currency: 'USD', payee: { offchainId: '@handle' } },
53
+ },
54
+ { signer },
55
+ );
56
+ const { txs, steps } = await cash.prepare({/* same input */}); // 2b unsigned plan
57
+ const order = await cash.order(res.depositId); // 3 observe
58
+ const mine = await cash.orders(ownerAddress, { inFlight: true }); // 4 list
59
+ for await (const o of cash.watch(res.depositId)) {
60
+ // 5 watch
61
+ if (!o.isInFlight) break;
62
+ }
63
+ await cash.withdraw(res.depositId, { signer }); // 6 unwind (amount: for partial)
64
+ await cash.topUp(res.depositId, usdc(50), { signer }); // 7 top up a live order
65
+ ```
66
+
67
+ Every mutating verb also has an unsigned `prepare*` counterpart, and every
68
+ transaction carries ERC-8021 attribution (`peer-cash` + your
69
+ `createCashClient({ referrer })` codes).
70
+
71
+ ## 4. Order management - indexer-native
72
+
73
+ - A cash order IS a deposit; the chain is the database. No storage layer.
74
+ - Bind orders to your users with one column in _your_ system:
75
+ `userId → depositId`, populated from `cashout()`'s return value.
76
+ - `order(depositId)` cold-hydrates from the id alone - resumable across
77
+ processes, devices, and crashes.
78
+ - Serialize across boundaries with the exported codecs
79
+ (`orderToJson`/`orderFromJson`) - they handle bigints and re-attach
80
+ `explain()`.
81
+
82
+ ## 5. Failure playbook
83
+
84
+ Every error is a `CashError` with `code`, `retryable`, `remediation`. The
85
+ full table lives in `AGENTS.md` and `docs/lifecycle-and-recovery.md` - quote
86
+ those, don't re-derive. The three that matter most in practice:
87
+
88
+ - `ORDER_NOT_FOUND` seconds after `cashout()` = indexer lag. The receipt is
89
+ the truth; retry. `watch()` and the React hooks absorb it.
90
+ - `ACTIVE_INTENT_BLOCKS_WITHDRAWAL` = a buyer may still deliver. Retry
91
+ `withdraw()` after their intent expires; it prunes automatically.
92
+ - Buyer never pays → nothing to do: the intent expires, `nextActions` gains
93
+ `'withdraw'`, one `withdraw()` call returns the funds (prune + withdraw).
94
+
95
+ ## 6. Verification checklist (mandatory before calling the integration done)
96
+
97
+ Run against `environment: 'staging'` with a small funded wallet.
98
+ **Maker-side only - never wait on a buyer.**
99
+
100
+ 1. Create a real 1–2 USDC deposit via `cashout()`; capture `depositId`.
101
+ 2. Assert `order(depositId).state === 'awaiting-buyer'` (retry through
102
+ indexer lag for up to ~60s).
103
+ 3. Assert `orders(owner)` contains the deposit.
104
+ 4. `withdraw(depositId, { signer })` succeeds.
105
+ 5. Assert `order(depositId).state === 'returned'` and the wallet balance is
106
+ restored minus gas.
107
+
108
+ If withdrawal fails with funds stuck: stop, do not retry blindly, escalate to
109
+ a human with the `depositId` and tx hashes.