@zkp2p/cash 0.4.7 → 0.4.9
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 +32 -17
- package/README.md +130 -94
- package/dist/{chunk-SYE25ICW.js → chunk-4LPWKZMW.js} +17 -8
- package/dist/{createCashClient-CL1SCbqF.d.cts → createCashClient-Br7uu4lQ.d.cts} +9 -8
- package/dist/{createCashClient-CL1SCbqF.d.ts → createCashClient-Br7uu4lQ.d.ts} +9 -8
- package/dist/index.cjs +99 -28
- package/dist/index.d.cts +307 -2910
- package/dist/index.d.ts +307 -2910
- package/dist/index.js +84 -22
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/tools.cjs +2 -2
- package/dist/tools.d.cts +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +2 -2
- package/docs/lifecycle-and-recovery.md +20 -14
- package/examples/agent-tool-use.ts +8 -2
- package/examples/node-cashout.ts +8 -6
- package/llms.txt +13 -3
- package/package.json +12 -12
- package/skills/peer-cash-integration/SKILL.md +26 -6
package/dist/index.cjs
CHANGED
|
@@ -498,7 +498,7 @@ function buildCapabilities(environment) {
|
|
|
498
498
|
currencies: [...new Set(currencies2)].sort(),
|
|
499
499
|
payeeHint: PAYEE_HINTS[platform] ?? "Your payment handle for this platform",
|
|
500
500
|
requiresIdentityAttestation: IDENTITY_ATTESTATION_PLATFORMS.has(platform),
|
|
501
|
-
requiresAtomicAccessPolicy:
|
|
501
|
+
requiresAtomicAccessPolicy: false
|
|
502
502
|
};
|
|
503
503
|
}).filter((p) => p.currencies.length > 0).sort((a, b) => a.platform.localeCompare(b.platform));
|
|
504
504
|
const currencies = [...new Set(platforms.flatMap((p) => p.currencies))].sort();
|
|
@@ -676,15 +676,16 @@ var errors = {
|
|
|
676
676
|
code: "PAYEE_VERIFICATION_REQUIRED",
|
|
677
677
|
message: `${platform} requires a verified maker identity attestation to register a payee; a bare handle is not accepted.`,
|
|
678
678
|
retryable: false,
|
|
679
|
-
remediation: `Register this ${platform} payee through
|
|
679
|
+
remediation: `Register this ${platform} payee through Peer web and its TEE browser extension, which produces the signed identity attestation, before cashing out. capabilities() flags such platforms with requiresIdentityAttestation: true.`
|
|
680
680
|
},
|
|
681
681
|
{ cause }
|
|
682
682
|
),
|
|
683
|
+
/** @deprecated Cash-outs no longer require an atomic access-policy flow. */
|
|
683
684
|
atomicAccessPolicyRequired: (platforms) => new CashError({
|
|
684
685
|
code: "ATOMIC_ACCESS_POLICY_REQUIRED",
|
|
685
|
-
message:
|
|
686
|
+
message: `Atomic access-policy enforcement for ${platforms.join(", ")} is deprecated.`,
|
|
686
687
|
retryable: false,
|
|
687
|
-
remediation: `
|
|
688
|
+
remediation: `Upgrade @zkp2p/cash; current cash-out flows do not require atomic access-policy configuration.`
|
|
688
689
|
}),
|
|
689
690
|
sourceRouteUnsupportedInPrepare: () => new CashError({
|
|
690
691
|
code: "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE",
|
|
@@ -887,20 +888,28 @@ var errors = {
|
|
|
887
888
|
},
|
|
888
889
|
{ cause }
|
|
889
890
|
),
|
|
890
|
-
accessPolicyConfigurationFailed: (depositId, groupIds,
|
|
891
|
+
accessPolicyConfigurationFailed: (depositId, groupIds, context = {}) => new CashError(
|
|
891
892
|
{
|
|
892
893
|
code: "ACCESS_POLICY_CONFIGURATION_FAILED",
|
|
893
|
-
message: `Cash-out deposit ${depositId} was created, but its
|
|
894
|
+
message: `Cash-out deposit ${depositId} was created, but its access policy could not be confirmed.`,
|
|
894
895
|
retryable: false,
|
|
895
|
-
remediation: `Do not
|
|
896
|
+
remediation: `Do not create another cash-out. If recovery.transactionHash is present, inspect that policy transaction first. Otherwise, or if it is confirmed reverted, submit and confirm prepareAccessPolicy(recovery.depositId) with the same depositor wallet.`,
|
|
896
897
|
recovery: {
|
|
897
898
|
kind: "configure-cashout-access-policy",
|
|
898
899
|
depositId,
|
|
899
900
|
groupIds: [...groupIds],
|
|
900
|
-
...transactionHash ? { transactionHash } : {}
|
|
901
|
+
...context.transactionHash ? { transactionHash: context.transactionHash } : {},
|
|
902
|
+
...context.source ? {
|
|
903
|
+
source: {
|
|
904
|
+
amount: context.source.amount.toString(),
|
|
905
|
+
...context.source.requestId ? { requestId: context.source.requestId } : {},
|
|
906
|
+
txHashes: context.source.txHashes,
|
|
907
|
+
...context.source.transactions ? { transactions: context.source.transactions } : {}
|
|
908
|
+
}
|
|
909
|
+
} : {}
|
|
901
910
|
}
|
|
902
911
|
},
|
|
903
|
-
{ cause }
|
|
912
|
+
{ cause: context.cause }
|
|
904
913
|
),
|
|
905
914
|
escrowPaused: () => new CashError({
|
|
906
915
|
code: "ESCROW_PAUSED",
|
|
@@ -1786,6 +1795,11 @@ async function submitAndConfirm(client, verb, send) {
|
|
|
1786
1795
|
function isKnownPreBroadcastFailure(mapped) {
|
|
1787
1796
|
return mapped.code === "TRANSACTION_REJECTED" || mapped.code === "INSUFFICIENT_TOKEN_BALANCE" || mapped.code === "ALLOWANCE_NOT_VISIBLE" || mapped.code === "ESCROW_PAUSED";
|
|
1788
1797
|
}
|
|
1798
|
+
function requiresCashoutAccessPolicy(depositInput) {
|
|
1799
|
+
return depositInput.payouts.some(
|
|
1800
|
+
(payout) => CASH_RESTRICTED_PLATFORMS.has(payout.processorName.toLowerCase())
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1789
1803
|
function depositOrderOptions(deposit) {
|
|
1790
1804
|
const remaining = toBigIntOrUndefined(deposit.remainingDeposits);
|
|
1791
1805
|
const outstanding = toBigIntOrUndefined(deposit.outstandingIntentAmount);
|
|
@@ -1917,12 +1931,6 @@ function createCashClient(options) {
|
|
|
1917
1931
|
...range ? { intentAmountRange: range } : {}
|
|
1918
1932
|
};
|
|
1919
1933
|
}
|
|
1920
|
-
function assertGenericCashoutSupported(payoutInput) {
|
|
1921
|
-
const restrictedPlatforms = payoutInput.payouts.map((payout) => payout.processorName.toLowerCase()).filter((platform) => CASH_RESTRICTED_PLATFORMS.has(platform));
|
|
1922
|
-
if (restrictedPlatforms.length > 0) {
|
|
1923
|
-
throw errors.atomicAccessPolicyRequired(restrictedPlatforms);
|
|
1924
|
-
}
|
|
1925
|
-
}
|
|
1926
1934
|
function isCashPayoutSet(payouts) {
|
|
1927
1935
|
return payouts.length > 0 && payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0);
|
|
1928
1936
|
}
|
|
@@ -2162,7 +2170,7 @@ function createCashClient(options) {
|
|
|
2162
2170
|
if (lastNonceError) throw lastNonceError;
|
|
2163
2171
|
throw new Error(`Signer provider did not observe Relay nonce ${afterRelay - 1}`);
|
|
2164
2172
|
}
|
|
2165
|
-
function prepareCashoutAccess(depositId, client = readClient) {
|
|
2173
|
+
function prepareCashoutAccess(depositId, client = readClient, source) {
|
|
2166
2174
|
const { compositeId, escrowAddress, onchainDepositId } = parseDepositId(depositId);
|
|
2167
2175
|
const groupIds = CASH_ACCESS_GROUP_IDS[environment];
|
|
2168
2176
|
try {
|
|
@@ -2181,9 +2189,50 @@ function createCashClient(options) {
|
|
|
2181
2189
|
chainId: prepared.chainId
|
|
2182
2190
|
};
|
|
2183
2191
|
} catch (err) {
|
|
2184
|
-
throw errors.accessPolicyConfigurationFailed(compositeId, groupIds,
|
|
2192
|
+
throw errors.accessPolicyConfigurationFailed(compositeId, groupIds, {
|
|
2193
|
+
cause: err,
|
|
2194
|
+
...source ? { source } : {}
|
|
2195
|
+
});
|
|
2185
2196
|
}
|
|
2186
2197
|
}
|
|
2198
|
+
async function configureCashoutAccess(client, signer, depositInput, depositId, source) {
|
|
2199
|
+
if (!requiresCashoutAccessPolicy(depositInput)) return void 0;
|
|
2200
|
+
const groupIds = CASH_ACCESS_GROUP_IDS[environment];
|
|
2201
|
+
const prepared = prepareCashoutAccess(depositId, client, source);
|
|
2202
|
+
let hash;
|
|
2203
|
+
try {
|
|
2204
|
+
hash = await signer.sendTransaction({
|
|
2205
|
+
account: signer.account,
|
|
2206
|
+
chain: signer.chain,
|
|
2207
|
+
to: prepared.to,
|
|
2208
|
+
data: prepared.data,
|
|
2209
|
+
value: prepared.value
|
|
2210
|
+
});
|
|
2211
|
+
} catch (err) {
|
|
2212
|
+
throw errors.accessPolicyConfigurationFailed(depositId, groupIds, {
|
|
2213
|
+
cause: err,
|
|
2214
|
+
...source ? { source } : {}
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
let receipt;
|
|
2218
|
+
try {
|
|
2219
|
+
receipt = await client.publicClient.waitForTransactionReceipt({ hash });
|
|
2220
|
+
} catch (err) {
|
|
2221
|
+
throw errors.accessPolicyConfigurationFailed(depositId, groupIds, {
|
|
2222
|
+
cause: err,
|
|
2223
|
+
transactionHash: hash,
|
|
2224
|
+
...source ? { source } : {}
|
|
2225
|
+
});
|
|
2226
|
+
}
|
|
2227
|
+
if (receipt.status === "reverted") {
|
|
2228
|
+
throw errors.accessPolicyConfigurationFailed(depositId, groupIds, {
|
|
2229
|
+
cause: errors.transactionFailed(hash),
|
|
2230
|
+
transactionHash: hash,
|
|
2231
|
+
...source ? { source } : {}
|
|
2232
|
+
});
|
|
2233
|
+
}
|
|
2234
|
+
return hash;
|
|
2235
|
+
}
|
|
2187
2236
|
return {
|
|
2188
2237
|
capabilities,
|
|
2189
2238
|
async sourceCapabilities() {
|
|
@@ -2221,11 +2270,8 @@ function createCashClient(options) {
|
|
|
2221
2270
|
},
|
|
2222
2271
|
async cashout(input, opts) {
|
|
2223
2272
|
const payoutInput = validatePayout(input);
|
|
2224
|
-
assertGenericCashoutSupported(payoutInput);
|
|
2225
2273
|
const client = await signingClient("cashout", opts);
|
|
2226
2274
|
const owner = opts.signer.account.address;
|
|
2227
|
-
let sourceResult;
|
|
2228
|
-
let cashoutAmount = input.amount;
|
|
2229
2275
|
if (input.source) {
|
|
2230
2276
|
const sourceSigner = opts.sourceSigner ?? (input.source.chainId === BASE_CHAIN_ID ? opts.signer : void 0);
|
|
2231
2277
|
if (!sourceSigner?.account) throw errors.signerRequired("source cashout");
|
|
@@ -2246,7 +2292,7 @@ function createCashClient(options) {
|
|
|
2246
2292
|
if (relayQuote.outputAmount < MIN_CASHOUT_AMOUNT) {
|
|
2247
2293
|
throw errors.amountBelowMinimum(relayQuote.outputAmount, MIN_CASHOUT_AMOUNT);
|
|
2248
2294
|
}
|
|
2249
|
-
cashoutAmount = relayQuote.outputAmount;
|
|
2295
|
+
const cashoutAmount = relayQuote.outputAmount;
|
|
2250
2296
|
const depositInput2 = validateDepositInput(cashoutAmount, input, payoutInput);
|
|
2251
2297
|
const params2 = await buildDepositParams(client, depositInput2);
|
|
2252
2298
|
const escrow2 = client.escrowV2Address ?? client.escrowAddress;
|
|
@@ -2263,7 +2309,6 @@ function createCashClient(options) {
|
|
|
2263
2309
|
txHashes: executed.txHashes,
|
|
2264
2310
|
...executed.transactions ? { transactions: executed.transactions } : {}
|
|
2265
2311
|
};
|
|
2266
|
-
sourceResult = routedSource;
|
|
2267
2312
|
try {
|
|
2268
2313
|
await waitForBaseSignerAfterRelay(
|
|
2269
2314
|
client,
|
|
@@ -2319,6 +2364,13 @@ function createCashClient(options) {
|
|
|
2319
2364
|
const abi2 = client.escrowV2Abi ?? client.escrowAbi;
|
|
2320
2365
|
const resolved2 = resolveCashDepositId({ logs: receipt2.logs, abi: abi2 });
|
|
2321
2366
|
if (!resolved2) throw errors.depositResolutionFailed(hash2);
|
|
2367
|
+
const accessPolicyTxHash2 = await configureCashoutAccess(
|
|
2368
|
+
client,
|
|
2369
|
+
opts.signer,
|
|
2370
|
+
depositInput2,
|
|
2371
|
+
resolved2.compositeId,
|
|
2372
|
+
routedSource
|
|
2373
|
+
);
|
|
2322
2374
|
const order2 = deriveCashOrder(resolved2.compositeId, [], {
|
|
2323
2375
|
remainingAmount: depositInput2.amount,
|
|
2324
2376
|
status: "ACTIVE"
|
|
@@ -2329,6 +2381,7 @@ function createCashClient(options) {
|
|
|
2329
2381
|
escrowAddress: resolved2.escrowAddress,
|
|
2330
2382
|
onchainDepositId: resolved2.onchainDepositId,
|
|
2331
2383
|
order: order2,
|
|
2384
|
+
...accessPolicyTxHash2 ? { accessPolicyTxHash: accessPolicyTxHash2 } : {},
|
|
2332
2385
|
source: routedSource
|
|
2333
2386
|
};
|
|
2334
2387
|
}
|
|
@@ -2373,6 +2426,12 @@ function createCashClient(options) {
|
|
|
2373
2426
|
const abi = client.escrowV2Abi ?? client.escrowAbi;
|
|
2374
2427
|
const resolved = resolveCashDepositId({ logs: receipt.logs, abi });
|
|
2375
2428
|
if (!resolved) throw errors.depositResolutionFailed(hash);
|
|
2429
|
+
const accessPolicyTxHash = await configureCashoutAccess(
|
|
2430
|
+
client,
|
|
2431
|
+
opts.signer,
|
|
2432
|
+
depositInput,
|
|
2433
|
+
resolved.compositeId
|
|
2434
|
+
);
|
|
2376
2435
|
const order = deriveCashOrder(resolved.compositeId, [], {
|
|
2377
2436
|
remainingAmount: depositInput.amount,
|
|
2378
2437
|
status: "ACTIVE"
|
|
@@ -2383,13 +2442,12 @@ function createCashClient(options) {
|
|
|
2383
2442
|
escrowAddress: resolved.escrowAddress,
|
|
2384
2443
|
onchainDepositId: resolved.onchainDepositId,
|
|
2385
2444
|
order,
|
|
2386
|
-
...
|
|
2445
|
+
...accessPolicyTxHash ? { accessPolicyTxHash } : {}
|
|
2387
2446
|
};
|
|
2388
2447
|
},
|
|
2389
2448
|
async prepare(input) {
|
|
2390
2449
|
if (input.source) throw errors.sourceRouteUnsupportedInPrepare();
|
|
2391
2450
|
const depositInput = validateDepositInput(input.amount, input);
|
|
2392
|
-
assertGenericCashoutSupported(depositInput);
|
|
2393
2451
|
const params = await buildDepositParams(readClient, depositInput);
|
|
2394
2452
|
const { prepared } = await readClient.prepareCreateDeposit({
|
|
2395
2453
|
...params,
|
|
@@ -2422,7 +2480,7 @@ function createCashClient(options) {
|
|
|
2422
2480
|
}
|
|
2423
2481
|
],
|
|
2424
2482
|
register: { hashedOnchainIds },
|
|
2425
|
-
accessPolicyRequired:
|
|
2483
|
+
accessPolicyRequired: requiresCashoutAccessPolicy(depositInput)
|
|
2426
2484
|
};
|
|
2427
2485
|
},
|
|
2428
2486
|
finalizePreparedCashout(receipt) {
|
|
@@ -3049,7 +3107,8 @@ var cashErrorRecoveryJsonSchema = zod.z.discriminatedUnion("kind", [
|
|
|
3049
3107
|
kind: zod.z.literal("configure-cashout-access-policy"),
|
|
3050
3108
|
depositId: zod.z.string(),
|
|
3051
3109
|
groupIds: zod.z.array(zod.z.string()),
|
|
3052
|
-
transactionHash: zod.z.string().optional()
|
|
3110
|
+
transactionHash: zod.z.string().optional(),
|
|
3111
|
+
source: zod.z.object(cashSourceRecoveryJsonShape).strict().optional()
|
|
3053
3112
|
}).strict()
|
|
3054
3113
|
]);
|
|
3055
3114
|
var cashErrorJsonSchema = zod.z.object({
|
|
@@ -3377,6 +3436,10 @@ function topUpResultFromJson(json) {
|
|
|
3377
3436
|
function capabilitiesToJson(caps) {
|
|
3378
3437
|
return {
|
|
3379
3438
|
...caps,
|
|
3439
|
+
platforms: caps.platforms.map((platform) => ({
|
|
3440
|
+
...platform,
|
|
3441
|
+
requiresAtomicAccessPolicy: false
|
|
3442
|
+
})),
|
|
3380
3443
|
amount: {
|
|
3381
3444
|
min: caps.amount.min.toString(),
|
|
3382
3445
|
recommendedMin: caps.amount.recommendedMin.toString(),
|
|
@@ -3395,7 +3458,7 @@ function capabilitiesFromJson(json) {
|
|
|
3395
3458
|
platforms: parsed.platforms.map((p) => ({
|
|
3396
3459
|
...p,
|
|
3397
3460
|
currencies: p.currencies,
|
|
3398
|
-
requiresAtomicAccessPolicy:
|
|
3461
|
+
requiresAtomicAccessPolicy: false
|
|
3399
3462
|
})),
|
|
3400
3463
|
currencies: parsed.currencies,
|
|
3401
3464
|
amount: {
|
|
@@ -3429,7 +3492,15 @@ function cashErrorFromJson(json) {
|
|
|
3429
3492
|
kind: parsed.recovery.kind,
|
|
3430
3493
|
depositId: parsed.recovery.depositId,
|
|
3431
3494
|
groupIds: parsed.recovery.groupIds,
|
|
3432
|
-
...parsed.recovery.transactionHash !== void 0 ? { transactionHash: parsed.recovery.transactionHash } : {}
|
|
3495
|
+
...parsed.recovery.transactionHash !== void 0 ? { transactionHash: parsed.recovery.transactionHash } : {},
|
|
3496
|
+
...parsed.recovery.source !== void 0 ? {
|
|
3497
|
+
source: {
|
|
3498
|
+
amount: parsed.recovery.source.amount,
|
|
3499
|
+
txHashes: parsed.recovery.source.txHashes,
|
|
3500
|
+
...parsed.recovery.source.requestId !== void 0 ? { requestId: parsed.recovery.source.requestId } : {},
|
|
3501
|
+
...parsed.recovery.source.transactions !== void 0 ? { transactions: parsed.recovery.source.transactions } : {}
|
|
3502
|
+
}
|
|
3503
|
+
} : {}
|
|
3433
3504
|
};
|
|
3434
3505
|
} else if (parsed.recovery.kind === "inspect-base-operation-submission") {
|
|
3435
3506
|
recovery = {
|