@zkp2p/cash 0.4.7 → 0.4.8
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 +12 -10
- package/README.md +26 -22
- package/dist/{chunk-SYE25ICW.js → chunk-CSDSJVI7.js} +16 -7
- package/dist/{createCashClient-CL1SCbqF.d.cts → createCashClient-BJmz3v4_.d.cts} +5 -8
- package/dist/{createCashClient-CL1SCbqF.d.ts → createCashClient-BJmz3v4_.d.ts} +5 -8
- package/dist/index.cjs +97 -22
- package/dist/index.d.cts +301 -13
- package/dist/index.d.ts +301 -13
- package/dist/index.js +83 -17
- 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 +12 -11
- package/examples/node-cashout.ts +6 -5
- package/llms.txt +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MARKET_SPREAD_BPS, ORACLE_MIN_CONVERSION_RATE_SENTINEL, CASH_RETAIN_ON_EMPTY, BASE_USDC_ADDRESS, USDC_DECIMALS, BASE_CHAIN_ID,
|
|
2
|
-
export { BASE_CHAIN_ID, BASE_USDC_ADDRESS, CASH_ORDER_POLL_INTERVAL_MS, CASH_ORDER_STATUSES, CASH_RETAIN_ON_EMPTY, CashError, MARKET_SPREAD_BPS, ORACLE_MIN_CONVERSION_RATE_SENTINEL, USDC_DECIMALS, errors, isCashError, isUserRejectedError } from './chunk-
|
|
1
|
+
import { MARKET_SPREAD_BPS, ORACLE_MIN_CONVERSION_RATE_SENTINEL, CASH_RETAIN_ON_EMPTY, BASE_USDC_ADDRESS, USDC_DECIMALS, BASE_CHAIN_ID, errors, isCashError, CASH_ORDER_STATUSES, mapChainError, CashError, CASH_ACCESS_GROUP_IDS, CASH_RESTRICTED_PLATFORMS } from './chunk-CSDSJVI7.js';
|
|
2
|
+
export { BASE_CHAIN_ID, BASE_USDC_ADDRESS, CASH_ORDER_POLL_INTERVAL_MS, CASH_ORDER_STATUSES, CASH_RETAIN_ON_EMPTY, CashError, MARKET_SPREAD_BPS, ORACLE_MIN_CONVERSION_RATE_SENTINEL, USDC_DECIMALS, errors, isCashError, isUserRejectedError } from './chunk-CSDSJVI7.js';
|
|
3
3
|
import { parseAbi, parseEventLogs, isAddress, http, createWalletClient, encodeFunctionData } from 'viem';
|
|
4
4
|
import { base } from 'viem/chains';
|
|
5
5
|
import { getSpreadOracleConfig, currencyInfo, getPaymentMethodsCatalog, getGatingServiceAddress, resolvePaymentMethodHashFromCatalog, resolvePaymentMethodNameFromHash, getCurrencyCodeFromHash, createCompositeDepositId, appendAttributionToCalldata, Zkp2pClient, CHAINLINK_ORACLE_FEEDS } from '@zkp2p/sdk';
|
|
@@ -461,7 +461,7 @@ function buildCapabilities(environment) {
|
|
|
461
461
|
currencies: [...new Set(currencies2)].sort(),
|
|
462
462
|
payeeHint: PAYEE_HINTS[platform] ?? "Your payment handle for this platform",
|
|
463
463
|
requiresIdentityAttestation: IDENTITY_ATTESTATION_PLATFORMS.has(platform),
|
|
464
|
-
requiresAtomicAccessPolicy:
|
|
464
|
+
requiresAtomicAccessPolicy: false
|
|
465
465
|
};
|
|
466
466
|
}).filter((p) => p.currencies.length > 0).sort((a, b) => a.platform.localeCompare(b.platform));
|
|
467
467
|
const currencies = [...new Set(platforms.flatMap((p) => p.currencies))].sort();
|
|
@@ -1296,6 +1296,11 @@ async function submitAndConfirm(client, verb, send) {
|
|
|
1296
1296
|
function isKnownPreBroadcastFailure(mapped) {
|
|
1297
1297
|
return mapped.code === "TRANSACTION_REJECTED" || mapped.code === "INSUFFICIENT_TOKEN_BALANCE" || mapped.code === "ALLOWANCE_NOT_VISIBLE" || mapped.code === "ESCROW_PAUSED";
|
|
1298
1298
|
}
|
|
1299
|
+
function requiresCashoutAccessPolicy(depositInput) {
|
|
1300
|
+
return depositInput.payouts.some(
|
|
1301
|
+
(payout) => CASH_RESTRICTED_PLATFORMS.has(payout.processorName.toLowerCase())
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1299
1304
|
function depositOrderOptions(deposit) {
|
|
1300
1305
|
const remaining = toBigIntOrUndefined(deposit.remainingDeposits);
|
|
1301
1306
|
const outstanding = toBigIntOrUndefined(deposit.outstandingIntentAmount);
|
|
@@ -1427,12 +1432,6 @@ function createCashClient(options) {
|
|
|
1427
1432
|
...range ? { intentAmountRange: range } : {}
|
|
1428
1433
|
};
|
|
1429
1434
|
}
|
|
1430
|
-
function assertGenericCashoutSupported(payoutInput) {
|
|
1431
|
-
const restrictedPlatforms = payoutInput.payouts.map((payout) => payout.processorName.toLowerCase()).filter((platform) => CASH_RESTRICTED_PLATFORMS.has(platform));
|
|
1432
|
-
if (restrictedPlatforms.length > 0) {
|
|
1433
|
-
throw errors.atomicAccessPolicyRequired(restrictedPlatforms);
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1436
1435
|
function isCashPayoutSet(payouts) {
|
|
1437
1436
|
return payouts.length > 0 && payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0);
|
|
1438
1437
|
}
|
|
@@ -1672,7 +1671,7 @@ function createCashClient(options) {
|
|
|
1672
1671
|
if (lastNonceError) throw lastNonceError;
|
|
1673
1672
|
throw new Error(`Signer provider did not observe Relay nonce ${afterRelay - 1}`);
|
|
1674
1673
|
}
|
|
1675
|
-
function prepareCashoutAccess(depositId, client = readClient) {
|
|
1674
|
+
function prepareCashoutAccess(depositId, client = readClient, source) {
|
|
1676
1675
|
const { compositeId, escrowAddress, onchainDepositId } = parseDepositId(depositId);
|
|
1677
1676
|
const groupIds = CASH_ACCESS_GROUP_IDS[environment];
|
|
1678
1677
|
try {
|
|
@@ -1691,9 +1690,50 @@ function createCashClient(options) {
|
|
|
1691
1690
|
chainId: prepared.chainId
|
|
1692
1691
|
};
|
|
1693
1692
|
} catch (err) {
|
|
1694
|
-
throw errors.accessPolicyConfigurationFailed(compositeId, groupIds,
|
|
1693
|
+
throw errors.accessPolicyConfigurationFailed(compositeId, groupIds, {
|
|
1694
|
+
cause: err,
|
|
1695
|
+
...source ? { source } : {}
|
|
1696
|
+
});
|
|
1695
1697
|
}
|
|
1696
1698
|
}
|
|
1699
|
+
async function configureCashoutAccess(client, signer, depositInput, depositId, source) {
|
|
1700
|
+
if (!requiresCashoutAccessPolicy(depositInput)) return void 0;
|
|
1701
|
+
const groupIds = CASH_ACCESS_GROUP_IDS[environment];
|
|
1702
|
+
const prepared = prepareCashoutAccess(depositId, client, source);
|
|
1703
|
+
let hash;
|
|
1704
|
+
try {
|
|
1705
|
+
hash = await signer.sendTransaction({
|
|
1706
|
+
account: signer.account,
|
|
1707
|
+
chain: signer.chain,
|
|
1708
|
+
to: prepared.to,
|
|
1709
|
+
data: prepared.data,
|
|
1710
|
+
value: prepared.value
|
|
1711
|
+
});
|
|
1712
|
+
} catch (err) {
|
|
1713
|
+
throw errors.accessPolicyConfigurationFailed(depositId, groupIds, {
|
|
1714
|
+
cause: err,
|
|
1715
|
+
...source ? { source } : {}
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
let receipt;
|
|
1719
|
+
try {
|
|
1720
|
+
receipt = await client.publicClient.waitForTransactionReceipt({ hash });
|
|
1721
|
+
} catch (err) {
|
|
1722
|
+
throw errors.accessPolicyConfigurationFailed(depositId, groupIds, {
|
|
1723
|
+
cause: err,
|
|
1724
|
+
transactionHash: hash,
|
|
1725
|
+
...source ? { source } : {}
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
if (receipt.status === "reverted") {
|
|
1729
|
+
throw errors.accessPolicyConfigurationFailed(depositId, groupIds, {
|
|
1730
|
+
cause: errors.transactionFailed(hash),
|
|
1731
|
+
transactionHash: hash,
|
|
1732
|
+
...source ? { source } : {}
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
return hash;
|
|
1736
|
+
}
|
|
1697
1737
|
return {
|
|
1698
1738
|
capabilities,
|
|
1699
1739
|
async sourceCapabilities() {
|
|
@@ -1731,7 +1771,6 @@ function createCashClient(options) {
|
|
|
1731
1771
|
},
|
|
1732
1772
|
async cashout(input, opts) {
|
|
1733
1773
|
const payoutInput = validatePayout(input);
|
|
1734
|
-
assertGenericCashoutSupported(payoutInput);
|
|
1735
1774
|
const client = await signingClient("cashout", opts);
|
|
1736
1775
|
const owner = opts.signer.account.address;
|
|
1737
1776
|
let sourceResult;
|
|
@@ -1829,6 +1868,13 @@ function createCashClient(options) {
|
|
|
1829
1868
|
const abi2 = client.escrowV2Abi ?? client.escrowAbi;
|
|
1830
1869
|
const resolved2 = resolveCashDepositId({ logs: receipt2.logs, abi: abi2 });
|
|
1831
1870
|
if (!resolved2) throw errors.depositResolutionFailed(hash2);
|
|
1871
|
+
const accessPolicyTxHash2 = await configureCashoutAccess(
|
|
1872
|
+
client,
|
|
1873
|
+
opts.signer,
|
|
1874
|
+
depositInput2,
|
|
1875
|
+
resolved2.compositeId,
|
|
1876
|
+
routedSource
|
|
1877
|
+
);
|
|
1832
1878
|
const order2 = deriveCashOrder(resolved2.compositeId, [], {
|
|
1833
1879
|
remainingAmount: depositInput2.amount,
|
|
1834
1880
|
status: "ACTIVE"
|
|
@@ -1839,6 +1885,7 @@ function createCashClient(options) {
|
|
|
1839
1885
|
escrowAddress: resolved2.escrowAddress,
|
|
1840
1886
|
onchainDepositId: resolved2.onchainDepositId,
|
|
1841
1887
|
order: order2,
|
|
1888
|
+
...accessPolicyTxHash2 ? { accessPolicyTxHash: accessPolicyTxHash2 } : {},
|
|
1842
1889
|
source: routedSource
|
|
1843
1890
|
};
|
|
1844
1891
|
}
|
|
@@ -1883,6 +1930,12 @@ function createCashClient(options) {
|
|
|
1883
1930
|
const abi = client.escrowV2Abi ?? client.escrowAbi;
|
|
1884
1931
|
const resolved = resolveCashDepositId({ logs: receipt.logs, abi });
|
|
1885
1932
|
if (!resolved) throw errors.depositResolutionFailed(hash);
|
|
1933
|
+
const accessPolicyTxHash = await configureCashoutAccess(
|
|
1934
|
+
client,
|
|
1935
|
+
opts.signer,
|
|
1936
|
+
depositInput,
|
|
1937
|
+
resolved.compositeId
|
|
1938
|
+
);
|
|
1886
1939
|
const order = deriveCashOrder(resolved.compositeId, [], {
|
|
1887
1940
|
remainingAmount: depositInput.amount,
|
|
1888
1941
|
status: "ACTIVE"
|
|
@@ -1893,13 +1946,13 @@ function createCashClient(options) {
|
|
|
1893
1946
|
escrowAddress: resolved.escrowAddress,
|
|
1894
1947
|
onchainDepositId: resolved.onchainDepositId,
|
|
1895
1948
|
order,
|
|
1949
|
+
...accessPolicyTxHash ? { accessPolicyTxHash } : {},
|
|
1896
1950
|
...sourceResult ? { source: sourceResult } : {}
|
|
1897
1951
|
};
|
|
1898
1952
|
},
|
|
1899
1953
|
async prepare(input) {
|
|
1900
1954
|
if (input.source) throw errors.sourceRouteUnsupportedInPrepare();
|
|
1901
1955
|
const depositInput = validateDepositInput(input.amount, input);
|
|
1902
|
-
assertGenericCashoutSupported(depositInput);
|
|
1903
1956
|
const params = await buildDepositParams(readClient, depositInput);
|
|
1904
1957
|
const { prepared } = await readClient.prepareCreateDeposit({
|
|
1905
1958
|
...params,
|
|
@@ -1932,7 +1985,7 @@ function createCashClient(options) {
|
|
|
1932
1985
|
}
|
|
1933
1986
|
],
|
|
1934
1987
|
register: { hashedOnchainIds },
|
|
1935
|
-
accessPolicyRequired:
|
|
1988
|
+
accessPolicyRequired: requiresCashoutAccessPolicy(depositInput)
|
|
1936
1989
|
};
|
|
1937
1990
|
},
|
|
1938
1991
|
finalizePreparedCashout(receipt) {
|
|
@@ -2559,7 +2612,8 @@ var cashErrorRecoveryJsonSchema = z.discriminatedUnion("kind", [
|
|
|
2559
2612
|
kind: z.literal("configure-cashout-access-policy"),
|
|
2560
2613
|
depositId: z.string(),
|
|
2561
2614
|
groupIds: z.array(z.string()),
|
|
2562
|
-
transactionHash: z.string().optional()
|
|
2615
|
+
transactionHash: z.string().optional(),
|
|
2616
|
+
source: z.object(cashSourceRecoveryJsonShape).strict().optional()
|
|
2563
2617
|
}).strict()
|
|
2564
2618
|
]);
|
|
2565
2619
|
var cashErrorJsonSchema = z.object({
|
|
@@ -2887,6 +2941,10 @@ function topUpResultFromJson(json) {
|
|
|
2887
2941
|
function capabilitiesToJson(caps) {
|
|
2888
2942
|
return {
|
|
2889
2943
|
...caps,
|
|
2944
|
+
platforms: caps.platforms.map((platform) => ({
|
|
2945
|
+
...platform,
|
|
2946
|
+
requiresAtomicAccessPolicy: false
|
|
2947
|
+
})),
|
|
2890
2948
|
amount: {
|
|
2891
2949
|
min: caps.amount.min.toString(),
|
|
2892
2950
|
recommendedMin: caps.amount.recommendedMin.toString(),
|
|
@@ -2905,7 +2963,7 @@ function capabilitiesFromJson(json) {
|
|
|
2905
2963
|
platforms: parsed.platforms.map((p) => ({
|
|
2906
2964
|
...p,
|
|
2907
2965
|
currencies: p.currencies,
|
|
2908
|
-
requiresAtomicAccessPolicy:
|
|
2966
|
+
requiresAtomicAccessPolicy: false
|
|
2909
2967
|
})),
|
|
2910
2968
|
currencies: parsed.currencies,
|
|
2911
2969
|
amount: {
|
|
@@ -2939,7 +2997,15 @@ function cashErrorFromJson(json) {
|
|
|
2939
2997
|
kind: parsed.recovery.kind,
|
|
2940
2998
|
depositId: parsed.recovery.depositId,
|
|
2941
2999
|
groupIds: parsed.recovery.groupIds,
|
|
2942
|
-
...parsed.recovery.transactionHash !== void 0 ? { transactionHash: parsed.recovery.transactionHash } : {}
|
|
3000
|
+
...parsed.recovery.transactionHash !== void 0 ? { transactionHash: parsed.recovery.transactionHash } : {},
|
|
3001
|
+
...parsed.recovery.source !== void 0 ? {
|
|
3002
|
+
source: {
|
|
3003
|
+
amount: parsed.recovery.source.amount,
|
|
3004
|
+
txHashes: parsed.recovery.source.txHashes,
|
|
3005
|
+
...parsed.recovery.source.requestId !== void 0 ? { requestId: parsed.recovery.source.requestId } : {},
|
|
3006
|
+
...parsed.recovery.source.transactions !== void 0 ? { transactions: parsed.recovery.source.transactions } : {}
|
|
3007
|
+
}
|
|
3008
|
+
} : {}
|
|
2943
3009
|
};
|
|
2944
3010
|
} else if (parsed.recovery.kind === "inspect-base-operation-submission") {
|
|
2945
3011
|
recovery = {
|
package/dist/react.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CurrencyType } from '@zkp2p/sdk';
|
|
2
|
-
import { s as CashClient, L as EstimateInput, i as CashEstimate, J as CashoutOptions, h as CashoutResult, H as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-
|
|
2
|
+
import { s as CashClient, L as EstimateInput, i as CashEstimate, J as CashoutOptions, h as CashoutResult, H as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-BJmz3v4_.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 { s as CashClient, L as EstimateInput, i as CashEstimate, J as CashoutOptions, h as CashoutResult, H as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-
|
|
2
|
+
import { s as CashClient, L as EstimateInput, i as CashEstimate, J as CashoutOptions, h as CashoutResult, H as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-BJmz3v4_.js';
|
|
3
3
|
import { WalletClient } from 'viem';
|
|
4
4
|
import '@relayprotocol/relay-sdk';
|
|
5
5
|
|
package/dist/react.js
CHANGED
package/dist/tools.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
|
-
version: "0.4.
|
|
5
|
+
version: "0.4.8"};
|
|
6
6
|
|
|
7
7
|
// src/tools/index.ts
|
|
8
8
|
var bigintString = {
|
|
@@ -164,7 +164,7 @@ var builtInCashTools = [
|
|
|
164
164
|
},
|
|
165
165
|
{
|
|
166
166
|
name: "cash_cashout",
|
|
167
|
-
description: "Start
|
|
167
|
+
description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For Venmo, Cash App, or PayPal, accessPolicyRequired is true: confirm createDeposit, finalize its receipt, then prepare and submit the access policy with the depositor. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.",
|
|
168
168
|
inputSchema: {
|
|
169
169
|
type: "object",
|
|
170
170
|
properties: {
|
package/dist/tools.d.cts
CHANGED
|
@@ -145,7 +145,7 @@ declare const builtInCashTools: readonly [{
|
|
|
145
145
|
};
|
|
146
146
|
}, {
|
|
147
147
|
readonly name: "cash_cashout";
|
|
148
|
-
readonly description: "Start
|
|
148
|
+
readonly description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For Venmo, Cash App, or PayPal, accessPolicyRequired is true: confirm createDeposit, finalize its receipt, then prepare and submit the access policy with the depositor. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.";
|
|
149
149
|
readonly inputSchema: {
|
|
150
150
|
readonly type: "object";
|
|
151
151
|
readonly properties: {
|
package/dist/tools.d.ts
CHANGED
|
@@ -145,7 +145,7 @@ declare const builtInCashTools: readonly [{
|
|
|
145
145
|
};
|
|
146
146
|
}, {
|
|
147
147
|
readonly name: "cash_cashout";
|
|
148
|
-
readonly description: "Start
|
|
148
|
+
readonly description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For Venmo, Cash App, or PayPal, accessPolicyRequired is true: confirm createDeposit, finalize its receipt, then prepare and submit the access policy with the depositor. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.";
|
|
149
149
|
readonly inputSchema: {
|
|
150
150
|
readonly type: "object";
|
|
151
151
|
readonly properties: {
|
package/dist/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
|
-
version: "0.4.
|
|
3
|
+
version: "0.4.8"};
|
|
4
4
|
|
|
5
5
|
// src/tools/index.ts
|
|
6
6
|
var bigintString = {
|
|
@@ -162,7 +162,7 @@ var builtInCashTools = [
|
|
|
162
162
|
},
|
|
163
163
|
{
|
|
164
164
|
name: "cash_cashout",
|
|
165
|
-
description: "Start
|
|
165
|
+
description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For Venmo, Cash App, or PayPal, accessPolicyRequired is true: confirm createDeposit, finalize its receipt, then prepare and submit the access policy with the depositor. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.",
|
|
166
166
|
inputSchema: {
|
|
167
167
|
type: "object",
|
|
168
168
|
properties: {
|
|
@@ -65,15 +65,16 @@ but the host or a signer-backed client must execute the route before
|
|
|
65
65
|
transaction confirms, call `finalizePreparedCashout(receipt)` to decode it with
|
|
66
66
|
the environment-correct escrow ABI and obtain the resumable `CashoutResult`.
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`
|
|
76
|
-
|
|
68
|
+
The deprecated `requiresAtomicAccessPolicy` capability is always `false`:
|
|
69
|
+
policy attachment is sequential, not atomic. Venmo, Cash App, and PayPal
|
|
70
|
+
cash-outs nevertheless attach Plus, Pro, Peer Makers, and Peer Pay groups by
|
|
71
|
+
default. Signed `cashout()` confirms the deposit before submitting and
|
|
72
|
+
confirming the policy with the same viem wallet, so a brief unprotected interval
|
|
73
|
+
exists. For `prepare()`, `accessPolicyRequired` marks whether the host must call
|
|
74
|
+
`prepareAccessPolicy(depositId)` after finalizing the confirmed deposit receipt.
|
|
75
|
+
Any viem `WalletClient`, including an EOA, can submit it; Privy is not required.
|
|
76
|
+
If the follow-up fails, the deposit already exists. Recover from
|
|
77
|
+
`ACCESS_POLICY_CONFIGURATION_FAILED` and never repeat the cash-out.
|
|
77
78
|
|
|
78
79
|
There is no static chain/token allowlist in Peer Cash. Relay decides source
|
|
79
80
|
support through its metadata and quote execution, filtered to the viem/EVM
|
|
@@ -301,7 +302,7 @@ explicit override.
|
|
|
301
302
|
| `INVALID_PAYOUT_PLATFORMS` | no | The payout leg set is empty or repeats a platform. Pass one leg, or an array of legs using each platform at most once. |
|
|
302
303
|
| `PAYEE_VERIFICATION_REQUIRED` | no | A new Wise/PayPal payee needs an attestation. Register it through Peer first; an existing registration can be reused. |
|
|
303
304
|
| `PAYEE_REGISTRATION_FAILED` | yes | Curator rejected the handle or was unavailable. Check `payeeHint` and retry. |
|
|
304
|
-
| `ATOMIC_ACCESS_POLICY_REQUIRED` | no |
|
|
305
|
+
| `ATOMIC_ACCESS_POLICY_REQUIRED` | no | Deprecated compatibility code. Current SDK flows never emit it. |
|
|
305
306
|
| `SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE` | no | `prepare()` accepts Base USDC only. Use signed source execution, or complete Relay first and then prepare the Base cashout. |
|
|
306
307
|
| `SOURCE_RECIPIENT_MISMATCH` | no | Relay output recipient differs from the cashout depositor. Use the depositor address. |
|
|
307
308
|
| `SOURCE_CAPABILITIES_FAILED` | yes | Relay source discovery failed. Retry or use Base USDC. |
|
|
@@ -319,7 +320,7 @@ explicit override.
|
|
|
319
320
|
| `TRANSACTION_SUBMISSION_UNKNOWN` | no | A Base mutation returned no hash but may have broadcast. Inspect wallet/protocol state and its recovery action before any retry. |
|
|
320
321
|
| `TRANSACTION_STATUS_UNKNOWN` | no | A transaction was submitted but its receipt is unknown. Inspect `recovery.transactionHash` before resubmitting. |
|
|
321
322
|
| `DEPOSIT_RESOLUTION_FAILED` | no | Base tx succeeded but no `DepositReceived` was decoded. Inspect its logs and recover the composite id. |
|
|
322
|
-
| `ACCESS_POLICY_CONFIGURATION_FAILED` | no |
|
|
323
|
+
| `ACCESS_POLICY_CONFIGURATION_FAILED` | no | Optional policy preparation failed. The cash-out remains valid; retry the opt-in with the same depositor if desired. |
|
|
323
324
|
| `INVALID_DEPOSIT_ID` | no | The id is not `escrowAddress_onchainId`. A bare number cannot cold-hydrate; use the value returned by `cashout()`. |
|
|
324
325
|
| `ORDER_NOT_FOUND` | yes | Unknown id or immediate indexer lag. Verify the id and retry shortly after creation. |
|
|
325
326
|
| `INDEXER_LAG` | yes | Indexer trails the chain. Retry the read shortly. |
|
package/examples/node-cashout.ts
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* The curator validates supported handles against the live platform, so the
|
|
12
12
|
* payee must be a real account. A new Wise/PayPal registration also needs the
|
|
13
13
|
* identity attestation created by Peer; an existing registered handle can be
|
|
14
|
-
* reused.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* reused. This private-key EOA works directly with every supported platform;
|
|
15
|
+
* no Privy wallet is required. Venmo, Cash App, and PayPal attach their access
|
|
16
|
+
* policy in a confirmed follow-up transaction. Override the demo corridor with:
|
|
17
17
|
* CASH_PLATFORM=revolut CASH_CURRENCY=EUR CASH_PAYEE=your-revtag
|
|
18
18
|
*/
|
|
19
19
|
import { createWalletClient, http } from 'viem';
|
|
@@ -28,9 +28,9 @@ const signer = createWalletClient({ account, chain: base, transport: http() });
|
|
|
28
28
|
// One leg here; `receive` also accepts an array of legs to offer several
|
|
29
29
|
// platforms on one order (each platform at most once, all at the oracle rate).
|
|
30
30
|
const receive = {
|
|
31
|
-
platform: process.env.CASH_PLATFORM ?? '
|
|
31
|
+
platform: process.env.CASH_PLATFORM ?? 'venmo',
|
|
32
32
|
currency: (process.env.CASH_CURRENCY ?? 'USD') as CurrencyType,
|
|
33
|
-
payee: { offchainId: process.env.CASH_PAYEE ?? '
|
|
33
|
+
payee: { offchainId: process.env.CASH_PAYEE ?? '@your-venmo' },
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
const cash = createCashClient({ environment: 'staging' });
|
|
@@ -51,6 +51,7 @@ console.log(
|
|
|
51
51
|
// 2 - Cash out.
|
|
52
52
|
const result = await cash.cashout({ amount: usdc(1), receive }, { signer });
|
|
53
53
|
console.log(`deposit created: ${result.depositId} (tx ${result.txHash})`);
|
|
54
|
+
if (result.accessPolicyTxHash) console.log(`access policy attached: ${result.accessPolicyTxHash}`);
|
|
54
55
|
// Persist this in YOUR system: userId → result.depositId
|
|
55
56
|
|
|
56
57
|
// 3/5 - Track it. A real service would watch until terminal; the demo bails
|
package/llms.txt
CHANGED
|
@@ -69,6 +69,10 @@ Key facts:
|
|
|
69
69
|
`sourceSigner`.
|
|
70
70
|
- Wise and PayPal require attestation for a new payee registration; a
|
|
71
71
|
previously registered bare handle can be reused.
|
|
72
|
+
- Venmo, Cash App, and PayPal attach Plus, Pro, Peer Makers, and Peer Pay
|
|
73
|
+
groups after the deposit confirms. The follow-up is intentionally non-atomic;
|
|
74
|
+
`cashout()` submits it with the same viem wallet, while prepared hosts must
|
|
75
|
+
act when `accessPolicyRequired` is true. Any EOA works; Privy is not required.
|
|
72
76
|
- Preproduction uses https://api-preprod.zkp2p.xyz by default; staging uses
|
|
73
77
|
https://api-staging.zkp2p.xyz. curatorUrl can override either.
|
|
74
78
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkp2p/cash",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.8",
|
|
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)",
|