@zkp2p/cash 0.1.4 → 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 +18 -5
- package/dist/{createCashClient-BbkfxILl.d.cts → createCashClient-jUA_GNdh.d.cts} +2 -0
- package/dist/{createCashClient-BbkfxILl.d.ts → createCashClient-jUA_GNdh.d.ts} +2 -0
- package/dist/index.cjs +119 -3
- package/dist/index.d.cts +177 -2
- package/dist/index.d.ts +177 -2
- package/dist/index.js +119 -3
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/tools.cjs +1 -1
- package/dist/tools.js +1 -1
- package/llms.txt +3 -4
- package/package.json +21 -14
package/dist/index.js
CHANGED
|
@@ -607,10 +607,18 @@ function collectRelayTransactions(steps, sourceChainId) {
|
|
|
607
607
|
for (const step of steps) {
|
|
608
608
|
for (const item of step.items) {
|
|
609
609
|
for (const tx of item.internalTxHashes ?? []) {
|
|
610
|
-
record({
|
|
610
|
+
record({
|
|
611
|
+
hash: tx.txHash,
|
|
612
|
+
chainId: tx.chainId,
|
|
613
|
+
...tx.isBatchTx ? { isBatchTx: true } : {}
|
|
614
|
+
});
|
|
611
615
|
}
|
|
612
616
|
for (const tx of item.txHashes ?? []) {
|
|
613
|
-
record({
|
|
617
|
+
record({
|
|
618
|
+
hash: tx.txHash,
|
|
619
|
+
chainId: tx.chainId,
|
|
620
|
+
...tx.isBatchTx ? { isBatchTx: true } : {}
|
|
621
|
+
});
|
|
614
622
|
}
|
|
615
623
|
}
|
|
616
624
|
}
|
|
@@ -1330,6 +1338,97 @@ function createCashClient(options) {
|
|
|
1330
1338
|
}
|
|
1331
1339
|
throw errors.allowanceNotVisible(amount, lastReadError);
|
|
1332
1340
|
}
|
|
1341
|
+
async function waitForBaseSignerAfterRelay(client, cashoutSigner, sourceSigner, owner, sourceChainId, executed) {
|
|
1342
|
+
if (sourceChainId !== BASE_CHAIN_ID) return;
|
|
1343
|
+
const baseTransactions = (executed.transactions?.origin ?? []).filter(
|
|
1344
|
+
(transaction) => transaction.chainId === BASE_CHAIN_ID
|
|
1345
|
+
);
|
|
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
|
+
});
|
|
1352
|
+
let batchTransactionHashes = [];
|
|
1353
|
+
if (batchIds.length > 0) {
|
|
1354
|
+
let batchError;
|
|
1355
|
+
let batchesComplete = false;
|
|
1356
|
+
let batchesSucceededWithoutReceipts = false;
|
|
1357
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
1358
|
+
try {
|
|
1359
|
+
const statuses = await Promise.all(
|
|
1360
|
+
batchIds.map((id) => sourceSigner.getCallsStatus({ id }))
|
|
1361
|
+
);
|
|
1362
|
+
if (statuses.some((status) => status.status === "failure")) {
|
|
1363
|
+
throw batchExecutionFailed(new Error("Relay wallet call bundle failed"));
|
|
1364
|
+
}
|
|
1365
|
+
if (statuses.every((status) => status.status === "success")) {
|
|
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
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
} catch (err) {
|
|
1382
|
+
if (isCashError(err)) throw err;
|
|
1383
|
+
batchError = err;
|
|
1384
|
+
}
|
|
1385
|
+
await sleep(250);
|
|
1386
|
+
}
|
|
1387
|
+
if (!batchesComplete) {
|
|
1388
|
+
if (batchesSucceededWithoutReceipts) throw batchError;
|
|
1389
|
+
throw batchExecutionFailed(
|
|
1390
|
+
batchError ?? new Error("Relay wallet call bundle did not complete")
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
const hashes = [
|
|
1395
|
+
...baseTransactions.filter((transaction) => transaction.isBatchTx !== true).map((transaction) => transaction.hash),
|
|
1396
|
+
...batchTransactionHashes
|
|
1397
|
+
];
|
|
1398
|
+
if (hashes.length === 0) return;
|
|
1399
|
+
let transactions;
|
|
1400
|
+
let lastLookupError;
|
|
1401
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
1402
|
+
try {
|
|
1403
|
+
transactions = await Promise.all(
|
|
1404
|
+
hashes.map((hash) => client.publicClient.getTransaction({ hash }))
|
|
1405
|
+
);
|
|
1406
|
+
break;
|
|
1407
|
+
} catch (err) {
|
|
1408
|
+
lastLookupError = err;
|
|
1409
|
+
await sleep(250);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
if (!transactions) throw lastLookupError;
|
|
1413
|
+
const ownerNonces = transactions.filter((transaction) => transaction.from.toLowerCase() === owner.toLowerCase()).map((transaction) => transaction.nonce);
|
|
1414
|
+
if (ownerNonces.length === 0) return;
|
|
1415
|
+
const afterRelay = Math.max(...ownerNonces) + 1;
|
|
1416
|
+
let lastNonceError;
|
|
1417
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
1418
|
+
try {
|
|
1419
|
+
const pendingHex = await cashoutSigner.transport.request({
|
|
1420
|
+
method: "eth_getTransactionCount",
|
|
1421
|
+
params: [owner, "pending"]
|
|
1422
|
+
});
|
|
1423
|
+
if (Number(BigInt(pendingHex)) >= afterRelay) return;
|
|
1424
|
+
} catch (err) {
|
|
1425
|
+
lastNonceError = err;
|
|
1426
|
+
}
|
|
1427
|
+
await sleep(250);
|
|
1428
|
+
}
|
|
1429
|
+
if (lastNonceError) throw lastNonceError;
|
|
1430
|
+
throw new Error(`Signer provider did not observe Relay nonce ${afterRelay - 1}`);
|
|
1431
|
+
}
|
|
1333
1432
|
return {
|
|
1334
1433
|
capabilities,
|
|
1335
1434
|
async sourceCapabilities() {
|
|
@@ -1401,6 +1500,22 @@ function createCashClient(options) {
|
|
|
1401
1500
|
...executed.transactions ? { transactions: executed.transactions } : {}
|
|
1402
1501
|
};
|
|
1403
1502
|
sourceResult = routedSource;
|
|
1503
|
+
try {
|
|
1504
|
+
await waitForBaseSignerAfterRelay(
|
|
1505
|
+
client,
|
|
1506
|
+
opts.signer,
|
|
1507
|
+
sourceSigner,
|
|
1508
|
+
owner,
|
|
1509
|
+
input.source.chainId,
|
|
1510
|
+
executed
|
|
1511
|
+
);
|
|
1512
|
+
} catch (err) {
|
|
1513
|
+
if (isCashError(err)) throw err;
|
|
1514
|
+
throw errors.sourceRouteCompletedCashoutFailed(
|
|
1515
|
+
routedSource,
|
|
1516
|
+
mapChainError("resolve same-chain Relay nonce", err)
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1404
1519
|
const attributedParams2 = { ...params2, txOverrides: attribution };
|
|
1405
1520
|
const send2 = async () => {
|
|
1406
1521
|
try {
|
|
@@ -1773,7 +1888,8 @@ var bigintString = z.string().regex(/^-?\d+$/, "expected a decimal bigint string
|
|
|
1773
1888
|
var nonNegativeBigintString = z.string().regex(/^\d+$/, "expected a non-negative decimal bigint string");
|
|
1774
1889
|
var relayTransactionJsonSchema = z.object({
|
|
1775
1890
|
hash: z.string(),
|
|
1776
|
-
chainId: z.number()
|
|
1891
|
+
chainId: z.number(),
|
|
1892
|
+
isBatchTx: z.boolean().optional()
|
|
1777
1893
|
});
|
|
1778
1894
|
var relayTransactionsJsonSchema = z.object({
|
|
1779
1895
|
origin: z.array(relayTransactionJsonSchema),
|
package/dist/react.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CurrencyType } from '@zkp2p/sdk';
|
|
2
|
-
import { q as CashClient, E as EstimateInput, i as CashEstimate, B as CashoutOptions, h as CashoutResult, A as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-
|
|
2
|
+
import { q as CashClient, E as EstimateInput, i as CashEstimate, B as CashoutOptions, h as CashoutResult, A as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-jUA_GNdh.cjs';
|
|
3
3
|
import { WalletClient } from 'viem';
|
|
4
4
|
import '@relayprotocol/relay-sdk';
|
|
5
5
|
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CurrencyType } from '@zkp2p/sdk';
|
|
2
|
-
import { q as CashClient, E as EstimateInput, i as CashEstimate, B as CashoutOptions, h as CashoutResult, A as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-
|
|
2
|
+
import { q as CashClient, E as EstimateInput, i as CashEstimate, B as CashoutOptions, h as CashoutResult, A as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-jUA_GNdh.js';
|
|
3
3
|
import { WalletClient } from 'viem';
|
|
4
4
|
import '@relayprotocol/relay-sdk';
|
|
5
5
|
|
package/dist/tools.cjs
CHANGED
package/dist/tools.js
CHANGED
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,
|
|
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.
|
|
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://
|
|
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.
|
|
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.
|
|
114
|
-
"@types/node": "^22.
|
|
115
|
-
"@types/react": "^19.
|
|
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.
|
|
118
|
-
"eslint-config-prettier": "^9.1.
|
|
119
|
-
"prettier": "^3.
|
|
120
|
-
"react": "^19.
|
|
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.
|
|
123
|
-
"typescript": "^5.
|
|
124
|
-
"typescript-eslint": "^8.
|
|
125
|
-
"viem": "^2.55.
|
|
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
|
}
|