@zkp2p/cash 0.1.5 → 0.1.6

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/README.md CHANGED
@@ -5,12 +5,25 @@ on Venmo, Revolut, Wise, Zelle, and more at the live Chainlink market rate,
5
5
  with zero spread and no centralized off-ramp provider.
6
6
 
7
7
  Peer Cash is an **offramp-only** SDK for the [ZKP2P](https://peer.xyz)
8
- protocol. The cashing-out user is the maker: their USDC becomes a
9
- protocol-held deposit, Peer handles the buyer side, and the SDK gives the
10
- integrator a small set of typed verbs plus readable order state. No hosted
11
- widget, no provider custody, no quote engine to maintain.
8
+ protocol. The cashing-out user is the maker: their USDC becomes a deposit in
9
+ the protocol contracts, a buyer pays them fiat and proves the payment, and the
10
+ SDK gives the integrator a small set of typed verbs plus readable order state.
11
+ No hosted 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)**
13
+ **[npm](https://www.npmjs.com/package/@zkp2p/cash)** · **[Lifecycle and recovery](docs/lifecycle-and-recovery.md)** · **[Agent integration manual](AGENTS.md)**
14
+
15
+ ## Pick the right SDK
16
+
17
+ Peer Cash and the general ZKP2P SDK serve different integration depths:
18
+
19
+ | Package | Use it when | Boundary |
20
+ | ------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
21
+ | `@zkp2p/cash` | Cash-out is the product | Offramp only. The user is always the maker, the destination is Base USDC, pricing is the live Chainlink rate at fill with zero spread, and the SDK owns the resumable order lifecycle. |
22
+ | `@zkp2p/sdk` | You are composing directly with the Peer protocol | General maker and taker operations, deposits, intents, proofs, quotes, vaults, rate managers, referrals, hooks, and API helpers. Your application owns the workflow and protocol choices. |
23
+
24
+ Peer Cash is a narrow facade over `@zkp2p/sdk`, not a replacement for it. It
25
+ cannot express custom spreads, buyer-side proof flows, vaults, disputes, or
26
+ arbitrary protocol operations.
14
27
 
15
28
  ```ts
16
29
  import { createCashClient, usdc } from '@zkp2p/cash';
package/dist/index.cjs CHANGED
@@ -1717,32 +1717,51 @@ function createCashClient(options) {
1717
1717
  (transaction) => transaction.chainId === BASE_CHAIN_ID
1718
1718
  );
1719
1719
  const batchIds = baseTransactions.filter((transaction) => transaction.isBatchTx === true).map((transaction) => transaction.hash);
1720
+ const batchExecutionFailed = (cause) => errors.sourceExecutionFailed(cause, {
1721
+ ...executed.requestId ? { requestId: executed.requestId } : {},
1722
+ txHashes: executed.txHashes,
1723
+ ...executed.transactions ? { transactions: executed.transactions } : {}
1724
+ });
1720
1725
  let batchTransactionHashes = [];
1721
1726
  if (batchIds.length > 0) {
1722
1727
  let batchError;
1723
1728
  let batchesComplete = false;
1729
+ let batchesSucceededWithoutReceipts = false;
1724
1730
  for (let attempt = 0; attempt < 20; attempt++) {
1725
1731
  try {
1726
1732
  const statuses = await Promise.all(
1727
1733
  batchIds.map((id) => sourceSigner.getCallsStatus({ id }))
1728
1734
  );
1729
1735
  if (statuses.some((status) => status.status === "failure")) {
1730
- throw new Error("Relay wallet call bundle failed");
1736
+ throw batchExecutionFailed(new Error("Relay wallet call bundle failed"));
1731
1737
  }
1732
1738
  if (statuses.every((status) => status.status === "success")) {
1733
- batchTransactionHashes = statuses.flatMap(
1734
- (status) => (status.receipts ?? []).map((receipt) => receipt.transactionHash)
1735
- );
1736
- batchesComplete = true;
1737
- break;
1739
+ const receiptGroups = statuses.map((status) => status.receipts ?? []);
1740
+ if (receiptGroups.some((receipts) => receipts.length === 0)) {
1741
+ batchError = new Error(
1742
+ "Relay wallet call bundle did not include transaction receipts"
1743
+ );
1744
+ batchesSucceededWithoutReceipts = true;
1745
+ break;
1746
+ } else {
1747
+ batchTransactionHashes = receiptGroups.flatMap(
1748
+ (receipts) => receipts.map((receipt) => receipt.transactionHash)
1749
+ );
1750
+ batchesComplete = true;
1751
+ break;
1752
+ }
1738
1753
  }
1739
1754
  } catch (err) {
1755
+ if (isCashError(err)) throw err;
1740
1756
  batchError = err;
1741
1757
  }
1742
1758
  await sleep(250);
1743
1759
  }
1744
1760
  if (!batchesComplete) {
1745
- throw batchError ?? new Error("Relay wallet call bundle did not complete");
1761
+ if (batchesSucceededWithoutReceipts) throw batchError;
1762
+ throw batchExecutionFailed(
1763
+ batchError ?? new Error("Relay wallet call bundle did not complete")
1764
+ );
1746
1765
  }
1747
1766
  }
1748
1767
  const hashes = [
@@ -1864,6 +1883,7 @@ function createCashClient(options) {
1864
1883
  executed
1865
1884
  );
1866
1885
  } catch (err) {
1886
+ if (isCashError(err)) throw err;
1867
1887
  throw errors.sourceRouteCompletedCashoutFailed(
1868
1888
  routedSource,
1869
1889
  mapChainError("resolve same-chain Relay nonce", err)
package/dist/index.js CHANGED
@@ -1344,32 +1344,51 @@ function createCashClient(options) {
1344
1344
  (transaction) => transaction.chainId === BASE_CHAIN_ID
1345
1345
  );
1346
1346
  const batchIds = baseTransactions.filter((transaction) => transaction.isBatchTx === true).map((transaction) => transaction.hash);
1347
+ const batchExecutionFailed = (cause) => errors.sourceExecutionFailed(cause, {
1348
+ ...executed.requestId ? { requestId: executed.requestId } : {},
1349
+ txHashes: executed.txHashes,
1350
+ ...executed.transactions ? { transactions: executed.transactions } : {}
1351
+ });
1347
1352
  let batchTransactionHashes = [];
1348
1353
  if (batchIds.length > 0) {
1349
1354
  let batchError;
1350
1355
  let batchesComplete = false;
1356
+ let batchesSucceededWithoutReceipts = false;
1351
1357
  for (let attempt = 0; attempt < 20; attempt++) {
1352
1358
  try {
1353
1359
  const statuses = await Promise.all(
1354
1360
  batchIds.map((id) => sourceSigner.getCallsStatus({ id }))
1355
1361
  );
1356
1362
  if (statuses.some((status) => status.status === "failure")) {
1357
- throw new Error("Relay wallet call bundle failed");
1363
+ throw batchExecutionFailed(new Error("Relay wallet call bundle failed"));
1358
1364
  }
1359
1365
  if (statuses.every((status) => status.status === "success")) {
1360
- batchTransactionHashes = statuses.flatMap(
1361
- (status) => (status.receipts ?? []).map((receipt) => receipt.transactionHash)
1362
- );
1363
- batchesComplete = true;
1364
- break;
1366
+ const receiptGroups = statuses.map((status) => status.receipts ?? []);
1367
+ if (receiptGroups.some((receipts) => receipts.length === 0)) {
1368
+ batchError = new Error(
1369
+ "Relay wallet call bundle did not include transaction receipts"
1370
+ );
1371
+ batchesSucceededWithoutReceipts = true;
1372
+ break;
1373
+ } else {
1374
+ batchTransactionHashes = receiptGroups.flatMap(
1375
+ (receipts) => receipts.map((receipt) => receipt.transactionHash)
1376
+ );
1377
+ batchesComplete = true;
1378
+ break;
1379
+ }
1365
1380
  }
1366
1381
  } catch (err) {
1382
+ if (isCashError(err)) throw err;
1367
1383
  batchError = err;
1368
1384
  }
1369
1385
  await sleep(250);
1370
1386
  }
1371
1387
  if (!batchesComplete) {
1372
- throw batchError ?? new Error("Relay wallet call bundle did not complete");
1388
+ if (batchesSucceededWithoutReceipts) throw batchError;
1389
+ throw batchExecutionFailed(
1390
+ batchError ?? new Error("Relay wallet call bundle did not complete")
1391
+ );
1373
1392
  }
1374
1393
  }
1375
1394
  const hashes = [
@@ -1491,6 +1510,7 @@ function createCashClient(options) {
1491
1510
  executed
1492
1511
  );
1493
1512
  } catch (err) {
1513
+ if (isCashError(err)) throw err;
1494
1514
  throw errors.sourceRouteCompletedCashoutFailed(
1495
1515
  routedSource,
1496
1516
  mapChainError("resolve same-chain Relay nonce", err)
package/dist/tools.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // package.json
4
4
  var package_default = {
5
- version: "0.1.5"};
5
+ version: "0.1.6"};
6
6
 
7
7
  // src/tools/index.ts
8
8
  var bigintString = {
package/dist/tools.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // package.json
2
2
  var package_default = {
3
- version: "0.1.5"};
3
+ version: "0.1.6"};
4
4
 
5
5
  // src/tools/index.ts
6
6
  var bigintString = {
package/llms.txt CHANGED
@@ -3,8 +3,8 @@
3
3
  > Offramp-only SDK for the ZKP2P protocol: route any Relay-supported EVM source
4
4
  > asset to Base USDC, then cash out to fiat (Venmo, Revolut, Wise, Zelle, ...)
5
5
  > at the live Chainlink oracle market rate with zero spread and no centralized
6
- > off-ramp provider. The user is the maker, Peer handles the buyer side, and the
7
- > SDK exposes readable order state.
6
+ > off-ramp provider. The user is the maker, a buyer pays them fiat and proves
7
+ > the payment, and the SDK exposes readable order state.
8
8
  > Base-USDC flows are serializable through prepare paths; source-routed cashout
9
9
  > uses Relay execution first. React apps, Node services, and agent hosts use the
10
10
  > same typed surface.
@@ -59,9 +59,8 @@ Key facts:
59
59
 
60
60
  ## Links
61
61
 
62
- - Live demo: https://react-cashout-demo.vercel.app
63
- - Product page: https://peer.xyz/cash
64
62
  - npm: https://www.npmjs.com/package/@zkp2p/cash
63
+ - Source: https://github.com/zkp2p/peer-cash
65
64
 
66
65
  ## Docs
67
66
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkp2p/cash",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Peer Cash - offramp-only SDK for routing crypto to Base USDC, then cashing out to fiat at the live oracle market rate.",
5
5
  "license": "MIT",
6
6
  "author": "Peer (https://peer.xyz)",
@@ -12,7 +12,14 @@
12
12
  "publishConfig": {
13
13
  "access": "public"
14
14
  },
15
- "homepage": "https://peer.xyz/cash",
15
+ "homepage": "https://github.com/zkp2p/peer-cash#readme",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/zkp2p/peer-cash.git"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/zkp2p/peer-cash/issues"
22
+ },
16
23
  "keywords": [
17
24
  "zkp2p",
18
25
  "peer",
@@ -98,7 +105,7 @@
98
105
  "dependencies": {
99
106
  "@relayprotocol/relay-sdk": "^6.1.3",
100
107
  "@zkp2p/sdk": "^0.8.1",
101
- "zod": "^3.24.1"
108
+ "zod": "^3.25.76"
102
109
  },
103
110
  "peerDependencies": {
104
111
  "react": ">=18",
@@ -110,19 +117,19 @@
110
117
  }
111
118
  },
112
119
  "devDependencies": {
113
- "@eslint/js": "^9.17.0",
114
- "@types/node": "^22.10.2",
115
- "@types/react": "^19.0.2",
120
+ "@eslint/js": "^9.39.5",
121
+ "@types/node": "^22.20.1",
122
+ "@types/react": "^19.2.17",
116
123
  "@types/react-test-renderer": "19.1.0",
117
- "eslint": "^9.17.0",
118
- "eslint-config-prettier": "^9.1.0",
119
- "prettier": "^3.4.2",
120
- "react": "^19.0.0",
124
+ "eslint": "^9.39.5",
125
+ "eslint-config-prettier": "^9.1.2",
126
+ "prettier": "^3.9.5",
127
+ "react": "^19.2.7",
121
128
  "react-test-renderer": "19.2.7",
122
- "tsup": "^8.3.5",
123
- "typescript": "^5.7.2",
124
- "typescript-eslint": "^8.18.1",
125
- "viem": "^2.55.0",
129
+ "tsup": "^8.5.1",
130
+ "typescript": "^5.9.3",
131
+ "typescript-eslint": "^8.63.0",
132
+ "viem": "^2.55.1",
126
133
  "vitest": "^4.1.10"
127
134
  }
128
135
  }