@zkp2p/cash 0.1.6 → 0.1.7
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 +13 -2
- package/README.md +11 -0
- package/dist/{chunk-P3KYZ2FX.js → chunk-TR6JVYYF.js} +6 -0
- package/dist/index.cjs +16 -0
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +12 -2
- package/dist/react.js +1 -1
- package/dist/tools.cjs +1 -1
- package/dist/tools.js +1 -1
- package/docs/lifecycle-and-recovery.md +21 -2
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -110,10 +110,19 @@ console.log(routed.source?.transactions?.origin, routed.source?.transactions?.de
|
|
|
110
110
|
`sourceSigner`. Use `EXACT_INPUT` in high-level cash-out flows so `amount`
|
|
111
111
|
remains source-token base units. `source.amount` is Relay's guaranteed
|
|
112
112
|
minimum output and the exact Base USDC deposit amount.
|
|
113
|
+
- **Use a nonce-managed source signer for routed cashouts.** Relay routes
|
|
114
|
+
with more than one source-chain transaction (approve, then route) are
|
|
115
|
+
refused preflight with `SOURCE_NONCE_MANAGER_REQUIRED` on plain local
|
|
116
|
+
accounts - create the source signer with
|
|
117
|
+
`privateKeyToAccount(pk, { nonceManager })`. Browser (`json-rpc`) wallets
|
|
118
|
+
are unaffected.
|
|
113
119
|
- **Persist source evidence.** A routed result carries `requestId`, flat
|
|
114
120
|
`txHashes`, and chain-aware `transactions.origin` / `.destination` arrays.
|
|
115
121
|
- **Never repeat a completed or uncertain route.** On `SOURCE_EXECUTION_FAILED`,
|
|
116
|
-
inspect its Relay request and transaction recovery evidence.
|
|
122
|
+
inspect its Relay request and transaction recovery evidence. A failed
|
|
123
|
+
approval-only route can sit in `relayStatus` `waiting` indefinitely - decide
|
|
124
|
+
from the recovery payload and origin transactions, never by waiting for a
|
|
125
|
+
terminal Relay status. On
|
|
117
126
|
`SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED`, retry without `source` using
|
|
118
127
|
`BigInt(err.recovery.amount)`. On `SOURCE_CASHOUT_SUBMISSION_UNKNOWN`, inspect
|
|
119
128
|
Base wallet activity and `orders(err.recovery.depositor)`. On
|
|
@@ -128,7 +137,8 @@ console.log(routed.source?.transactions?.origin, routed.source?.transactions?.de
|
|
|
128
137
|
deposit. The tx receipt you hold is the truth. Retry; `watch()` absorbs
|
|
129
138
|
this automatically.
|
|
130
139
|
- **Unwind with `withdraw()` only.** It is state-aware (prunes expired
|
|
131
|
-
intents first). Do not call escrow functions directly.
|
|
140
|
+
intents first). Do not call escrow functions directly. Partial withdrawals
|
|
141
|
+
increment `returnedAmount`; `totalAmount` is historical and never shrinks.
|
|
132
142
|
- **Read fills as receipts.** `fiatOwed` is the buyer's obligation at the
|
|
133
143
|
locked rate; after the proof, `fiatPaid`/`paymentId`/`releasedAmount` are
|
|
134
144
|
the verified outcome. Reconcile against those, not your own math.
|
|
@@ -161,6 +171,7 @@ Every `CashError` carries `code`, `retryable`, `remediation`. Behavior:
|
|
|
161
171
|
| `SOURCE_RECIPIENT_MISMATCH` | no | Route Base USDC to the cashout depositor |
|
|
162
172
|
| `SOURCE_CAPABILITIES_FAILED` | yes | Retry discovery or fall back to Base USDC |
|
|
163
173
|
| `SOURCE_QUOTE_FAILED` | yes | Refresh capabilities and request a new canonical Base-USDC quote |
|
|
174
|
+
| `SOURCE_NONCE_MANAGER_REQUIRED` | no | Preflight; recreate the source signer with viem's `nonceManager`, then quote again |
|
|
164
175
|
| `SOURCE_EXECUTION_FAILED` | no | Inspect source transactions and Relay status before any retry |
|
|
165
176
|
| `SOURCE_STATUS_FAILED` | yes | Retry only the status read |
|
|
166
177
|
| `SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED` | no | Do not route again; retry Base-only with `recovery.amount` |
|
package/README.md
CHANGED
|
@@ -107,6 +107,13 @@ The destination is always canonical Base USDC
|
|
|
107
107
|
discovered and quoted by `@relayprotocol/relay-sdk`, not a static token
|
|
108
108
|
allowlist.
|
|
109
109
|
|
|
110
|
+
Routes that submit more than one source-chain transaction (approve, then
|
|
111
|
+
route) require a nonce-managed source signer -
|
|
112
|
+
`privateKeyToAccount(pk, { nonceManager })` from viem. Without one the SDK
|
|
113
|
+
refuses the route preflight with `SOURCE_NONCE_MANAGER_REQUIRED` instead of
|
|
114
|
+
letting the route transaction reuse the approval's nonce and revert
|
|
115
|
+
mid-route. Browser wallets are unaffected.
|
|
116
|
+
|
|
110
117
|
`capabilities()` tells you which platforms need a verified identity for a new
|
|
111
118
|
payee registration (`requiresIdentityAttestation` - Wise and PayPal today).
|
|
112
119
|
An already-registered Wise or PayPal handle can be reused with bare payee data.
|
|
@@ -120,6 +127,10 @@ they are available. A source-routed result includes both a flat
|
|
|
120
127
|
`source.txHashes` list and chain-aware `source.transactions.origin` /
|
|
121
128
|
`.destination` entries.
|
|
122
129
|
|
|
130
|
+
- `SOURCE_EXECUTION_FAILED` where only the approval landed: the Relay request
|
|
131
|
+
can stay in `relayStatus` `waiting` indefinitely. Decide from the error's
|
|
132
|
+
recovery payload and origin transactions, never by waiting for a terminal
|
|
133
|
+
Relay status.
|
|
123
134
|
- `SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED`: Relay completed, but the Base
|
|
124
135
|
cashout was not created. Do not route again. Retry a Base-USDC-only
|
|
125
136
|
`cashout()` with `BigInt(error.recovery.amount)`.
|
|
@@ -189,6 +189,12 @@ var errors = {
|
|
|
189
189
|
},
|
|
190
190
|
{ cause }
|
|
191
191
|
),
|
|
192
|
+
sourceNonceManagerRequired: (transactionCount) => new CashError({
|
|
193
|
+
code: "SOURCE_NONCE_MANAGER_REQUIRED",
|
|
194
|
+
message: `This Relay route submits ${transactionCount} source-chain transactions, but the local signer has no nonce manager; the route transaction would reuse the approval nonce and revert.`,
|
|
195
|
+
retryable: false,
|
|
196
|
+
remediation: `Create the source signer with viem's nonce manager - privateKeyToAccount(pk, { nonceManager }) - then request a fresh quote and retry. No transaction was submitted.`
|
|
197
|
+
}),
|
|
192
198
|
sourceExecutionFailed: (cause, evidence) => new CashError(
|
|
193
199
|
{
|
|
194
200
|
code: "SOURCE_EXECUTION_FAILED",
|
package/dist/index.cjs
CHANGED
|
@@ -623,6 +623,12 @@ var errors = {
|
|
|
623
623
|
},
|
|
624
624
|
{ cause }
|
|
625
625
|
),
|
|
626
|
+
sourceNonceManagerRequired: (transactionCount) => new CashError({
|
|
627
|
+
code: "SOURCE_NONCE_MANAGER_REQUIRED",
|
|
628
|
+
message: `This Relay route submits ${transactionCount} source-chain transactions, but the local signer has no nonce manager; the route transaction would reuse the approval nonce and revert.`,
|
|
629
|
+
retryable: false,
|
|
630
|
+
remediation: `Create the source signer with viem's nonce manager - privateKeyToAccount(pk, { nonceManager }) - then request a fresh quote and retry. No transaction was submitted.`
|
|
631
|
+
}),
|
|
626
632
|
sourceExecutionFailed: (cause, evidence) => new CashError(
|
|
627
633
|
{
|
|
628
634
|
code: "SOURCE_EXECUTION_FAILED",
|
|
@@ -1048,6 +1054,14 @@ async function assertRelayExecutionIdentity(quote, wallet, expectedRecipient) {
|
|
|
1048
1054
|
throw new Error("Relay quote recipient does not match the expected Base recipient");
|
|
1049
1055
|
}
|
|
1050
1056
|
}
|
|
1057
|
+
function assertRelayNonceManagement(quote, wallet) {
|
|
1058
|
+
const account = wallet.account;
|
|
1059
|
+
if (!account || account.type !== "local" || account.nonceManager !== void 0) return;
|
|
1060
|
+
const transactionCount = quote.steps.flatMap(
|
|
1061
|
+
(step) => step.items.filter((item) => asString(asRecord(item.data).to) !== void 0)
|
|
1062
|
+
).length;
|
|
1063
|
+
if (transactionCount > 1) throw errors.sourceNonceManagerRequired(transactionCount);
|
|
1064
|
+
}
|
|
1051
1065
|
function isRelaySecretKey(key) {
|
|
1052
1066
|
const normalized = key.toLowerCase();
|
|
1053
1067
|
return normalized === "headers" || normalized === "apikey";
|
|
@@ -1249,6 +1263,7 @@ async function executeRelayQuote(quote, wallet, options = {}) {
|
|
|
1249
1263
|
observedRequestId = quoteRequestId(rawQuote);
|
|
1250
1264
|
assertCanonicalRelayDestination(rawQuote);
|
|
1251
1265
|
await assertRelayExecutionIdentity(rawQuote, wallet, options.recipient);
|
|
1266
|
+
assertRelayNonceManagement(rawQuote, wallet);
|
|
1252
1267
|
const client = relayClient(options.relay);
|
|
1253
1268
|
const sourceChainId = quoteSourceChainId(rawQuote);
|
|
1254
1269
|
if (sourceChainId !== void 0 && !(client.chains ?? []).some((chain) => chain.id === sourceChainId)) {
|
|
@@ -2559,6 +2574,7 @@ var CASH_ERROR_CODES = defineCashErrorCodes([
|
|
|
2559
2574
|
"SOURCE_RECIPIENT_MISMATCH",
|
|
2560
2575
|
"SOURCE_CAPABILITIES_FAILED",
|
|
2561
2576
|
"SOURCE_QUOTE_FAILED",
|
|
2577
|
+
"SOURCE_NONCE_MANAGER_REQUIRED",
|
|
2562
2578
|
"SOURCE_EXECUTION_FAILED",
|
|
2563
2579
|
"SOURCE_STATUS_FAILED",
|
|
2564
2580
|
"SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED",
|
package/dist/index.d.cts
CHANGED
|
@@ -10,7 +10,7 @@ import '@relayprotocol/relay-sdk';
|
|
|
10
10
|
* Typed errors - every failure carries a `code`, whether it is `retryable`,
|
|
11
11
|
* and a `remediation` sentence so agents can self-drive recovery.
|
|
12
12
|
*/
|
|
13
|
-
type CashErrorCode = 'ORACLE_UNSUPPORTED_CURRENCY' | 'ORACLE_READ_FAILED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_PLATFORM_CURRENCY' | 'AMOUNT_BELOW_MINIMUM' | 'INVALID_INTENT_AMOUNT_RANGE' | 'ACTIVE_INTENT_BLOCKS_WITHDRAWAL' | 'NOTHING_TO_WITHDRAW' | 'INSUFFICIENT_AVAILABLE_FUNDS' | 'INSUFFICIENT_TOKEN_BALANCE' | 'ORDER_NOT_ACTIVE' | 'INVALID_DEPOSIT_ID' | 'ESCROW_PAUSED' | 'INDEXER_LAG' | 'INDEXER_UNAVAILABLE' | 'ORDER_NOT_FOUND' | 'PAYEE_REGISTRATION_FAILED' | 'PAYEE_VERIFICATION_REQUIRED' | 'SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE' | 'SOURCE_RECIPIENT_MISMATCH' | 'SOURCE_CAPABILITIES_FAILED' | 'SOURCE_QUOTE_FAILED' | 'SOURCE_EXECUTION_FAILED' | 'SOURCE_STATUS_FAILED' | 'SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED' | 'SOURCE_CASHOUT_SUBMISSION_UNKNOWN' | 'SOURCE_CASHOUT_STATUS_UNKNOWN' | 'DEPOSIT_RESOLUTION_FAILED' | 'ALLOWANCE_NOT_VISIBLE' | 'SIGNER_REQUIRED' | 'SIGNER_CHAIN_MISMATCH' | 'SIGNER_CHAIN_UNAVAILABLE' | 'WATCH_TIMEOUT' | 'TRANSACTION_FAILED' | 'TRANSACTION_SUBMISSION_UNKNOWN' | 'TRANSACTION_STATUS_UNKNOWN';
|
|
13
|
+
type CashErrorCode = 'ORACLE_UNSUPPORTED_CURRENCY' | 'ORACLE_READ_FAILED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_PLATFORM_CURRENCY' | 'AMOUNT_BELOW_MINIMUM' | 'INVALID_INTENT_AMOUNT_RANGE' | 'ACTIVE_INTENT_BLOCKS_WITHDRAWAL' | 'NOTHING_TO_WITHDRAW' | 'INSUFFICIENT_AVAILABLE_FUNDS' | 'INSUFFICIENT_TOKEN_BALANCE' | 'ORDER_NOT_ACTIVE' | 'INVALID_DEPOSIT_ID' | 'ESCROW_PAUSED' | 'INDEXER_LAG' | 'INDEXER_UNAVAILABLE' | 'ORDER_NOT_FOUND' | 'PAYEE_REGISTRATION_FAILED' | 'PAYEE_VERIFICATION_REQUIRED' | 'SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE' | 'SOURCE_RECIPIENT_MISMATCH' | 'SOURCE_CAPABILITIES_FAILED' | 'SOURCE_QUOTE_FAILED' | 'SOURCE_NONCE_MANAGER_REQUIRED' | 'SOURCE_EXECUTION_FAILED' | 'SOURCE_STATUS_FAILED' | 'SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED' | 'SOURCE_CASHOUT_SUBMISSION_UNKNOWN' | 'SOURCE_CASHOUT_STATUS_UNKNOWN' | 'DEPOSIT_RESOLUTION_FAILED' | 'ALLOWANCE_NOT_VISIBLE' | 'SIGNER_REQUIRED' | 'SIGNER_CHAIN_MISMATCH' | 'SIGNER_CHAIN_UNAVAILABLE' | 'WATCH_TIMEOUT' | 'TRANSACTION_FAILED' | 'TRANSACTION_SUBMISSION_UNKNOWN' | 'TRANSACTION_STATUS_UNKNOWN';
|
|
14
14
|
interface CashErrorShape {
|
|
15
15
|
code: CashErrorCode;
|
|
16
16
|
message: string;
|
|
@@ -92,6 +92,7 @@ declare const errors: {
|
|
|
92
92
|
sourceRecipientMismatch: (recipient: string, owner: string) => CashError;
|
|
93
93
|
sourceCapabilitiesFailed: (cause?: unknown) => CashError;
|
|
94
94
|
sourceQuoteFailed: (cause?: unknown) => CashError;
|
|
95
|
+
sourceNonceManagerRequired: (transactionCount: number) => CashError;
|
|
95
96
|
sourceExecutionFailed: (cause?: unknown, evidence?: {
|
|
96
97
|
requestId?: string;
|
|
97
98
|
txHashes: string[];
|
|
@@ -3153,7 +3154,7 @@ declare const cashErrorRecoveryJsonSchema: z.ZodDiscriminatedUnion<"kind", [z.Zo
|
|
|
3153
3154
|
operation: string;
|
|
3154
3155
|
}>]>;
|
|
3155
3156
|
declare const cashErrorJsonSchema: z.ZodObject<{
|
|
3156
|
-
code: z.ZodEnum<["ORACLE_UNSUPPORTED_CURRENCY", "ORACLE_READ_FAILED", "UNSUPPORTED_PLATFORM", "UNSUPPORTED_PLATFORM_CURRENCY", "AMOUNT_BELOW_MINIMUM", "INVALID_INTENT_AMOUNT_RANGE", "ACTIVE_INTENT_BLOCKS_WITHDRAWAL", "NOTHING_TO_WITHDRAW", "INSUFFICIENT_AVAILABLE_FUNDS", "INSUFFICIENT_TOKEN_BALANCE", "ORDER_NOT_ACTIVE", "INVALID_DEPOSIT_ID", "ESCROW_PAUSED", "INDEXER_LAG", "INDEXER_UNAVAILABLE", "ORDER_NOT_FOUND", "PAYEE_REGISTRATION_FAILED", "PAYEE_VERIFICATION_REQUIRED", "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE", "SOURCE_RECIPIENT_MISMATCH", "SOURCE_CAPABILITIES_FAILED", "SOURCE_QUOTE_FAILED", "SOURCE_EXECUTION_FAILED", "SOURCE_STATUS_FAILED", "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED", "SOURCE_CASHOUT_SUBMISSION_UNKNOWN", "SOURCE_CASHOUT_STATUS_UNKNOWN", "DEPOSIT_RESOLUTION_FAILED", "ALLOWANCE_NOT_VISIBLE", "SIGNER_REQUIRED", "SIGNER_CHAIN_MISMATCH", "SIGNER_CHAIN_UNAVAILABLE", "WATCH_TIMEOUT", "TRANSACTION_FAILED", "TRANSACTION_SUBMISSION_UNKNOWN", "TRANSACTION_STATUS_UNKNOWN"]>;
|
|
3157
|
+
code: z.ZodEnum<["ORACLE_UNSUPPORTED_CURRENCY", "ORACLE_READ_FAILED", "UNSUPPORTED_PLATFORM", "UNSUPPORTED_PLATFORM_CURRENCY", "AMOUNT_BELOW_MINIMUM", "INVALID_INTENT_AMOUNT_RANGE", "ACTIVE_INTENT_BLOCKS_WITHDRAWAL", "NOTHING_TO_WITHDRAW", "INSUFFICIENT_AVAILABLE_FUNDS", "INSUFFICIENT_TOKEN_BALANCE", "ORDER_NOT_ACTIVE", "INVALID_DEPOSIT_ID", "ESCROW_PAUSED", "INDEXER_LAG", "INDEXER_UNAVAILABLE", "ORDER_NOT_FOUND", "PAYEE_REGISTRATION_FAILED", "PAYEE_VERIFICATION_REQUIRED", "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE", "SOURCE_RECIPIENT_MISMATCH", "SOURCE_CAPABILITIES_FAILED", "SOURCE_QUOTE_FAILED", "SOURCE_NONCE_MANAGER_REQUIRED", "SOURCE_EXECUTION_FAILED", "SOURCE_STATUS_FAILED", "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED", "SOURCE_CASHOUT_SUBMISSION_UNKNOWN", "SOURCE_CASHOUT_STATUS_UNKNOWN", "DEPOSIT_RESOLUTION_FAILED", "ALLOWANCE_NOT_VISIBLE", "SIGNER_REQUIRED", "SIGNER_CHAIN_MISMATCH", "SIGNER_CHAIN_UNAVAILABLE", "WATCH_TIMEOUT", "TRANSACTION_FAILED", "TRANSACTION_SUBMISSION_UNKNOWN", "TRANSACTION_STATUS_UNKNOWN"]>;
|
|
3157
3158
|
message: z.ZodString;
|
|
3158
3159
|
retryable: z.ZodBoolean;
|
|
3159
3160
|
remediation: z.ZodString;
|
|
@@ -3540,7 +3541,7 @@ declare const cashErrorJsonSchema: z.ZodObject<{
|
|
|
3540
3541
|
}>]>>;
|
|
3541
3542
|
}, "strict", z.ZodTypeAny, {
|
|
3542
3543
|
message: string;
|
|
3543
|
-
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3544
|
+
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_NONCE_MANAGER_REQUIRED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3544
3545
|
retryable: boolean;
|
|
3545
3546
|
remediation: string;
|
|
3546
3547
|
recovery?: {
|
|
@@ -3622,7 +3623,7 @@ declare const cashErrorJsonSchema: z.ZodObject<{
|
|
|
3622
3623
|
} | undefined;
|
|
3623
3624
|
}, {
|
|
3624
3625
|
message: string;
|
|
3625
|
-
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3626
|
+
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_NONCE_MANAGER_REQUIRED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3626
3627
|
retryable: boolean;
|
|
3627
3628
|
remediation: string;
|
|
3628
3629
|
recovery?: {
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import '@relayprotocol/relay-sdk';
|
|
|
10
10
|
* Typed errors - every failure carries a `code`, whether it is `retryable`,
|
|
11
11
|
* and a `remediation` sentence so agents can self-drive recovery.
|
|
12
12
|
*/
|
|
13
|
-
type CashErrorCode = 'ORACLE_UNSUPPORTED_CURRENCY' | 'ORACLE_READ_FAILED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_PLATFORM_CURRENCY' | 'AMOUNT_BELOW_MINIMUM' | 'INVALID_INTENT_AMOUNT_RANGE' | 'ACTIVE_INTENT_BLOCKS_WITHDRAWAL' | 'NOTHING_TO_WITHDRAW' | 'INSUFFICIENT_AVAILABLE_FUNDS' | 'INSUFFICIENT_TOKEN_BALANCE' | 'ORDER_NOT_ACTIVE' | 'INVALID_DEPOSIT_ID' | 'ESCROW_PAUSED' | 'INDEXER_LAG' | 'INDEXER_UNAVAILABLE' | 'ORDER_NOT_FOUND' | 'PAYEE_REGISTRATION_FAILED' | 'PAYEE_VERIFICATION_REQUIRED' | 'SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE' | 'SOURCE_RECIPIENT_MISMATCH' | 'SOURCE_CAPABILITIES_FAILED' | 'SOURCE_QUOTE_FAILED' | 'SOURCE_EXECUTION_FAILED' | 'SOURCE_STATUS_FAILED' | 'SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED' | 'SOURCE_CASHOUT_SUBMISSION_UNKNOWN' | 'SOURCE_CASHOUT_STATUS_UNKNOWN' | 'DEPOSIT_RESOLUTION_FAILED' | 'ALLOWANCE_NOT_VISIBLE' | 'SIGNER_REQUIRED' | 'SIGNER_CHAIN_MISMATCH' | 'SIGNER_CHAIN_UNAVAILABLE' | 'WATCH_TIMEOUT' | 'TRANSACTION_FAILED' | 'TRANSACTION_SUBMISSION_UNKNOWN' | 'TRANSACTION_STATUS_UNKNOWN';
|
|
13
|
+
type CashErrorCode = 'ORACLE_UNSUPPORTED_CURRENCY' | 'ORACLE_READ_FAILED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_PLATFORM_CURRENCY' | 'AMOUNT_BELOW_MINIMUM' | 'INVALID_INTENT_AMOUNT_RANGE' | 'ACTIVE_INTENT_BLOCKS_WITHDRAWAL' | 'NOTHING_TO_WITHDRAW' | 'INSUFFICIENT_AVAILABLE_FUNDS' | 'INSUFFICIENT_TOKEN_BALANCE' | 'ORDER_NOT_ACTIVE' | 'INVALID_DEPOSIT_ID' | 'ESCROW_PAUSED' | 'INDEXER_LAG' | 'INDEXER_UNAVAILABLE' | 'ORDER_NOT_FOUND' | 'PAYEE_REGISTRATION_FAILED' | 'PAYEE_VERIFICATION_REQUIRED' | 'SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE' | 'SOURCE_RECIPIENT_MISMATCH' | 'SOURCE_CAPABILITIES_FAILED' | 'SOURCE_QUOTE_FAILED' | 'SOURCE_NONCE_MANAGER_REQUIRED' | 'SOURCE_EXECUTION_FAILED' | 'SOURCE_STATUS_FAILED' | 'SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED' | 'SOURCE_CASHOUT_SUBMISSION_UNKNOWN' | 'SOURCE_CASHOUT_STATUS_UNKNOWN' | 'DEPOSIT_RESOLUTION_FAILED' | 'ALLOWANCE_NOT_VISIBLE' | 'SIGNER_REQUIRED' | 'SIGNER_CHAIN_MISMATCH' | 'SIGNER_CHAIN_UNAVAILABLE' | 'WATCH_TIMEOUT' | 'TRANSACTION_FAILED' | 'TRANSACTION_SUBMISSION_UNKNOWN' | 'TRANSACTION_STATUS_UNKNOWN';
|
|
14
14
|
interface CashErrorShape {
|
|
15
15
|
code: CashErrorCode;
|
|
16
16
|
message: string;
|
|
@@ -92,6 +92,7 @@ declare const errors: {
|
|
|
92
92
|
sourceRecipientMismatch: (recipient: string, owner: string) => CashError;
|
|
93
93
|
sourceCapabilitiesFailed: (cause?: unknown) => CashError;
|
|
94
94
|
sourceQuoteFailed: (cause?: unknown) => CashError;
|
|
95
|
+
sourceNonceManagerRequired: (transactionCount: number) => CashError;
|
|
95
96
|
sourceExecutionFailed: (cause?: unknown, evidence?: {
|
|
96
97
|
requestId?: string;
|
|
97
98
|
txHashes: string[];
|
|
@@ -3153,7 +3154,7 @@ declare const cashErrorRecoveryJsonSchema: z.ZodDiscriminatedUnion<"kind", [z.Zo
|
|
|
3153
3154
|
operation: string;
|
|
3154
3155
|
}>]>;
|
|
3155
3156
|
declare const cashErrorJsonSchema: z.ZodObject<{
|
|
3156
|
-
code: z.ZodEnum<["ORACLE_UNSUPPORTED_CURRENCY", "ORACLE_READ_FAILED", "UNSUPPORTED_PLATFORM", "UNSUPPORTED_PLATFORM_CURRENCY", "AMOUNT_BELOW_MINIMUM", "INVALID_INTENT_AMOUNT_RANGE", "ACTIVE_INTENT_BLOCKS_WITHDRAWAL", "NOTHING_TO_WITHDRAW", "INSUFFICIENT_AVAILABLE_FUNDS", "INSUFFICIENT_TOKEN_BALANCE", "ORDER_NOT_ACTIVE", "INVALID_DEPOSIT_ID", "ESCROW_PAUSED", "INDEXER_LAG", "INDEXER_UNAVAILABLE", "ORDER_NOT_FOUND", "PAYEE_REGISTRATION_FAILED", "PAYEE_VERIFICATION_REQUIRED", "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE", "SOURCE_RECIPIENT_MISMATCH", "SOURCE_CAPABILITIES_FAILED", "SOURCE_QUOTE_FAILED", "SOURCE_EXECUTION_FAILED", "SOURCE_STATUS_FAILED", "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED", "SOURCE_CASHOUT_SUBMISSION_UNKNOWN", "SOURCE_CASHOUT_STATUS_UNKNOWN", "DEPOSIT_RESOLUTION_FAILED", "ALLOWANCE_NOT_VISIBLE", "SIGNER_REQUIRED", "SIGNER_CHAIN_MISMATCH", "SIGNER_CHAIN_UNAVAILABLE", "WATCH_TIMEOUT", "TRANSACTION_FAILED", "TRANSACTION_SUBMISSION_UNKNOWN", "TRANSACTION_STATUS_UNKNOWN"]>;
|
|
3157
|
+
code: z.ZodEnum<["ORACLE_UNSUPPORTED_CURRENCY", "ORACLE_READ_FAILED", "UNSUPPORTED_PLATFORM", "UNSUPPORTED_PLATFORM_CURRENCY", "AMOUNT_BELOW_MINIMUM", "INVALID_INTENT_AMOUNT_RANGE", "ACTIVE_INTENT_BLOCKS_WITHDRAWAL", "NOTHING_TO_WITHDRAW", "INSUFFICIENT_AVAILABLE_FUNDS", "INSUFFICIENT_TOKEN_BALANCE", "ORDER_NOT_ACTIVE", "INVALID_DEPOSIT_ID", "ESCROW_PAUSED", "INDEXER_LAG", "INDEXER_UNAVAILABLE", "ORDER_NOT_FOUND", "PAYEE_REGISTRATION_FAILED", "PAYEE_VERIFICATION_REQUIRED", "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE", "SOURCE_RECIPIENT_MISMATCH", "SOURCE_CAPABILITIES_FAILED", "SOURCE_QUOTE_FAILED", "SOURCE_NONCE_MANAGER_REQUIRED", "SOURCE_EXECUTION_FAILED", "SOURCE_STATUS_FAILED", "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED", "SOURCE_CASHOUT_SUBMISSION_UNKNOWN", "SOURCE_CASHOUT_STATUS_UNKNOWN", "DEPOSIT_RESOLUTION_FAILED", "ALLOWANCE_NOT_VISIBLE", "SIGNER_REQUIRED", "SIGNER_CHAIN_MISMATCH", "SIGNER_CHAIN_UNAVAILABLE", "WATCH_TIMEOUT", "TRANSACTION_FAILED", "TRANSACTION_SUBMISSION_UNKNOWN", "TRANSACTION_STATUS_UNKNOWN"]>;
|
|
3157
3158
|
message: z.ZodString;
|
|
3158
3159
|
retryable: z.ZodBoolean;
|
|
3159
3160
|
remediation: z.ZodString;
|
|
@@ -3540,7 +3541,7 @@ declare const cashErrorJsonSchema: z.ZodObject<{
|
|
|
3540
3541
|
}>]>>;
|
|
3541
3542
|
}, "strict", z.ZodTypeAny, {
|
|
3542
3543
|
message: string;
|
|
3543
|
-
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3544
|
+
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_NONCE_MANAGER_REQUIRED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3544
3545
|
retryable: boolean;
|
|
3545
3546
|
remediation: string;
|
|
3546
3547
|
recovery?: {
|
|
@@ -3622,7 +3623,7 @@ declare const cashErrorJsonSchema: z.ZodObject<{
|
|
|
3622
3623
|
} | undefined;
|
|
3623
3624
|
}, {
|
|
3624
3625
|
message: string;
|
|
3625
|
-
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3626
|
+
code: "ORACLE_UNSUPPORTED_CURRENCY" | "ORACLE_READ_FAILED" | "UNSUPPORTED_PLATFORM" | "UNSUPPORTED_PLATFORM_CURRENCY" | "AMOUNT_BELOW_MINIMUM" | "INVALID_INTENT_AMOUNT_RANGE" | "ACTIVE_INTENT_BLOCKS_WITHDRAWAL" | "NOTHING_TO_WITHDRAW" | "INSUFFICIENT_AVAILABLE_FUNDS" | "INSUFFICIENT_TOKEN_BALANCE" | "ORDER_NOT_ACTIVE" | "INVALID_DEPOSIT_ID" | "ESCROW_PAUSED" | "INDEXER_LAG" | "INDEXER_UNAVAILABLE" | "ORDER_NOT_FOUND" | "PAYEE_REGISTRATION_FAILED" | "PAYEE_VERIFICATION_REQUIRED" | "SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE" | "SOURCE_RECIPIENT_MISMATCH" | "SOURCE_CAPABILITIES_FAILED" | "SOURCE_QUOTE_FAILED" | "SOURCE_NONCE_MANAGER_REQUIRED" | "SOURCE_EXECUTION_FAILED" | "SOURCE_STATUS_FAILED" | "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED" | "SOURCE_CASHOUT_SUBMISSION_UNKNOWN" | "SOURCE_CASHOUT_STATUS_UNKNOWN" | "DEPOSIT_RESOLUTION_FAILED" | "ALLOWANCE_NOT_VISIBLE" | "SIGNER_REQUIRED" | "SIGNER_CHAIN_MISMATCH" | "SIGNER_CHAIN_UNAVAILABLE" | "WATCH_TIMEOUT" | "TRANSACTION_FAILED" | "TRANSACTION_SUBMISSION_UNKNOWN" | "TRANSACTION_STATUS_UNKNOWN";
|
|
3626
3627
|
retryable: boolean;
|
|
3627
3628
|
remediation: string;
|
|
3628
3629
|
recovery?: {
|
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, errors, isCashError, CASH_ORDER_STATUSES, mapChainError, CashError } from './chunk-
|
|
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 } 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 } from './chunk-TR6JVYYF.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 } from './chunk-TR6JVYYF.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';
|
|
@@ -675,6 +675,14 @@ async function assertRelayExecutionIdentity(quote, wallet, expectedRecipient) {
|
|
|
675
675
|
throw new Error("Relay quote recipient does not match the expected Base recipient");
|
|
676
676
|
}
|
|
677
677
|
}
|
|
678
|
+
function assertRelayNonceManagement(quote, wallet) {
|
|
679
|
+
const account = wallet.account;
|
|
680
|
+
if (!account || account.type !== "local" || account.nonceManager !== void 0) return;
|
|
681
|
+
const transactionCount = quote.steps.flatMap(
|
|
682
|
+
(step) => step.items.filter((item) => asString(asRecord(item.data).to) !== void 0)
|
|
683
|
+
).length;
|
|
684
|
+
if (transactionCount > 1) throw errors.sourceNonceManagerRequired(transactionCount);
|
|
685
|
+
}
|
|
678
686
|
function isRelaySecretKey(key) {
|
|
679
687
|
const normalized = key.toLowerCase();
|
|
680
688
|
return normalized === "headers" || normalized === "apikey";
|
|
@@ -876,6 +884,7 @@ async function executeRelayQuote(quote, wallet, options = {}) {
|
|
|
876
884
|
observedRequestId = quoteRequestId(rawQuote);
|
|
877
885
|
assertCanonicalRelayDestination(rawQuote);
|
|
878
886
|
await assertRelayExecutionIdentity(rawQuote, wallet, options.recipient);
|
|
887
|
+
assertRelayNonceManagement(rawQuote, wallet);
|
|
879
888
|
const client = relayClient(options.relay);
|
|
880
889
|
const sourceChainId = quoteSourceChainId(rawQuote);
|
|
881
890
|
if (sourceChainId !== void 0 && !(client.chains ?? []).some((chain) => chain.id === sourceChainId)) {
|
|
@@ -2186,6 +2195,7 @@ var CASH_ERROR_CODES = defineCashErrorCodes([
|
|
|
2186
2195
|
"SOURCE_RECIPIENT_MISMATCH",
|
|
2187
2196
|
"SOURCE_CAPABILITIES_FAILED",
|
|
2188
2197
|
"SOURCE_QUOTE_FAILED",
|
|
2198
|
+
"SOURCE_NONCE_MANAGER_REQUIRED",
|
|
2189
2199
|
"SOURCE_EXECUTION_FAILED",
|
|
2190
2200
|
"SOURCE_STATUS_FAILED",
|
|
2191
2201
|
"SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED",
|
package/dist/react.js
CHANGED
package/dist/tools.cjs
CHANGED
package/dist/tools.js
CHANGED
|
@@ -36,6 +36,16 @@ For any other EVM source asset, Peer Cash uses `@relayprotocol/relay-sdk`:
|
|
|
36
36
|
`executeSourceQuote()` remains available for apps that want a separate
|
|
37
37
|
bridge step.
|
|
38
38
|
|
|
39
|
+
Routes that need more than one source-chain transaction (an ERC-20 `approve`,
|
|
40
|
+
then the route transaction) are submitted back-to-back by the Relay SDK. On a
|
|
41
|
+
plain local account the route transaction reuses the approval's nonce and
|
|
42
|
+
reverts mid-route, so `executeSourceQuote()` and `cashout({ source })` refuse
|
|
43
|
+
multi-transaction routes up front with `SOURCE_NONCE_MANAGER_REQUIRED` unless
|
|
44
|
+
the source signer carries a viem nonce manager:
|
|
45
|
+
`privateKeyToAccount(pk, { nonceManager })`. The check fires before anything
|
|
46
|
+
is submitted. Browser (`json-rpc`) wallets are unaffected - the node
|
|
47
|
+
allocates their nonces.
|
|
48
|
+
|
|
39
49
|
Cash-out interfaces should use `tradeType: 'EXACT_INPUT'` (also the default),
|
|
40
50
|
so `amount` always means source-token base units. A `RelayQuote.outputAmount`
|
|
41
51
|
is the guaranteed minimum Base USDC output. The same value becomes
|
|
@@ -62,10 +72,16 @@ destination constant.
|
|
|
62
72
|
|
|
63
73
|
Do not retry a source route merely because the Base cashout did not finish:
|
|
64
74
|
|
|
75
|
+
- `SOURCE_NONCE_MANAGER_REQUIRED` is preflight: nothing was submitted.
|
|
76
|
+
Recreate the source signer with viem's nonce manager and execute a fresh
|
|
77
|
+
quote.
|
|
65
78
|
- `SOURCE_EXECUTION_FAILED` means Relay execution did not report success. Check
|
|
66
79
|
its `inspect-relay-route` recovery evidence, submitted wallet transactions,
|
|
67
80
|
and `relayStatus(requestId)` before taking another action; a blind retry can
|
|
68
|
-
route twice.
|
|
81
|
+
route twice. A failed route whose only landed transaction is the approval
|
|
82
|
+
can sit in `relayStatus` `waiting` indefinitely - it never becomes terminal,
|
|
83
|
+
so decide from the persisted recovery payload and the origin transactions,
|
|
84
|
+
not from Relay reaching a final status.
|
|
69
85
|
- `SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED` means Relay completed, but the Base
|
|
70
86
|
cashout was not created. Its recovery payload has
|
|
71
87
|
`kind: 'retry-base-usdc-cashout'`, the guaranteed Base USDC `amount`, Relay
|
|
@@ -132,7 +148,9 @@ UI built on this SDK is a bug in that UI.
|
|
|
132
148
|
- **Partial withdrawal** - `withdraw(depositId, { amount })` pulls part of
|
|
133
149
|
the _unlocked_ balance back out. A live buyer intent does not block it
|
|
134
150
|
(their locked portion is untouched); asking for more than the unlocked
|
|
135
|
-
balance fails with `INSUFFICIENT_AVAILABLE_FUNDS`.
|
|
151
|
+
balance fails with `INSUFFICIENT_AVAILABLE_FUNDS`. Accounting note: a
|
|
152
|
+
partial withdrawal increments `returnedAmount`; `totalAmount` records
|
|
153
|
+
everything the order has ever held and does not shrink.
|
|
136
154
|
- There is no retain-on-empty or rate knob to manage - a cash order cleans
|
|
137
155
|
itself up when fully filled, and the market rate is not configurable.
|
|
138
156
|
|
|
@@ -252,6 +270,7 @@ explicit override.
|
|
|
252
270
|
| `SOURCE_RECIPIENT_MISMATCH` | no | Relay output recipient differs from the cashout depositor. Use the depositor address. |
|
|
253
271
|
| `SOURCE_CAPABILITIES_FAILED` | yes | Relay source discovery failed. Retry or use Base USDC. |
|
|
254
272
|
| `SOURCE_QUOTE_FAILED` | yes | Relay returned no valid canonical Base-USDC route. Refresh capabilities and quote again. |
|
|
273
|
+
| `SOURCE_NONCE_MANAGER_REQUIRED` | no | Preflight; nothing was submitted. Recreate the source signer with viem's `nonceManager` and execute a fresh quote. |
|
|
255
274
|
| `SOURCE_EXECUTION_FAILED` | no | Route execution did not report success. Inspect source transactions and Relay status before retrying. |
|
|
256
275
|
| `SOURCE_STATUS_FAILED` | yes | Relay status is temporarily unavailable. Retry the status read without resubmitting. |
|
|
257
276
|
| `SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED` | no | Relay completed but no Base cashout was created. Use the recovery amount for a Base-USDC-only retry; never repeat Relay. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkp2p/cash",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
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)",
|