@zkp2p/cash 0.1.3 → 0.1.4
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 +89 -26
- package/README.md +66 -24
- package/dist/chunk-P3KYZ2FX.js +373 -0
- package/dist/{createCashClient-iHuGgjH_.d.cts → createCashClient-BbkfxILl.d.cts} +37 -8
- package/dist/{createCashClient-iHuGgjH_.d.ts → createCashClient-BbkfxILl.d.ts} +37 -8
- package/dist/index.cjs +1081 -245
- package/dist/index.d.cts +1554 -74
- package/dist/index.d.ts +1554 -74
- package/dist/index.js +868 -239
- package/dist/react.cjs +239 -59
- package/dist/react.d.cts +6 -4
- package/dist/react.d.ts +6 -4
- package/dist/react.js +236 -59
- package/dist/tools.cjs +36 -36
- package/dist/tools.d.cts +282 -3
- package/dist/tools.d.ts +282 -3
- package/dist/tools.js +36 -36
- package/docs/lifecycle-and-recovery.md +278 -0
- package/examples/agent-tool-use.ts +122 -0
- package/examples/node-cashout.ts +79 -0
- package/llms.txt +23 -5
- package/package.json +51 -21
- package/skills/peer-cash-integration/SKILL.md +79 -17
- package/dist/chunk-FKVPZVFH.js +0 -188
- package/dist/chunk-FKVPZVFH.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/react.cjs.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/tools.cjs.map +0 -1
- package/dist/tools.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -237,10 +237,12 @@ function deriveCashOrder(depositId, intents, options = {}) {
|
|
|
237
237
|
const total = options.totalAmount ?? remaining + outstanding + taken + withdrawn;
|
|
238
238
|
const status = options.status;
|
|
239
239
|
const isTerminal = status === "CLOSED" || status === "WITHDRAWN";
|
|
240
|
-
const hasLiveFunds = remaining
|
|
240
|
+
const hasLiveFunds = remaining >= DUST_THRESHOLD || outstanding > 0n;
|
|
241
241
|
let state;
|
|
242
242
|
if (outstanding > 0n) {
|
|
243
243
|
state = taken > 0n ? "delivering" : "matched";
|
|
244
|
+
} else if (!hasLiveFunds && withdrawn > 0n) {
|
|
245
|
+
state = "returned";
|
|
244
246
|
} else if (taken > 0n && !hasLiveFunds) {
|
|
245
247
|
state = "delivered";
|
|
246
248
|
} else if (taken > 0n && hasLiveFunds) {
|
|
@@ -282,7 +284,7 @@ function deriveCashOrder(depositId, intents, options = {}) {
|
|
|
282
284
|
...options.payouts !== void 0 ? { payouts: options.payouts } : {},
|
|
283
285
|
...options.successRateBps !== void 0 ? { successRateBps: options.successRateBps } : {},
|
|
284
286
|
isInFlight,
|
|
285
|
-
withdrawn:
|
|
287
|
+
withdrawn: state === "returned" && withdrawn > 0n
|
|
286
288
|
});
|
|
287
289
|
}
|
|
288
290
|
var ORACLE_KINDS = /* @__PURE__ */ new Set(["oracle_chainlink", "oracle_pyth"]);
|
|
@@ -392,12 +394,14 @@ function resolveCashDepositId(params) {
|
|
|
392
394
|
}
|
|
393
395
|
function parseCompositeDepositId(compositeId) {
|
|
394
396
|
const idx = compositeId.lastIndexOf("_");
|
|
395
|
-
if (idx === -1) {
|
|
396
|
-
return { escrowAddress: "", onchainDepositId: BigInt(compositeId) };
|
|
397
|
-
}
|
|
398
397
|
const escrowAddress = compositeId.slice(0, idx);
|
|
399
|
-
const
|
|
400
|
-
|
|
398
|
+
const rawDepositId = compositeId.slice(idx + 1);
|
|
399
|
+
if (idx <= 0 || compositeId.indexOf("_") !== idx || !viem.isAddress(escrowAddress, { strict: false }) || !/^\d+$/.test(rawDepositId)) {
|
|
400
|
+
throw new Error(`Invalid deposit id: '${compositeId}'`);
|
|
401
|
+
}
|
|
402
|
+
const canonicalEscrowAddress = escrowAddress.toLowerCase();
|
|
403
|
+
const onchainDepositId = BigInt(rawDepositId);
|
|
404
|
+
return { escrowAddress: canonicalEscrowAddress, onchainDepositId };
|
|
401
405
|
}
|
|
402
406
|
var MIN_CASHOUT_AMOUNT = 10000n;
|
|
403
407
|
var RECOMMENDED_MIN_CASHOUT_AMOUNT = 1000000n;
|
|
@@ -415,9 +419,6 @@ var PAYEE_HINTS = {
|
|
|
415
419
|
n26: "MoneyBeam email or phone number"
|
|
416
420
|
};
|
|
417
421
|
var IDENTITY_ATTESTATION_PLATFORMS = /* @__PURE__ */ new Set(["wise", "paypal"]);
|
|
418
|
-
function platformRequiresIdentityAttestation(platform) {
|
|
419
|
-
return IDENTITY_ATTESTATION_PLATFORMS.has(platform);
|
|
420
|
-
}
|
|
421
422
|
function buildCapabilities(environment) {
|
|
422
423
|
const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
423
424
|
const platforms = Object.entries(catalog).map(([platform, entry]) => {
|
|
@@ -451,12 +452,14 @@ var CashError = class extends Error {
|
|
|
451
452
|
code;
|
|
452
453
|
retryable;
|
|
453
454
|
remediation;
|
|
455
|
+
recovery;
|
|
454
456
|
constructor(shape, options) {
|
|
455
457
|
super(shape.message, options);
|
|
456
458
|
this.name = "CashError";
|
|
457
459
|
this.code = shape.code;
|
|
458
460
|
this.retryable = shape.retryable;
|
|
459
461
|
this.remediation = shape.remediation;
|
|
462
|
+
if (shape.recovery) this.recovery = shape.recovery;
|
|
460
463
|
}
|
|
461
464
|
/** Serializable view (for tool results and logs). */
|
|
462
465
|
toJSON() {
|
|
@@ -464,7 +467,8 @@ var CashError = class extends Error {
|
|
|
464
467
|
code: this.code,
|
|
465
468
|
message: this.message,
|
|
466
469
|
retryable: this.retryable,
|
|
467
|
-
remediation: this.remediation
|
|
470
|
+
remediation: this.remediation,
|
|
471
|
+
...this.recovery ? { recovery: this.recovery } : {}
|
|
468
472
|
};
|
|
469
473
|
}
|
|
470
474
|
};
|
|
@@ -478,18 +482,39 @@ var errors = {
|
|
|
478
482
|
retryable: false,
|
|
479
483
|
remediation: `Pick a currency listed in capabilities() - each one is priced by a live oracle feed.`
|
|
480
484
|
}),
|
|
485
|
+
oracleReadFailed: (currency, cause) => new CashError(
|
|
486
|
+
{
|
|
487
|
+
code: "ORACLE_READ_FAILED",
|
|
488
|
+
message: `The ${currency} market-rate oracle could not be read.`,
|
|
489
|
+
retryable: true,
|
|
490
|
+
remediation: `Retry the estimate shortly or use another healthy Base RPC. Do not present a cached value as a live market rate.`
|
|
491
|
+
},
|
|
492
|
+
{ cause }
|
|
493
|
+
),
|
|
481
494
|
unsupportedPlatform: (platform) => new CashError({
|
|
482
495
|
code: "UNSUPPORTED_PLATFORM",
|
|
483
496
|
message: `'${platform}' is not a supported payout platform in this environment.`,
|
|
484
497
|
retryable: false,
|
|
485
498
|
remediation: `Pick a platform listed in capabilities().`
|
|
486
499
|
}),
|
|
500
|
+
unsupportedPlatformCurrency: (platform, currency) => new CashError({
|
|
501
|
+
code: "UNSUPPORTED_PLATFORM_CURRENCY",
|
|
502
|
+
message: `${platform} cannot receive ${currency} in this environment.`,
|
|
503
|
+
retryable: false,
|
|
504
|
+
remediation: `Pick one of the currencies listed for ${platform} in capabilities().`
|
|
505
|
+
}),
|
|
487
506
|
amountBelowMinimum: (amount, min) => new CashError({
|
|
488
507
|
code: "AMOUNT_BELOW_MINIMUM",
|
|
489
508
|
message: `Amount ${amount} is below the minimum cash-out of ${min} USDC base units.`,
|
|
490
509
|
retryable: false,
|
|
491
510
|
remediation: `Increase the amount to at least ${min} base units (${Number(min) / 1e6} USDC).`
|
|
492
511
|
}),
|
|
512
|
+
invalidIntentAmountRange: (amount, min, max) => new CashError({
|
|
513
|
+
code: "INVALID_INTENT_AMOUNT_RANGE",
|
|
514
|
+
message: `Intent amount range ${min}-${max} is invalid for a ${amount} base-unit cash-out.`,
|
|
515
|
+
retryable: false,
|
|
516
|
+
remediation: `Use a positive minimum no greater than the maximum, and a maximum no greater than the cash-out amount.`
|
|
517
|
+
}),
|
|
493
518
|
activeIntentBlocksWithdrawal: (depositId) => new CashError({
|
|
494
519
|
code: "ACTIVE_INTENT_BLOCKS_WITHDRAWAL",
|
|
495
520
|
message: `Order ${depositId} has a live buyer intent; escrow blocks withdrawal while a buyer may still deliver.`,
|
|
@@ -502,12 +527,27 @@ var errors = {
|
|
|
502
527
|
retryable: true,
|
|
503
528
|
remediation: `Withdraw at most the available (unlocked) amount, or omit the amount to close the order fully once no buyer intent is live.`
|
|
504
529
|
}),
|
|
530
|
+
insufficientTokenBalance: (requiredAmount) => new CashError({
|
|
531
|
+
code: "INSUFFICIENT_TOKEN_BALANCE",
|
|
532
|
+
message: requiredAmount === void 0 ? `The wallet does not hold enough of the source token for this transaction.` : `The wallet does not hold the ${requiredAmount} base units required for this transaction.`,
|
|
533
|
+
retryable: false,
|
|
534
|
+
remediation: requiredAmount === void 0 ? `Fund the wallet with the required token amount, then retry.` : `Fund the wallet to at least ${requiredAmount} token base units, then retry.`
|
|
535
|
+
}),
|
|
505
536
|
orderNotActive: (depositId) => new CashError({
|
|
506
537
|
code: "ORDER_NOT_ACTIVE",
|
|
507
538
|
message: `Order ${depositId} is closed (delivered or returned); it cannot be topped up.`,
|
|
508
539
|
retryable: false,
|
|
509
540
|
remediation: `Start a new cash-out with cashout() instead.`
|
|
510
541
|
}),
|
|
542
|
+
invalidDepositId: (depositId, cause) => new CashError(
|
|
543
|
+
{
|
|
544
|
+
code: "INVALID_DEPOSIT_ID",
|
|
545
|
+
message: `'${depositId}' is not a valid Peer Cash deposit id.`,
|
|
546
|
+
retryable: false,
|
|
547
|
+
remediation: `Use the depositId returned by cashout() (escrowAddress_onchainDepositId) without modifying it.`
|
|
548
|
+
},
|
|
549
|
+
{ cause }
|
|
550
|
+
),
|
|
511
551
|
nothingToWithdraw: (depositId) => new CashError({
|
|
512
552
|
code: "NOTHING_TO_WITHDRAW",
|
|
513
553
|
message: `Order ${depositId} holds no withdrawable funds (already delivered or returned).`,
|
|
@@ -526,6 +566,15 @@ var errors = {
|
|
|
526
566
|
retryable: true,
|
|
527
567
|
remediation: `Verify the composite depositId (escrow_onchainId). If the deposit was created seconds ago this is indexer lag - retry shortly.`
|
|
528
568
|
}),
|
|
569
|
+
indexerUnavailable: (operation, cause) => new CashError(
|
|
570
|
+
{
|
|
571
|
+
code: "INDEXER_UNAVAILABLE",
|
|
572
|
+
message: `The protocol indexer could not complete the ${operation} query.`,
|
|
573
|
+
retryable: true,
|
|
574
|
+
remediation: `Retry shortly. Keep the composite depositId or owner address so the read can resume without repeating an on-chain transaction.`
|
|
575
|
+
},
|
|
576
|
+
{ cause }
|
|
577
|
+
),
|
|
529
578
|
payeeRegistrationFailed: (cause) => new CashError(
|
|
530
579
|
{
|
|
531
580
|
code: "PAYEE_REGISTRATION_FAILED",
|
|
@@ -556,12 +605,109 @@ var errors = {
|
|
|
556
605
|
retryable: false,
|
|
557
606
|
remediation: `For one-call source cashout, deliver Relay output to the depositor address. For a different recipient, bridge first and then cash out from that recipient's signer.`
|
|
558
607
|
}),
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
608
|
+
sourceCapabilitiesFailed: (cause) => new CashError(
|
|
609
|
+
{
|
|
610
|
+
code: "SOURCE_CAPABILITIES_FAILED",
|
|
611
|
+
message: `Relay source-chain discovery failed.`,
|
|
612
|
+
retryable: true,
|
|
613
|
+
remediation: `Retry sourceCapabilities() shortly, or use the default Base USDC path.`
|
|
614
|
+
},
|
|
615
|
+
{ cause }
|
|
616
|
+
),
|
|
617
|
+
sourceQuoteFailed: (cause) => new CashError(
|
|
618
|
+
{
|
|
619
|
+
code: "SOURCE_QUOTE_FAILED",
|
|
620
|
+
message: `Relay did not return a valid route to canonical Base USDC.`,
|
|
621
|
+
retryable: true,
|
|
622
|
+
remediation: `Refresh source capabilities and request a new quote. Do not submit transactions from this response.`
|
|
623
|
+
},
|
|
624
|
+
{ cause }
|
|
625
|
+
),
|
|
626
|
+
sourceExecutionFailed: (cause, evidence) => new CashError(
|
|
627
|
+
{
|
|
628
|
+
code: "SOURCE_EXECUTION_FAILED",
|
|
629
|
+
message: `Relay source-route execution did not complete successfully.`,
|
|
630
|
+
retryable: false,
|
|
631
|
+
remediation: `Inspect the wallet transactions and Relay request status before retrying so the source transfer is never submitted twice.`,
|
|
632
|
+
...evidence && (evidence.requestId !== void 0 || evidence.txHashes.length > 0) ? {
|
|
633
|
+
recovery: {
|
|
634
|
+
kind: "inspect-relay-route",
|
|
635
|
+
...evidence.requestId ? { requestId: evidence.requestId } : {},
|
|
636
|
+
txHashes: evidence.txHashes,
|
|
637
|
+
...evidence.transactions ? { transactions: evidence.transactions } : {}
|
|
638
|
+
}
|
|
639
|
+
} : {}
|
|
640
|
+
},
|
|
641
|
+
{ cause }
|
|
642
|
+
),
|
|
643
|
+
sourceStatusFailed: (requestId, cause) => new CashError(
|
|
644
|
+
{
|
|
645
|
+
code: "SOURCE_STATUS_FAILED",
|
|
646
|
+
message: `Relay status is unavailable for request ${requestId}.`,
|
|
647
|
+
retryable: true,
|
|
648
|
+
remediation: `Retry relayStatus(requestId) shortly; keep the request id and transaction hashes for recovery.`
|
|
649
|
+
},
|
|
650
|
+
{ cause }
|
|
651
|
+
),
|
|
652
|
+
sourceRouteCompletedCashoutFailed: (source, cause) => new CashError(
|
|
653
|
+
{
|
|
654
|
+
code: "SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED",
|
|
655
|
+
message: `Relay completed, but the Base USDC cash-out transaction was not created.`,
|
|
656
|
+
retryable: false,
|
|
657
|
+
remediation: `Do not repeat the Relay route. Retry cashout() without source using the recovery amount already delivered on Base.`,
|
|
658
|
+
recovery: {
|
|
659
|
+
kind: "retry-base-usdc-cashout",
|
|
660
|
+
amount: source.amount.toString(),
|
|
661
|
+
...source.requestId ? { requestId: source.requestId } : {},
|
|
662
|
+
txHashes: source.txHashes,
|
|
663
|
+
...source.transactions ? { transactions: source.transactions } : {}
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
{ cause }
|
|
667
|
+
),
|
|
668
|
+
sourceCashoutSubmissionUnknown: (source, depositor, cause) => new CashError(
|
|
669
|
+
{
|
|
670
|
+
code: "SOURCE_CASHOUT_SUBMISSION_UNKNOWN",
|
|
671
|
+
message: `Relay completed, but the Base cash-out submission did not return a transaction hash.`,
|
|
672
|
+
retryable: false,
|
|
673
|
+
remediation: `Do not repeat Relay or submit another cash-out yet. Inspect recent Base transactions and orders(${depositor}) to prove no deposit was broadcast; only then retry Base-USDC-only with the recovery amount.`,
|
|
674
|
+
recovery: {
|
|
675
|
+
kind: "inspect-base-cashout-submission",
|
|
676
|
+
amount: source.amount.toString(),
|
|
677
|
+
...source.requestId ? { requestId: source.requestId } : {},
|
|
678
|
+
txHashes: source.txHashes,
|
|
679
|
+
...source.transactions ? { transactions: source.transactions } : {},
|
|
680
|
+
depositor
|
|
681
|
+
}
|
|
682
|
+
},
|
|
683
|
+
{ cause }
|
|
684
|
+
),
|
|
685
|
+
sourceCashoutStatusUnknown: (source, depositTxHash, cause) => new CashError(
|
|
686
|
+
{
|
|
687
|
+
code: "SOURCE_CASHOUT_STATUS_UNKNOWN",
|
|
688
|
+
message: `Relay completed and Base cash-out transaction ${depositTxHash} was submitted, but its receipt could not be confirmed.`,
|
|
689
|
+
retryable: false,
|
|
690
|
+
remediation: `Do not repeat the Relay route or submit another cash-out. Inspect the Base transaction; if it succeeded, recover the depositId from its DepositReceived log, and if it reverted, retry a Base-USDC-only cashout with the recovery amount.`,
|
|
691
|
+
recovery: {
|
|
692
|
+
kind: "inspect-base-cashout-transaction",
|
|
693
|
+
amount: source.amount.toString(),
|
|
694
|
+
...source.requestId ? { requestId: source.requestId } : {},
|
|
695
|
+
txHashes: source.txHashes,
|
|
696
|
+
...source.transactions ? { transactions: source.transactions } : {},
|
|
697
|
+
depositTxHash
|
|
698
|
+
}
|
|
699
|
+
},
|
|
700
|
+
{ cause }
|
|
701
|
+
),
|
|
702
|
+
allowanceNotVisible: (amount, cause) => new CashError(
|
|
703
|
+
{
|
|
704
|
+
code: "ALLOWANCE_NOT_VISIBLE",
|
|
705
|
+
message: `USDC approval for ${amount} base units did not become visible on the read path in time.`,
|
|
706
|
+
retryable: true,
|
|
707
|
+
remediation: `The approve transaction mined but the RPC read path is stale or unavailable. Retry the same call in a few seconds.`
|
|
708
|
+
},
|
|
709
|
+
{ cause }
|
|
710
|
+
),
|
|
565
711
|
depositResolutionFailed: (txHash) => new CashError({
|
|
566
712
|
code: "DEPOSIT_RESOLUTION_FAILED",
|
|
567
713
|
message: `Deposit transaction ${txHash} succeeded but no DepositReceived event was found in the receipt.`,
|
|
@@ -574,6 +720,21 @@ var errors = {
|
|
|
574
720
|
retryable: false,
|
|
575
721
|
remediation: `Pass { signer } (a viem WalletClient with an account), or use prepare() and submit the returned txs with your own signing infrastructure.`
|
|
576
722
|
}),
|
|
723
|
+
signerChainMismatch: (verb, expectedChainId, actualChainId) => new CashError({
|
|
724
|
+
code: "SIGNER_CHAIN_MISMATCH",
|
|
725
|
+
message: `${verb} requires chain ${expectedChainId}, but the signer is connected to chain ${actualChainId}.`,
|
|
726
|
+
retryable: false,
|
|
727
|
+
remediation: `Switch the wallet to chain ${expectedChainId}, obtain a fresh quote if Relay is involved, and retry before submitting any transaction.`
|
|
728
|
+
}),
|
|
729
|
+
signerChainUnavailable: (verb, expectedChainId, cause) => new CashError(
|
|
730
|
+
{
|
|
731
|
+
code: "SIGNER_CHAIN_UNAVAILABLE",
|
|
732
|
+
message: `${verb} could not verify that the signer is connected to chain ${expectedChainId}.`,
|
|
733
|
+
retryable: true,
|
|
734
|
+
remediation: `Reconnect the wallet, switch it to chain ${expectedChainId}, and retry before submitting any transaction.`
|
|
735
|
+
},
|
|
736
|
+
{ cause }
|
|
737
|
+
),
|
|
577
738
|
watchTimeout: (depositId, timeoutMs) => new CashError({
|
|
578
739
|
code: "WATCH_TIMEOUT",
|
|
579
740
|
message: `watch(${depositId}) exceeded ${timeoutMs}ms without reaching a terminal state.`,
|
|
@@ -589,6 +750,30 @@ var errors = {
|
|
|
589
750
|
},
|
|
590
751
|
{ cause }
|
|
591
752
|
),
|
|
753
|
+
transactionSubmissionUnknown: (operation, cause, recovery) => new CashError(
|
|
754
|
+
{
|
|
755
|
+
code: "TRANSACTION_SUBMISSION_UNKNOWN",
|
|
756
|
+
message: `The Base ${operation} submission did not return a transaction hash.`,
|
|
757
|
+
retryable: false,
|
|
758
|
+
remediation: `Do not submit the operation again until you inspect recent Base wallet activity and protocol state; the first transaction may already exist.`,
|
|
759
|
+
...recovery ? { recovery } : {}
|
|
760
|
+
},
|
|
761
|
+
{ cause }
|
|
762
|
+
),
|
|
763
|
+
transactionStatusUnknown: (txHash, cause, operation = "transaction") => new CashError(
|
|
764
|
+
{
|
|
765
|
+
code: "TRANSACTION_STATUS_UNKNOWN",
|
|
766
|
+
message: `Transaction ${txHash} was submitted, but its receipt could not be confirmed.`,
|
|
767
|
+
retryable: false,
|
|
768
|
+
remediation: `Do not resubmit the operation until you inspect ${txHash} on Base or successfully fetch its receipt; the transaction may already have succeeded.`,
|
|
769
|
+
recovery: {
|
|
770
|
+
kind: "inspect-base-transaction",
|
|
771
|
+
transactionHash: txHash,
|
|
772
|
+
operation
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
{ cause }
|
|
776
|
+
),
|
|
592
777
|
escrowPaused: () => new CashError({
|
|
593
778
|
code: "ESCROW_PAUSED",
|
|
594
779
|
message: `The escrow contract is paused; deposits are temporarily disabled.`,
|
|
@@ -606,12 +791,15 @@ var errors = {
|
|
|
606
791
|
{ cause }
|
|
607
792
|
)
|
|
608
793
|
};
|
|
609
|
-
function mapChainError(verb, err) {
|
|
794
|
+
function mapChainError(verb, err, context = {}) {
|
|
610
795
|
if (isCashError(err)) return err;
|
|
611
796
|
const message = err instanceof Error ? err.message : String(err);
|
|
612
797
|
if (/\bpaused\b/i.test(message)) return errors.escrowPaused();
|
|
613
|
-
if (/exceeds
|
|
614
|
-
return errors.
|
|
798
|
+
if (/exceeds balance|insufficient token balance/i.test(message)) {
|
|
799
|
+
return errors.insufficientTokenBalance(context.requiredAmount);
|
|
800
|
+
}
|
|
801
|
+
if (/exceeds allowance|insufficient allowance/i.test(message)) {
|
|
802
|
+
return errors.allowanceNotVisible(context.requiredAmount ?? 0n);
|
|
615
803
|
}
|
|
616
804
|
return errors.chainCallFailed(verb, err);
|
|
617
805
|
}
|
|
@@ -777,20 +965,175 @@ function normalizeChain(chain) {
|
|
|
777
965
|
function isSupportedEvmChain(chain) {
|
|
778
966
|
return chain.vmType === void 0 || chain.vmType === "evm";
|
|
779
967
|
}
|
|
968
|
+
function isExecutableSourceChain(chain) {
|
|
969
|
+
return isSupportedEvmChain(chain) && !chain.disabled && chain.depositEnabled && !chain.blockProductionLagging;
|
|
970
|
+
}
|
|
780
971
|
function quoteRequestId(quote) {
|
|
781
972
|
return quote.steps.map((step) => step.requestId).find((id) => id !== void 0);
|
|
782
973
|
}
|
|
974
|
+
function collectRelayTransactions(steps, sourceChainId) {
|
|
975
|
+
const origin = [];
|
|
976
|
+
const destination = [];
|
|
977
|
+
const record = (tx) => {
|
|
978
|
+
(tx.chainId === sourceChainId ? origin : destination).push(tx);
|
|
979
|
+
};
|
|
980
|
+
for (const step of steps) {
|
|
981
|
+
for (const item of step.items) {
|
|
982
|
+
for (const tx of item.internalTxHashes ?? []) {
|
|
983
|
+
record({ hash: tx.txHash, chainId: tx.chainId });
|
|
984
|
+
}
|
|
985
|
+
for (const tx of item.txHashes ?? []) {
|
|
986
|
+
record({ hash: tx.txHash, chainId: tx.chainId });
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
const dedupe = (txs) => [
|
|
991
|
+
...new Map(txs.map((tx) => [`${tx.chainId}:${tx.hash.toLowerCase()}`, tx])).values()
|
|
992
|
+
];
|
|
993
|
+
return { origin: dedupe(origin), destination: dedupe(destination) };
|
|
994
|
+
}
|
|
995
|
+
function relayTransactionHashes(transactions) {
|
|
996
|
+
return [
|
|
997
|
+
...new Set([...transactions.origin, ...transactions.destination].map(({ hash }) => hash))
|
|
998
|
+
];
|
|
999
|
+
}
|
|
783
1000
|
function quoteSourceChainId(quote) {
|
|
784
1001
|
const details = asRecord(quote.details);
|
|
785
1002
|
const currencyIn = asRecord(details.currencyIn);
|
|
786
1003
|
const sourceCurrency = asRecord(currencyIn.currency);
|
|
787
1004
|
return asNumber(sourceCurrency.chainId);
|
|
788
1005
|
}
|
|
1006
|
+
function assertCanonicalRelayDestination(quote) {
|
|
1007
|
+
const details = asRecord(quote.details);
|
|
1008
|
+
const currencyOut = asRecord(details.currencyOut);
|
|
1009
|
+
const destination = asRecord(currencyOut.currency);
|
|
1010
|
+
if (asNumber(destination.chainId) !== BASE_CHAIN_ID || asString(destination.address)?.toLowerCase() !== BASE_USDC_ADDRESS.toLowerCase()) {
|
|
1011
|
+
throw new Error("Relay quote destination is not canonical Base USDC");
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
async function assertWalletChainId(wallet, expectedChainId, operation) {
|
|
1015
|
+
let actualChainId;
|
|
1016
|
+
try {
|
|
1017
|
+
actualChainId = await wallet.getChainId();
|
|
1018
|
+
} catch (err) {
|
|
1019
|
+
throw errors.signerChainUnavailable(operation, expectedChainId, err);
|
|
1020
|
+
}
|
|
1021
|
+
if (actualChainId !== expectedChainId) {
|
|
1022
|
+
throw errors.signerChainMismatch(operation, expectedChainId, actualChainId);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
async function assertRelayExecutionIdentity(quote, wallet, expectedRecipient) {
|
|
1026
|
+
const signer = wallet.account?.address;
|
|
1027
|
+
if (!signer) throw new Error("Relay execution requires a wallet account");
|
|
1028
|
+
const sourceChainId = quoteSourceChainId(quote);
|
|
1029
|
+
if (sourceChainId !== void 0) {
|
|
1030
|
+
await assertWalletChainId(wallet, sourceChainId, "Relay execution");
|
|
1031
|
+
}
|
|
1032
|
+
const details = asRecord(quote.details);
|
|
1033
|
+
const sender = asString(details.sender);
|
|
1034
|
+
const recipient = asString(details.recipient);
|
|
1035
|
+
if (!sender || sender.toLowerCase() !== signer.toLowerCase()) {
|
|
1036
|
+
throw new Error("Relay quote sender does not match the execution signer");
|
|
1037
|
+
}
|
|
1038
|
+
const destinationOwner = expectedRecipient ?? signer;
|
|
1039
|
+
if (!recipient || recipient.toLowerCase() !== destinationOwner.toLowerCase()) {
|
|
1040
|
+
throw new Error("Relay quote recipient does not match the expected Base recipient");
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
function isRelaySecretKey(key) {
|
|
1044
|
+
const normalized = key.toLowerCase();
|
|
1045
|
+
return normalized === "headers" || normalized === "apikey";
|
|
1046
|
+
}
|
|
1047
|
+
function redactRelayValue(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
1048
|
+
if (value === null || typeof value !== "object") return value;
|
|
1049
|
+
if (value instanceof Date || value instanceof Error) return value;
|
|
1050
|
+
const existing = seen.get(value);
|
|
1051
|
+
if (existing !== void 0) return existing;
|
|
1052
|
+
if (Array.isArray(value)) {
|
|
1053
|
+
const output2 = [];
|
|
1054
|
+
seen.set(value, output2);
|
|
1055
|
+
for (const entry of value) output2.push(redactRelayValue(entry, seen));
|
|
1056
|
+
return output2;
|
|
1057
|
+
}
|
|
1058
|
+
const output = {};
|
|
1059
|
+
seen.set(value, output);
|
|
1060
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
1061
|
+
if (!isRelaySecretKey(key)) output[key] = redactRelayValue(entry, seen);
|
|
1062
|
+
}
|
|
1063
|
+
return output;
|
|
1064
|
+
}
|
|
1065
|
+
var RELAY_WIRE_TYPE = "__zkp2pCashType";
|
|
1066
|
+
function sanitizeRelayValue(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1067
|
+
if (typeof value === "bigint") {
|
|
1068
|
+
return { [RELAY_WIRE_TYPE]: "bigint", value: value.toString() };
|
|
1069
|
+
}
|
|
1070
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
1071
|
+
return value;
|
|
1072
|
+
}
|
|
1073
|
+
if (typeof value === "number") {
|
|
1074
|
+
return Number.isFinite(value) ? value : { [RELAY_WIRE_TYPE]: "number", value: String(value) };
|
|
1075
|
+
}
|
|
1076
|
+
if (typeof value === "undefined") return { [RELAY_WIRE_TYPE]: "undefined" };
|
|
1077
|
+
if (value instanceof Date) {
|
|
1078
|
+
return { [RELAY_WIRE_TYPE]: "date", value: value.toISOString() };
|
|
1079
|
+
}
|
|
1080
|
+
if (value instanceof Error) {
|
|
1081
|
+
return {
|
|
1082
|
+
[RELAY_WIRE_TYPE]: "error",
|
|
1083
|
+
name: value.name,
|
|
1084
|
+
message: value.message
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
if (typeof value !== "object") return void 0;
|
|
1088
|
+
if (seen.has(value)) throw new TypeError("Relay payload contains a circular reference");
|
|
1089
|
+
seen.add(value);
|
|
1090
|
+
if (Array.isArray(value)) {
|
|
1091
|
+
const output2 = value.map((entry) => sanitizeRelayValue(entry, seen));
|
|
1092
|
+
seen.delete(value);
|
|
1093
|
+
return output2;
|
|
1094
|
+
}
|
|
1095
|
+
const output = {};
|
|
1096
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
1097
|
+
if (isRelaySecretKey(key)) continue;
|
|
1098
|
+
const sanitized = sanitizeRelayValue(entry, seen);
|
|
1099
|
+
if (sanitized !== void 0) output[key] = sanitized;
|
|
1100
|
+
}
|
|
1101
|
+
seen.delete(value);
|
|
1102
|
+
return output;
|
|
1103
|
+
}
|
|
1104
|
+
function restoreRelayValue(value) {
|
|
1105
|
+
if (Array.isArray(value)) return value.map(restoreRelayValue);
|
|
1106
|
+
if (value === null || typeof value !== "object") return value;
|
|
1107
|
+
const row = value;
|
|
1108
|
+
const wireType = row[RELAY_WIRE_TYPE];
|
|
1109
|
+
const keyCount = Object.keys(row).length;
|
|
1110
|
+
if (keyCount === 2 && wireType === "bigint" && typeof row.value === "string") {
|
|
1111
|
+
return BigInt(row.value);
|
|
1112
|
+
}
|
|
1113
|
+
if (keyCount === 2 && wireType === "date" && typeof row.value === "string") {
|
|
1114
|
+
return new Date(row.value);
|
|
1115
|
+
}
|
|
1116
|
+
if (keyCount === 2 && wireType === "number" && typeof row.value === "string") {
|
|
1117
|
+
return Number(row.value);
|
|
1118
|
+
}
|
|
1119
|
+
if (keyCount === 1 && wireType === "undefined") return void 0;
|
|
1120
|
+
if (keyCount === 3 && wireType === "error" && typeof row.message === "string") {
|
|
1121
|
+
const error = new Error(row.message);
|
|
1122
|
+
if (typeof row.name === "string") error.name = row.name;
|
|
1123
|
+
return error;
|
|
1124
|
+
}
|
|
1125
|
+
return Object.fromEntries(
|
|
1126
|
+
Object.entries(row).map(([key, entry]) => [key, restoreRelayValue(entry)])
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
function redactRelayQuoteRaw(quote) {
|
|
1130
|
+
return redactRelayValue(quote);
|
|
1131
|
+
}
|
|
789
1132
|
function sanitizeRelayQuoteRaw(quote) {
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
return
|
|
1133
|
+
return sanitizeRelayValue(quote);
|
|
1134
|
+
}
|
|
1135
|
+
function restoreRelayQuoteRaw(value) {
|
|
1136
|
+
return restoreRelayValue(value);
|
|
794
1137
|
}
|
|
795
1138
|
async function resolveRelayChains(options, client, config = {}) {
|
|
796
1139
|
const preferInjectedClientChains = config.preferInjectedClientChains ?? true;
|
|
@@ -804,19 +1147,38 @@ function relayQuoteFromExecute(input, quote) {
|
|
|
804
1147
|
const currencyOut = asRecord(details.currencyOut);
|
|
805
1148
|
const sourceCurrency = asRecord(currencyIn.currency);
|
|
806
1149
|
const destinationCurrency = asRecord(currencyOut.currency);
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
const
|
|
1150
|
+
const sourceChainId = asNumber(sourceCurrency.chainId);
|
|
1151
|
+
const sourceAddress = asString(sourceCurrency.address);
|
|
1152
|
+
const sender = asString(details.sender);
|
|
1153
|
+
const recipient = asString(details.recipient);
|
|
1154
|
+
const expectedRecipient = input.recipient ?? input.user;
|
|
1155
|
+
const destinationChainId = asNumber(destinationCurrency.chainId);
|
|
1156
|
+
const destinationAddress = asString(destinationCurrency.address);
|
|
1157
|
+
if (sourceChainId !== input.source.chainId || sourceAddress?.toLowerCase() !== input.source.currency.toLowerCase()) {
|
|
1158
|
+
throw new Error("Relay quote source does not match the requested asset");
|
|
1159
|
+
}
|
|
1160
|
+
if (!sender || sender.toLowerCase() !== input.user.toLowerCase()) {
|
|
1161
|
+
throw new Error("Relay quote sender does not match the requested wallet");
|
|
1162
|
+
}
|
|
1163
|
+
if (!recipient || recipient.toLowerCase() !== expectedRecipient.toLowerCase()) {
|
|
1164
|
+
throw new Error("Relay quote recipient does not match the requested Base recipient");
|
|
1165
|
+
}
|
|
1166
|
+
if (destinationChainId !== BASE_CHAIN_ID || destinationAddress?.toLowerCase() !== BASE_USDC_ADDRESS.toLowerCase()) {
|
|
1167
|
+
throw new Error("Relay quote destination is not canonical Base USDC");
|
|
1168
|
+
}
|
|
1169
|
+
const source = normalizeToken(input.source.chainId, sourceCurrency);
|
|
1170
|
+
if (!source) throw new Error("Relay quote source metadata is malformed");
|
|
1171
|
+
const destination = normalizeToken(destinationChainId, destinationCurrency);
|
|
1172
|
+
if (!destination) throw new Error("Relay quote destination metadata is malformed");
|
|
814
1173
|
const txs = quote.steps.flatMap(
|
|
815
1174
|
(step) => step.items.map((item) => normalizeTx(item.data, input.source.chainId)).filter((tx) => tx !== null)
|
|
816
1175
|
);
|
|
817
|
-
const
|
|
818
|
-
|
|
819
|
-
|
|
1176
|
+
const rawOutputAmount = currencyOut.minimumAmount ?? currencyOut.amount;
|
|
1177
|
+
if (rawOutputAmount === void 0 || rawOutputAmount === null) {
|
|
1178
|
+
throw new Error("Relay quote is missing an output amount");
|
|
1179
|
+
}
|
|
1180
|
+
const outputAmount = BigInt(String(rawOutputAmount));
|
|
1181
|
+
if (outputAmount <= 0n) throw new Error("Relay quote output amount must be positive");
|
|
820
1182
|
const requestId = quoteRequestId(quote);
|
|
821
1183
|
const rate = asNumber(details.rate);
|
|
822
1184
|
const timeEstimateSeconds = asNumber(details.timeEstimate);
|
|
@@ -824,92 +1186,135 @@ function relayQuoteFromExecute(input, quote) {
|
|
|
824
1186
|
...requestId ? { requestId } : {},
|
|
825
1187
|
source,
|
|
826
1188
|
destination,
|
|
827
|
-
inputAmount: BigInt(String(currencyIn.amount
|
|
1189
|
+
inputAmount: BigInt(String(currencyIn.amount)),
|
|
828
1190
|
outputAmount,
|
|
829
1191
|
...rate !== void 0 ? { rate } : {},
|
|
830
1192
|
...timeEstimateSeconds !== void 0 ? { timeEstimateSeconds } : {},
|
|
831
1193
|
...quote.fees !== void 0 ? { fees: quote.fees } : {},
|
|
832
1194
|
txs,
|
|
833
|
-
raw:
|
|
1195
|
+
raw: redactRelayQuoteRaw(quote)
|
|
834
1196
|
};
|
|
835
1197
|
}
|
|
836
1198
|
async function readRelaySourceCapabilities(options = {}) {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1199
|
+
try {
|
|
1200
|
+
const client = relayClient(options);
|
|
1201
|
+
const chains = await resolveRelayChains(options, client);
|
|
1202
|
+
return {
|
|
1203
|
+
destination: BASE_USDC_ASSET,
|
|
1204
|
+
chains: chains.map(normalizeChain).filter((chain) => chain.tokens.length > 0 && isExecutableSourceChain(chain)).sort((a, b) => a.displayName.localeCompare(b.displayName)),
|
|
1205
|
+
source: "relay-sdk",
|
|
1206
|
+
asOf: Math.floor(Date.now() / 1e3)
|
|
1207
|
+
};
|
|
1208
|
+
} catch (err) {
|
|
1209
|
+
if (isCashError(err)) throw err;
|
|
1210
|
+
throw errors.sourceCapabilitiesFailed(err);
|
|
1211
|
+
}
|
|
845
1212
|
}
|
|
846
1213
|
async function quoteRelayToBaseUsdc(input, options = {}) {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1214
|
+
try {
|
|
1215
|
+
if (input.amount <= 0n) throw new Error("Relay quote amount must be positive");
|
|
1216
|
+
const client = relayClient(options);
|
|
1217
|
+
const quote = await client.actions.getQuote(
|
|
1218
|
+
{
|
|
1219
|
+
chainId: input.source.chainId,
|
|
1220
|
+
currency: input.source.currency,
|
|
1221
|
+
toChainId: BASE_CHAIN_ID,
|
|
1222
|
+
toCurrency: BASE_USDC_ADDRESS,
|
|
1223
|
+
user: input.user,
|
|
1224
|
+
recipient: input.recipient ?? input.user,
|
|
1225
|
+
amount: input.amount.toString(),
|
|
1226
|
+
tradeType: input.tradeType ?? "EXACT_INPUT"
|
|
1227
|
+
},
|
|
1228
|
+
false
|
|
1229
|
+
);
|
|
1230
|
+
return relayQuoteFromExecute(input, quote);
|
|
1231
|
+
} catch (err) {
|
|
1232
|
+
if (isCashError(err)) throw err;
|
|
1233
|
+
throw errors.sourceQuoteFailed(err);
|
|
1234
|
+
}
|
|
862
1235
|
}
|
|
863
1236
|
async function executeRelayQuote(quote, wallet, options = {}) {
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
1237
|
+
let observedRequestId;
|
|
1238
|
+
let observedTransactions = { origin: [], destination: [] };
|
|
1239
|
+
try {
|
|
1240
|
+
const rawQuote = "raw" in quote ? quote.raw : quote;
|
|
1241
|
+
observedRequestId = quoteRequestId(rawQuote);
|
|
1242
|
+
assertCanonicalRelayDestination(rawQuote);
|
|
1243
|
+
await assertRelayExecutionIdentity(rawQuote, wallet, options.recipient);
|
|
1244
|
+
const client = relayClient(options.relay);
|
|
1245
|
+
const sourceChainId = quoteSourceChainId(rawQuote);
|
|
1246
|
+
if (sourceChainId !== void 0 && !(client.chains ?? []).some((chain) => chain.id === sourceChainId)) {
|
|
1247
|
+
await resolveRelayChains(options.relay ?? {}, client, { preferInjectedClientChains: false });
|
|
1248
|
+
}
|
|
1249
|
+
const onProgress = (data2) => {
|
|
1250
|
+
const progressSteps = Array.isArray(data2.steps) ? data2.steps : [];
|
|
1251
|
+
observedRequestId = progressSteps.map((step) => step.requestId).find((id) => id !== void 0) ?? observedRequestId;
|
|
1252
|
+
observedTransactions = collectRelayTransactions(progressSteps, sourceChainId);
|
|
1253
|
+
if (options.onProgress) {
|
|
1254
|
+
try {
|
|
1255
|
+
options.onProgress(data2);
|
|
1256
|
+
} catch {
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
const { data } = await client.actions.execute({
|
|
1261
|
+
quote: rawQuote,
|
|
1262
|
+
wallet,
|
|
1263
|
+
onProgress,
|
|
1264
|
+
...options.disableCapabilitiesCheck !== void 0 ? { disableCapabilitiesCheck: options.disableCapabilitiesCheck } : {}
|
|
1265
|
+
});
|
|
1266
|
+
const requestId = quoteRequestId(data) ?? observedRequestId;
|
|
1267
|
+
const transactions = collectRelayTransactions(data.steps, sourceChainId);
|
|
1268
|
+
return {
|
|
1269
|
+
...requestId ? { requestId } : {},
|
|
1270
|
+
txHashes: relayTransactionHashes(transactions),
|
|
1271
|
+
transactions,
|
|
1272
|
+
quote: redactRelayQuoteRaw(data)
|
|
1273
|
+
};
|
|
1274
|
+
} catch (err) {
|
|
1275
|
+
if (isCashError(err)) throw err;
|
|
1276
|
+
const txHashes = relayTransactionHashes(observedTransactions);
|
|
1277
|
+
throw errors.sourceExecutionFailed(err, {
|
|
1278
|
+
...observedRequestId ? { requestId: observedRequestId } : {},
|
|
1279
|
+
txHashes,
|
|
1280
|
+
...txHashes.length > 0 ? { transactions: observedTransactions } : {}
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
883
1283
|
}
|
|
884
1284
|
async function readRelayStatus(requestId, options = {}) {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1285
|
+
try {
|
|
1286
|
+
const client = relayClient(options);
|
|
1287
|
+
const response = await client.utils.request({
|
|
1288
|
+
url: `${client.baseApiUrl}/intents/status/v3`,
|
|
1289
|
+
method: "get",
|
|
1290
|
+
params: { requestId }
|
|
1291
|
+
});
|
|
1292
|
+
const root = asRecord(response.data);
|
|
1293
|
+
const status = asString(root.status);
|
|
1294
|
+
if (status !== "refund" && status !== "waiting" && status !== "depositing" && status !== "failure" && status !== "pending" && status !== "submitted" && status !== "success") {
|
|
1295
|
+
throw new Error(`Relay returned unknown status: ${String(root.status)}`);
|
|
1296
|
+
}
|
|
1297
|
+
const details = asString(root.details);
|
|
1298
|
+
const updatedAt = asNumber(root.updatedAt);
|
|
1299
|
+
const originChainId = asNumber(root.originChainId);
|
|
1300
|
+
const destinationChainId = asNumber(root.destinationChainId);
|
|
1301
|
+
const quoteCreatedAt = asNumber(root.quoteCreatedAt);
|
|
1302
|
+
return {
|
|
1303
|
+
requestId,
|
|
1304
|
+
status,
|
|
1305
|
+
...details ? { details } : {},
|
|
1306
|
+
inTxHashes: Array.isArray(root.inTxHashes) ? root.inTxHashes.map(String) : [],
|
|
1307
|
+
txHashes: Array.isArray(root.txHashes) ? root.txHashes.map(String) : [],
|
|
1308
|
+
...updatedAt !== void 0 ? { updatedAt } : {},
|
|
1309
|
+
...originChainId !== void 0 ? { originChainId } : {},
|
|
1310
|
+
...destinationChainId !== void 0 ? { destinationChainId } : {},
|
|
1311
|
+
...quoteCreatedAt !== void 0 ? { quoteCreatedAt } : {},
|
|
1312
|
+
raw: response.data
|
|
1313
|
+
};
|
|
1314
|
+
} catch (err) {
|
|
1315
|
+
if (isCashError(err)) throw err;
|
|
1316
|
+
throw errors.sourceStatusFailed(requestId, err);
|
|
1317
|
+
}
|
|
913
1318
|
}
|
|
914
1319
|
|
|
915
1320
|
// src/client/estimate.ts
|
|
@@ -956,11 +1361,16 @@ async function readEstimate(publicClient, input, context = {}) {
|
|
|
956
1361
|
if (!feedConfig || feedConfig.feed.toLowerCase() === ZERO_ADDRESS) {
|
|
957
1362
|
rate = 1;
|
|
958
1363
|
} else {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1364
|
+
let result;
|
|
1365
|
+
try {
|
|
1366
|
+
result = await publicClient.readContract({
|
|
1367
|
+
address: feedConfig.feed,
|
|
1368
|
+
abi: CHAINLINK_LATEST_ROUND_ABI,
|
|
1369
|
+
functionName: "latestRoundData"
|
|
1370
|
+
});
|
|
1371
|
+
} catch (err) {
|
|
1372
|
+
throw errors.oracleReadFailed(currency, err);
|
|
1373
|
+
}
|
|
964
1374
|
const answer = Number(result[1]);
|
|
965
1375
|
const price = answer / 10 ** feedConfig.decimals;
|
|
966
1376
|
if (!Number.isFinite(price) || price <= 0) {
|
|
@@ -1006,6 +1416,7 @@ async function readEstimate(publicClient, input, context = {}) {
|
|
|
1006
1416
|
var DEFAULT_RPC_URL = "https://mainnet.base.org";
|
|
1007
1417
|
var CASH_ATTRIBUTION_CODE = "peer-cash";
|
|
1008
1418
|
var DEFAULT_CURATOR_URLS = {
|
|
1419
|
+
preproduction: "https://api-preprod.zkp2p.xyz",
|
|
1009
1420
|
staging: "https://api-staging.zkp2p.xyz"
|
|
1010
1421
|
};
|
|
1011
1422
|
var ERC20_APPROVE_ABI = viem.parseAbi([
|
|
@@ -1040,12 +1451,29 @@ async function submitAndConfirm(client, verb, send) {
|
|
|
1040
1451
|
try {
|
|
1041
1452
|
hash = await send();
|
|
1042
1453
|
} catch (err) {
|
|
1043
|
-
|
|
1454
|
+
const mapped = mapChainError(verb, err);
|
|
1455
|
+
if (isKnownPreBroadcastFailure(err, mapped)) throw mapped;
|
|
1456
|
+
throw errors.transactionSubmissionUnknown(verb, err, {
|
|
1457
|
+
kind: "inspect-base-operation-submission",
|
|
1458
|
+
operation: verb
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
let receipt;
|
|
1462
|
+
try {
|
|
1463
|
+
receipt = await client.publicClient.waitForTransactionReceipt({ hash });
|
|
1464
|
+
} catch (err) {
|
|
1465
|
+
throw errors.transactionStatusUnknown(hash, err, verb);
|
|
1044
1466
|
}
|
|
1045
|
-
const receipt = await client.publicClient.waitForTransactionReceipt({ hash });
|
|
1046
1467
|
if (receipt.status === "reverted") throw errors.transactionFailed(hash);
|
|
1047
1468
|
return hash;
|
|
1048
1469
|
}
|
|
1470
|
+
function isKnownPreBroadcastFailure(err, mapped) {
|
|
1471
|
+
if (mapped.code === "INSUFFICIENT_TOKEN_BALANCE" || mapped.code === "ALLOWANCE_NOT_VISIBLE" || mapped.code === "ESCROW_PAUSED") {
|
|
1472
|
+
return true;
|
|
1473
|
+
}
|
|
1474
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1475
|
+
return /user rejected|user denied|rejected request|action_rejected/i.test(message);
|
|
1476
|
+
}
|
|
1049
1477
|
function depositOrderOptions(deposit) {
|
|
1050
1478
|
const remaining = toBigIntOrUndefined(deposit.remainingDeposits);
|
|
1051
1479
|
const outstanding = toBigIntOrUndefined(deposit.outstandingIntentAmount);
|
|
@@ -1085,9 +1513,10 @@ function createCashClient(options) {
|
|
|
1085
1513
|
}
|
|
1086
1514
|
const readClient = buildSdkClient(viem.createWalletClient({ chain: chains.base, transport }));
|
|
1087
1515
|
const signingClients = /* @__PURE__ */ new WeakMap();
|
|
1088
|
-
function signingClient(verb, opts) {
|
|
1516
|
+
async function signingClient(verb, opts) {
|
|
1089
1517
|
const signer = opts?.signer;
|
|
1090
1518
|
if (!signer?.account) throw errors.signerRequired(verb);
|
|
1519
|
+
await assertWalletChainId(signer, BASE_CHAIN_ID, verb);
|
|
1091
1520
|
let client = signingClients.get(signer);
|
|
1092
1521
|
if (!client) {
|
|
1093
1522
|
client = buildSdkClient(signer);
|
|
@@ -1097,13 +1526,15 @@ function createCashClient(options) {
|
|
|
1097
1526
|
}
|
|
1098
1527
|
function validatePayout(input) {
|
|
1099
1528
|
const { receive } = input;
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1529
|
+
const platform = buildCapabilities(environment).platforms.find(
|
|
1530
|
+
(capability) => capability.platform === receive.platform
|
|
1531
|
+
);
|
|
1532
|
+
if (!platform) throw errors.unsupportedPlatform(receive.platform);
|
|
1102
1533
|
if (!isMarketRateSupported(receive.currency)) {
|
|
1103
1534
|
throw errors.oracleUnsupportedCurrency(receive.currency);
|
|
1104
1535
|
}
|
|
1105
|
-
if (
|
|
1106
|
-
throw errors.
|
|
1536
|
+
if (!platform.currencies.includes(receive.currency)) {
|
|
1537
|
+
throw errors.unsupportedPlatformCurrency(receive.platform, receive.currency);
|
|
1107
1538
|
}
|
|
1108
1539
|
return {
|
|
1109
1540
|
payouts: [
|
|
@@ -1112,15 +1543,22 @@ function createCashClient(options) {
|
|
|
1112
1543
|
currency: receive.currency,
|
|
1113
1544
|
payeeData: receive.payee
|
|
1114
1545
|
}
|
|
1115
|
-
]
|
|
1116
|
-
...input.intentAmountRange ? { intentAmountRange: input.intentAmountRange } : {}
|
|
1546
|
+
]
|
|
1117
1547
|
};
|
|
1118
1548
|
}
|
|
1119
|
-
function
|
|
1120
|
-
if (
|
|
1121
|
-
throw errors.amountBelowMinimum(
|
|
1549
|
+
function validateDepositInput(amount, input, payoutInput = validatePayout(input)) {
|
|
1550
|
+
if (amount < MIN_CASHOUT_AMOUNT) {
|
|
1551
|
+
throw errors.amountBelowMinimum(amount, MIN_CASHOUT_AMOUNT);
|
|
1552
|
+
}
|
|
1553
|
+
const range = input.intentAmountRange;
|
|
1554
|
+
if (range && (range.min <= 0n || range.max < range.min || range.max > amount)) {
|
|
1555
|
+
throw errors.invalidIntentAmountRange(amount, range.min, range.max);
|
|
1122
1556
|
}
|
|
1123
|
-
return {
|
|
1557
|
+
return {
|
|
1558
|
+
amount,
|
|
1559
|
+
...payoutInput,
|
|
1560
|
+
...range ? { intentAmountRange: range } : {}
|
|
1561
|
+
};
|
|
1124
1562
|
}
|
|
1125
1563
|
async function buildDepositParams(client, depositInput) {
|
|
1126
1564
|
try {
|
|
@@ -1135,32 +1573,54 @@ function createCashClient(options) {
|
|
|
1135
1573
|
throw errors.payeeRegistrationFailed(err);
|
|
1136
1574
|
}
|
|
1137
1575
|
}
|
|
1576
|
+
function parseDepositId(depositId) {
|
|
1577
|
+
try {
|
|
1578
|
+
const parsed = parseCompositeDepositId(depositId);
|
|
1579
|
+
return {
|
|
1580
|
+
...parsed,
|
|
1581
|
+
compositeId: sdk.createCompositeDepositId(parsed.escrowAddress, parsed.onchainDepositId)
|
|
1582
|
+
};
|
|
1583
|
+
} catch (err) {
|
|
1584
|
+
throw errors.invalidDepositId(depositId, err);
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1138
1587
|
async function fetchOrder(depositId) {
|
|
1139
|
-
const
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1588
|
+
const { compositeId } = parseDepositId(depositId);
|
|
1589
|
+
let deposits;
|
|
1590
|
+
try {
|
|
1591
|
+
deposits = await readClient.indexer.getDepositsByIdsWithRelations([compositeId], {
|
|
1592
|
+
includeIntents: true,
|
|
1593
|
+
intentStatuses: CASH_ORDER_STATUSES
|
|
1594
|
+
});
|
|
1595
|
+
} catch (err) {
|
|
1596
|
+
throw errors.indexerUnavailable("order", err);
|
|
1597
|
+
}
|
|
1143
1598
|
const deposit = deposits[0];
|
|
1144
1599
|
if (!deposit) {
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1600
|
+
let intents;
|
|
1601
|
+
try {
|
|
1602
|
+
intents = await readClient.indexer.getIntentsForDeposits(
|
|
1603
|
+
[compositeId],
|
|
1604
|
+
CASH_ORDER_STATUSES
|
|
1605
|
+
);
|
|
1606
|
+
} catch (err) {
|
|
1607
|
+
throw errors.indexerUnavailable("order intents", err);
|
|
1608
|
+
}
|
|
1609
|
+
if (intents.length === 0) throw errors.orderNotFound(compositeId);
|
|
1610
|
+
return deriveCashOrder(compositeId, intents);
|
|
1151
1611
|
}
|
|
1152
1612
|
const payouts = derivePayouts(
|
|
1153
1613
|
deposit.paymentMethods ?? [],
|
|
1154
1614
|
deposit.currencies ?? [],
|
|
1155
1615
|
sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment)
|
|
1156
1616
|
);
|
|
1157
|
-
return deriveCashOrder(
|
|
1617
|
+
return deriveCashOrder(compositeId, deposit.intents ?? [], {
|
|
1158
1618
|
...depositOrderOptions(deposit),
|
|
1159
1619
|
...payouts.length > 0 ? { payouts } : {}
|
|
1160
1620
|
});
|
|
1161
1621
|
}
|
|
1162
1622
|
function escrowContext(depositId) {
|
|
1163
|
-
const { escrowAddress, onchainDepositId } =
|
|
1623
|
+
const { escrowAddress, onchainDepositId } = parseDepositId(depositId);
|
|
1164
1624
|
return {
|
|
1165
1625
|
onchainDepositId,
|
|
1166
1626
|
escrowArg: escrowAddress ? { escrowAddress } : {}
|
|
@@ -1175,7 +1635,7 @@ function createCashClient(options) {
|
|
|
1175
1635
|
const signaled = order.fills.filter((f) => f.status === "SIGNALED");
|
|
1176
1636
|
const liveIntent = signaled.some((f) => isFillLive(f, nowSeconds));
|
|
1177
1637
|
const expiredIntent = signaled.length > 0 && !liveIntent;
|
|
1178
|
-
if (order.pendingAmount > 0n &&
|
|
1638
|
+
if (liveIntent || order.pendingAmount > 0n && signaled.length === 0) {
|
|
1179
1639
|
throw errors.activeIntentBlocksWithdrawal(depositId);
|
|
1180
1640
|
}
|
|
1181
1641
|
if (availableAmount(order) <= 0n && order.pendingAmount === 0n) {
|
|
@@ -1216,22 +1676,32 @@ function createCashClient(options) {
|
|
|
1216
1676
|
txOverrides: attribution
|
|
1217
1677
|
});
|
|
1218
1678
|
} catch (err) {
|
|
1219
|
-
throw mapChainError("approve", err);
|
|
1679
|
+
throw mapChainError("approve", err, { requiredAmount: amount });
|
|
1220
1680
|
}
|
|
1221
1681
|
if (allowance.hadAllowance || !allowance.hash) return;
|
|
1222
|
-
|
|
1682
|
+
let receipt;
|
|
1683
|
+
try {
|
|
1684
|
+
receipt = await client.publicClient.waitForTransactionReceipt({ hash: allowance.hash });
|
|
1685
|
+
} catch (err) {
|
|
1686
|
+
throw errors.transactionStatusUnknown(allowance.hash, err, "approve");
|
|
1687
|
+
}
|
|
1223
1688
|
if (receipt.status === "reverted") throw errors.transactionFailed(allowance.hash);
|
|
1689
|
+
let lastReadError;
|
|
1224
1690
|
for (let attempt = 0; attempt < 15; attempt++) {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1691
|
+
try {
|
|
1692
|
+
const visible = await client.publicClient.readContract({
|
|
1693
|
+
address: token,
|
|
1694
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
1695
|
+
functionName: "allowance",
|
|
1696
|
+
args: [owner, escrow]
|
|
1697
|
+
});
|
|
1698
|
+
if (visible >= amount) return;
|
|
1699
|
+
} catch (err) {
|
|
1700
|
+
lastReadError = err;
|
|
1701
|
+
}
|
|
1232
1702
|
await sleep(1e3);
|
|
1233
1703
|
}
|
|
1234
|
-
throw errors.allowanceNotVisible(amount);
|
|
1704
|
+
throw errors.allowanceNotVisible(amount, lastReadError);
|
|
1235
1705
|
}
|
|
1236
1706
|
return {
|
|
1237
1707
|
capabilities,
|
|
@@ -1242,8 +1712,10 @@ function createCashClient(options) {
|
|
|
1242
1712
|
return quoteRelayToBaseUsdc(input, options.relay);
|
|
1243
1713
|
},
|
|
1244
1714
|
async executeSourceQuote(quote, opts) {
|
|
1715
|
+
if (!opts.signer.account) throw errors.signerRequired("executeSourceQuote");
|
|
1245
1716
|
return executeRelayQuote(quote, opts.signer, {
|
|
1246
1717
|
...options.relay ? { relay: options.relay } : {},
|
|
1718
|
+
...opts.recipient ? { recipient: opts.recipient } : {},
|
|
1247
1719
|
...opts.onProgress ? { onProgress: opts.onProgress } : {},
|
|
1248
1720
|
...opts.disableCapabilitiesCheck !== void 0 ? { disableCapabilitiesCheck: opts.disableCapabilitiesCheck } : {}
|
|
1249
1721
|
});
|
|
@@ -1259,7 +1731,7 @@ function createCashClient(options) {
|
|
|
1259
1731
|
});
|
|
1260
1732
|
},
|
|
1261
1733
|
async cashout(input, opts) {
|
|
1262
|
-
const client = signingClient("cashout", opts);
|
|
1734
|
+
const client = await signingClient("cashout", opts);
|
|
1263
1735
|
const owner = opts.signer.account.address;
|
|
1264
1736
|
const payoutInput = validatePayout(input);
|
|
1265
1737
|
let sourceResult;
|
|
@@ -1267,6 +1739,7 @@ function createCashClient(options) {
|
|
|
1267
1739
|
if (input.source) {
|
|
1268
1740
|
const sourceSigner = opts.sourceSigner ?? (input.source.chainId === BASE_CHAIN_ID ? opts.signer : void 0);
|
|
1269
1741
|
if (!sourceSigner?.account) throw errors.signerRequired("source cashout");
|
|
1742
|
+
await assertWalletChainId(sourceSigner, input.source.chainId, "source cashout");
|
|
1270
1743
|
if (input.source.recipient !== void 0 && input.source.recipient.toLowerCase() !== owner.toLowerCase()) {
|
|
1271
1744
|
throw errors.sourceRecipientMismatch(input.source.recipient, owner);
|
|
1272
1745
|
}
|
|
@@ -1284,20 +1757,23 @@ function createCashClient(options) {
|
|
|
1284
1757
|
throw errors.amountBelowMinimum(relayQuote.outputAmount, MIN_CASHOUT_AMOUNT);
|
|
1285
1758
|
}
|
|
1286
1759
|
cashoutAmount = relayQuote.outputAmount;
|
|
1287
|
-
const depositInput2 =
|
|
1760
|
+
const depositInput2 = validateDepositInput(cashoutAmount, input, payoutInput);
|
|
1288
1761
|
const params2 = await buildDepositParams(client, depositInput2);
|
|
1289
1762
|
const escrow2 = client.escrowV2Address ?? client.escrowAddress;
|
|
1290
1763
|
await settleAllowance(client, params2.token, owner, escrow2, depositInput2.amount);
|
|
1291
1764
|
const executed = await executeRelayQuote(relayQuote.raw, sourceSigner, {
|
|
1292
1765
|
...options.relay ? { relay: options.relay } : {},
|
|
1766
|
+
recipient: owner,
|
|
1293
1767
|
...opts.onSourceProgress ? { onProgress: opts.onSourceProgress } : {},
|
|
1294
1768
|
...opts.disableSourceCapabilitiesCheck !== void 0 ? { disableCapabilitiesCheck: opts.disableSourceCapabilitiesCheck } : {}
|
|
1295
1769
|
});
|
|
1296
|
-
|
|
1770
|
+
const routedSource = {
|
|
1297
1771
|
amount: cashoutAmount,
|
|
1298
1772
|
...executed.requestId ? { requestId: executed.requestId } : {},
|
|
1299
|
-
txHashes: executed.txHashes
|
|
1773
|
+
txHashes: executed.txHashes,
|
|
1774
|
+
...executed.transactions ? { transactions: executed.transactions } : {}
|
|
1300
1775
|
};
|
|
1776
|
+
sourceResult = routedSource;
|
|
1301
1777
|
const attributedParams2 = { ...params2, txOverrides: attribution };
|
|
1302
1778
|
const send2 = async () => {
|
|
1303
1779
|
try {
|
|
@@ -1314,10 +1790,26 @@ function createCashClient(options) {
|
|
|
1314
1790
|
try {
|
|
1315
1791
|
hash2 = await send2();
|
|
1316
1792
|
} catch (err) {
|
|
1317
|
-
|
|
1793
|
+
const mapped = mapChainError("createDeposit", err, {
|
|
1794
|
+
requiredAmount: depositInput2.amount
|
|
1795
|
+
});
|
|
1796
|
+
if (isKnownPreBroadcastFailure(err, mapped)) {
|
|
1797
|
+
throw errors.sourceRouteCompletedCashoutFailed(routedSource, mapped);
|
|
1798
|
+
}
|
|
1799
|
+
throw errors.sourceCashoutSubmissionUnknown(routedSource, owner, mapped);
|
|
1800
|
+
}
|
|
1801
|
+
let receipt2;
|
|
1802
|
+
try {
|
|
1803
|
+
receipt2 = await client.publicClient.waitForTransactionReceipt({ hash: hash2 });
|
|
1804
|
+
} catch (err) {
|
|
1805
|
+
throw errors.sourceCashoutStatusUnknown(routedSource, hash2, err);
|
|
1806
|
+
}
|
|
1807
|
+
if (receipt2.status === "reverted") {
|
|
1808
|
+
throw errors.sourceRouteCompletedCashoutFailed(
|
|
1809
|
+
routedSource,
|
|
1810
|
+
errors.transactionFailed(hash2)
|
|
1811
|
+
);
|
|
1318
1812
|
}
|
|
1319
|
-
const receipt2 = await client.publicClient.waitForTransactionReceipt({ hash: hash2 });
|
|
1320
|
-
if (receipt2.status === "reverted") throw errors.transactionFailed(hash2);
|
|
1321
1813
|
const abi2 = client.escrowV2Abi ?? client.escrowAbi;
|
|
1322
1814
|
const resolved2 = resolveCashDepositId({ logs: receipt2.logs, abi: abi2 });
|
|
1323
1815
|
if (!resolved2) throw errors.depositResolutionFailed(hash2);
|
|
@@ -1331,10 +1823,10 @@ function createCashClient(options) {
|
|
|
1331
1823
|
escrowAddress: resolved2.escrowAddress,
|
|
1332
1824
|
onchainDepositId: resolved2.onchainDepositId,
|
|
1333
1825
|
order: order2,
|
|
1334
|
-
source:
|
|
1826
|
+
source: routedSource
|
|
1335
1827
|
};
|
|
1336
1828
|
}
|
|
1337
|
-
const depositInput =
|
|
1829
|
+
const depositInput = validateDepositInput(input.amount, input, payoutInput);
|
|
1338
1830
|
const params = await buildDepositParams(client, depositInput);
|
|
1339
1831
|
const escrow = client.escrowV2Address ?? client.escrowAddress;
|
|
1340
1832
|
await settleAllowance(client, params.token, owner, escrow, depositInput.amount);
|
|
@@ -1354,9 +1846,23 @@ function createCashClient(options) {
|
|
|
1354
1846
|
try {
|
|
1355
1847
|
hash = await send();
|
|
1356
1848
|
} catch (err) {
|
|
1357
|
-
|
|
1849
|
+
const mapped = mapChainError("createDeposit", err, {
|
|
1850
|
+
requiredAmount: depositInput.amount
|
|
1851
|
+
});
|
|
1852
|
+
if (isKnownPreBroadcastFailure(err, mapped)) throw mapped;
|
|
1853
|
+
throw errors.transactionSubmissionUnknown("cashout", err, {
|
|
1854
|
+
kind: "inspect-base-cashout-submission",
|
|
1855
|
+
amount: depositInput.amount.toString(),
|
|
1856
|
+
depositor: owner,
|
|
1857
|
+
txHashes: []
|
|
1858
|
+
});
|
|
1859
|
+
}
|
|
1860
|
+
let receipt;
|
|
1861
|
+
try {
|
|
1862
|
+
receipt = await client.publicClient.waitForTransactionReceipt({ hash });
|
|
1863
|
+
} catch (err) {
|
|
1864
|
+
throw errors.transactionStatusUnknown(hash, err, "cashout");
|
|
1358
1865
|
}
|
|
1359
|
-
const receipt = await client.publicClient.waitForTransactionReceipt({ hash });
|
|
1360
1866
|
if (receipt.status === "reverted") throw errors.transactionFailed(hash);
|
|
1361
1867
|
const abi = client.escrowV2Abi ?? client.escrowAbi;
|
|
1362
1868
|
const resolved = resolveCashDepositId({ logs: receipt.logs, abi });
|
|
@@ -1376,7 +1882,7 @@ function createCashClient(options) {
|
|
|
1376
1882
|
},
|
|
1377
1883
|
async prepare(input) {
|
|
1378
1884
|
if (input.source) throw errors.sourceRouteUnsupportedInPrepare();
|
|
1379
|
-
const depositInput =
|
|
1885
|
+
const depositInput = validateDepositInput(input.amount, input);
|
|
1380
1886
|
const params = await buildDepositParams(readClient, depositInput);
|
|
1381
1887
|
const { prepared } = await readClient.prepareCreateDeposit({
|
|
1382
1888
|
...params,
|
|
@@ -1415,13 +1921,46 @@ function createCashClient(options) {
|
|
|
1415
1921
|
return fetchOrder(depositId);
|
|
1416
1922
|
},
|
|
1417
1923
|
async buyer(address) {
|
|
1418
|
-
|
|
1924
|
+
let intents;
|
|
1925
|
+
try {
|
|
1926
|
+
intents = await readClient.indexer.getOwnerIntents(address, CASH_ORDER_STATUSES);
|
|
1927
|
+
} catch (err) {
|
|
1928
|
+
throw errors.indexerUnavailable("buyer profile", err);
|
|
1929
|
+
}
|
|
1419
1930
|
return deriveBuyerProfile(address, intents);
|
|
1420
1931
|
},
|
|
1421
1932
|
async orders(owner, opts = {}) {
|
|
1422
1933
|
const { inFlight = false, limit = 100 } = opts;
|
|
1423
|
-
|
|
1424
|
-
|
|
1934
|
+
let deposits;
|
|
1935
|
+
try {
|
|
1936
|
+
deposits = await readClient.indexer.getDepositsWithRelations(
|
|
1937
|
+
{ depositor: owner },
|
|
1938
|
+
{ limit }
|
|
1939
|
+
);
|
|
1940
|
+
} catch (err) {
|
|
1941
|
+
throw errors.indexerUnavailable("orders", err);
|
|
1942
|
+
}
|
|
1943
|
+
const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
1944
|
+
const derived = deposits.flatMap((deposit) => {
|
|
1945
|
+
if (deposit.token.toLowerCase() !== BASE_USDC_ADDRESS.toLowerCase()) return [];
|
|
1946
|
+
const payouts = derivePayouts(
|
|
1947
|
+
deposit.paymentMethods ?? [],
|
|
1948
|
+
deposit.currencies ?? [],
|
|
1949
|
+
catalog
|
|
1950
|
+
);
|
|
1951
|
+
if (payouts.length !== 1 || !payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0)) {
|
|
1952
|
+
return [];
|
|
1953
|
+
}
|
|
1954
|
+
return [
|
|
1955
|
+
deriveCashOrder(deposit.id, [], {
|
|
1956
|
+
...depositOrderOptions(deposit),
|
|
1957
|
+
payouts,
|
|
1958
|
+
// List rows carry no intent detail - a positive outstanding
|
|
1959
|
+
// amount is treated conservatively as a live lock.
|
|
1960
|
+
fillsIncluded: false
|
|
1961
|
+
})
|
|
1962
|
+
];
|
|
1963
|
+
}).filter((o) => o.totalAmount >= MIN_CASHOUT_AMOUNT).sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
|
|
1425
1964
|
return inFlight ? derived.filter((o) => o.isInFlight) : derived;
|
|
1426
1965
|
},
|
|
1427
1966
|
async *watch(depositId, opts = {}) {
|
|
@@ -1451,7 +1990,7 @@ function createCashClient(options) {
|
|
|
1451
1990
|
}
|
|
1452
1991
|
},
|
|
1453
1992
|
async withdraw(depositId, opts) {
|
|
1454
|
-
const client = signingClient("withdraw", opts);
|
|
1993
|
+
const client = await signingClient("withdraw", opts);
|
|
1455
1994
|
if (opts.amount !== void 0) {
|
|
1456
1995
|
const { onchainDepositId: onchainDepositId2, escrowArg: escrowArg2 } = await partialWithdrawContext(
|
|
1457
1996
|
depositId,
|
|
@@ -1549,7 +2088,7 @@ function createCashClient(options) {
|
|
|
1549
2088
|
return { txs, steps };
|
|
1550
2089
|
},
|
|
1551
2090
|
async topUp(depositId, amount, opts) {
|
|
1552
|
-
const client = signingClient("topUp", opts);
|
|
2091
|
+
const client = await signingClient("topUp", opts);
|
|
1553
2092
|
const { onchainDepositId, escrowArg } = await topUpContext(depositId, amount);
|
|
1554
2093
|
const owner = opts.signer.account.address;
|
|
1555
2094
|
const escrow = escrowArg.escrowAddress ?? client.escrowV2Address ?? client.escrowAddress;
|
|
@@ -1604,6 +2143,39 @@ function createCashClient(options) {
|
|
|
1604
2143
|
};
|
|
1605
2144
|
}
|
|
1606
2145
|
var bigintString = zod.z.string().regex(/^-?\d+$/, "expected a decimal bigint string");
|
|
2146
|
+
var nonNegativeBigintString = zod.z.string().regex(/^\d+$/, "expected a non-negative decimal bigint string");
|
|
2147
|
+
var relayTransactionJsonSchema = zod.z.object({
|
|
2148
|
+
hash: zod.z.string(),
|
|
2149
|
+
chainId: zod.z.number()
|
|
2150
|
+
});
|
|
2151
|
+
var relayTransactionsJsonSchema = zod.z.object({
|
|
2152
|
+
origin: zod.z.array(relayTransactionJsonSchema),
|
|
2153
|
+
destination: zod.z.array(relayTransactionJsonSchema)
|
|
2154
|
+
}).strict();
|
|
2155
|
+
var cashAssetJsonSchema = zod.z.object({
|
|
2156
|
+
chainId: zod.z.number(),
|
|
2157
|
+
address: zod.z.string(),
|
|
2158
|
+
symbol: zod.z.string(),
|
|
2159
|
+
decimals: zod.z.number(),
|
|
2160
|
+
name: zod.z.string().optional(),
|
|
2161
|
+
isNative: zod.z.boolean().optional()
|
|
2162
|
+
});
|
|
2163
|
+
var cashChainJsonSchema = zod.z.object({
|
|
2164
|
+
id: zod.z.number(),
|
|
2165
|
+
name: zod.z.string(),
|
|
2166
|
+
displayName: zod.z.string(),
|
|
2167
|
+
disabled: zod.z.boolean(),
|
|
2168
|
+
depositEnabled: zod.z.boolean(),
|
|
2169
|
+
blockProductionLagging: zod.z.boolean(),
|
|
2170
|
+
vmType: zod.z.string().optional(),
|
|
2171
|
+
tokens: zod.z.array(cashAssetJsonSchema)
|
|
2172
|
+
});
|
|
2173
|
+
var cashSourceCapabilitiesJsonSchema = zod.z.object({
|
|
2174
|
+
destination: cashAssetJsonSchema,
|
|
2175
|
+
chains: zod.z.array(cashChainJsonSchema),
|
|
2176
|
+
source: zod.z.literal("relay-sdk"),
|
|
2177
|
+
asOf: zod.z.number()
|
|
2178
|
+
});
|
|
1607
2179
|
var cashOrderStateSchema = zod.z.enum([
|
|
1608
2180
|
"awaiting-buyer",
|
|
1609
2181
|
"matched",
|
|
@@ -1616,18 +2188,18 @@ var intentStatusSchema = zod.z.enum(["SIGNALED", "FULFILLED", "PRUNED", "MANUALL
|
|
|
1616
2188
|
var cashFillJsonSchema = zod.z.object({
|
|
1617
2189
|
intentHash: zod.z.string(),
|
|
1618
2190
|
status: intentStatusSchema,
|
|
1619
|
-
amount:
|
|
2191
|
+
amount: nonNegativeBigintString,
|
|
1620
2192
|
buyer: zod.z.string(),
|
|
1621
2193
|
currency: zod.z.string().optional(),
|
|
1622
2194
|
currencyHash: zod.z.string().optional(),
|
|
1623
2195
|
rate: zod.z.number().optional(),
|
|
1624
|
-
conversionRate:
|
|
2196
|
+
conversionRate: nonNegativeBigintString.optional(),
|
|
1625
2197
|
fiatOwed: zod.z.number().optional(),
|
|
1626
2198
|
fiatPaid: zod.z.number().optional(),
|
|
1627
2199
|
paidCurrency: zod.z.string().optional(),
|
|
1628
2200
|
paymentId: zod.z.string().optional(),
|
|
1629
2201
|
paidAt: zod.z.number().optional(),
|
|
1630
|
-
releasedAmount:
|
|
2202
|
+
releasedAmount: nonNegativeBigintString.optional(),
|
|
1631
2203
|
fillLatencySeconds: zod.z.number().optional(),
|
|
1632
2204
|
isExpired: zod.z.boolean().optional(),
|
|
1633
2205
|
signaledAt: zod.z.number().optional(),
|
|
@@ -1666,10 +2238,10 @@ var cashOrderJsonSchema = zod.z.object({
|
|
|
1666
2238
|
depositId: zod.z.string(),
|
|
1667
2239
|
state: cashOrderStateSchema,
|
|
1668
2240
|
fills: zod.z.array(cashFillJsonSchema),
|
|
1669
|
-
totalAmount:
|
|
1670
|
-
filledAmount:
|
|
1671
|
-
pendingAmount:
|
|
1672
|
-
returnedAmount:
|
|
2241
|
+
totalAmount: nonNegativeBigintString,
|
|
2242
|
+
filledAmount: nonNegativeBigintString,
|
|
2243
|
+
pendingAmount: nonNegativeBigintString,
|
|
2244
|
+
returnedAmount: nonNegativeBigintString,
|
|
1673
2245
|
nextActions: zod.z.array(cashNextActionSchema),
|
|
1674
2246
|
primaryIntentHash: zod.z.string().optional(),
|
|
1675
2247
|
matchedAt: zod.z.number().optional(),
|
|
@@ -1684,7 +2256,7 @@ var cashOrderJsonSchema = zod.z.object({
|
|
|
1684
2256
|
var cashEstimateJsonSchema = zod.z.object({
|
|
1685
2257
|
kind: zod.z.literal("oracle-estimate"),
|
|
1686
2258
|
currency: zod.z.string(),
|
|
1687
|
-
amount:
|
|
2259
|
+
amount: nonNegativeBigintString,
|
|
1688
2260
|
rate: zod.z.number(),
|
|
1689
2261
|
receiveAmount: zod.z.number(),
|
|
1690
2262
|
asOf: zod.z.number(),
|
|
@@ -1700,7 +2272,7 @@ var cashEstimateJsonSchema = zod.z.object({
|
|
|
1700
2272
|
name: zod.z.string().optional(),
|
|
1701
2273
|
isNative: zod.z.boolean().optional()
|
|
1702
2274
|
}),
|
|
1703
|
-
inputAmount:
|
|
2275
|
+
inputAmount: nonNegativeBigintString,
|
|
1704
2276
|
relayQuote: zod.z.object({
|
|
1705
2277
|
requestId: zod.z.string().optional(),
|
|
1706
2278
|
source: zod.z.object({
|
|
@@ -1719,8 +2291,8 @@ var cashEstimateJsonSchema = zod.z.object({
|
|
|
1719
2291
|
name: zod.z.string().optional(),
|
|
1720
2292
|
isNative: zod.z.boolean().optional()
|
|
1721
2293
|
}),
|
|
1722
|
-
inputAmount:
|
|
1723
|
-
outputAmount:
|
|
2294
|
+
inputAmount: nonNegativeBigintString,
|
|
2295
|
+
outputAmount: nonNegativeBigintString,
|
|
1724
2296
|
rate: zod.z.number().optional(),
|
|
1725
2297
|
timeEstimateSeconds: zod.z.number().optional(),
|
|
1726
2298
|
fees: zod.z.unknown().optional(),
|
|
@@ -1728,7 +2300,7 @@ var cashEstimateJsonSchema = zod.z.object({
|
|
|
1728
2300
|
zod.z.object({
|
|
1729
2301
|
to: zod.z.string(),
|
|
1730
2302
|
data: zod.z.string(),
|
|
1731
|
-
value:
|
|
2303
|
+
value: nonNegativeBigintString,
|
|
1732
2304
|
chainId: zod.z.number()
|
|
1733
2305
|
})
|
|
1734
2306
|
),
|
|
@@ -1743,9 +2315,39 @@ var cashEstimateJsonSchema = zod.z.object({
|
|
|
1743
2315
|
var preparedTransactionJsonSchema = zod.z.object({
|
|
1744
2316
|
to: zod.z.string(),
|
|
1745
2317
|
data: zod.z.string(),
|
|
1746
|
-
value:
|
|
2318
|
+
value: nonNegativeBigintString,
|
|
1747
2319
|
chainId: zod.z.number()
|
|
1748
2320
|
});
|
|
2321
|
+
var relayQuoteJsonSchema = zod.z.object({
|
|
2322
|
+
requestId: zod.z.string().optional(),
|
|
2323
|
+
source: cashAssetJsonSchema,
|
|
2324
|
+
destination: cashAssetJsonSchema,
|
|
2325
|
+
inputAmount: nonNegativeBigintString,
|
|
2326
|
+
outputAmount: nonNegativeBigintString,
|
|
2327
|
+
rate: zod.z.number().optional(),
|
|
2328
|
+
timeEstimateSeconds: zod.z.number().optional(),
|
|
2329
|
+
fees: zod.z.unknown().optional(),
|
|
2330
|
+
txs: zod.z.array(preparedTransactionJsonSchema),
|
|
2331
|
+
raw: zod.z.unknown()
|
|
2332
|
+
});
|
|
2333
|
+
var relayStatusJsonSchema = zod.z.object({
|
|
2334
|
+
requestId: zod.z.string(),
|
|
2335
|
+
status: zod.z.enum(["refund", "waiting", "depositing", "failure", "pending", "submitted", "success"]),
|
|
2336
|
+
details: zod.z.string().optional(),
|
|
2337
|
+
inTxHashes: zod.z.array(zod.z.string()),
|
|
2338
|
+
txHashes: zod.z.array(zod.z.string()),
|
|
2339
|
+
updatedAt: zod.z.number().optional(),
|
|
2340
|
+
originChainId: zod.z.number().optional(),
|
|
2341
|
+
destinationChainId: zod.z.number().optional(),
|
|
2342
|
+
quoteCreatedAt: zod.z.number().optional(),
|
|
2343
|
+
raw: zod.z.unknown()
|
|
2344
|
+
});
|
|
2345
|
+
var relayExecutionResultJsonSchema = zod.z.object({
|
|
2346
|
+
requestId: zod.z.string().optional(),
|
|
2347
|
+
txHashes: zod.z.array(zod.z.string()),
|
|
2348
|
+
transactions: relayTransactionsJsonSchema.optional(),
|
|
2349
|
+
quote: zod.z.unknown()
|
|
2350
|
+
});
|
|
1749
2351
|
var cashPreparedStepJsonSchema = zod.z.object({
|
|
1750
2352
|
kind: zod.z.enum([
|
|
1751
2353
|
"approve",
|
|
@@ -1761,12 +2363,13 @@ var cashoutResultJsonSchema = zod.z.object({
|
|
|
1761
2363
|
depositId: zod.z.string(),
|
|
1762
2364
|
txHash: zod.z.string(),
|
|
1763
2365
|
escrowAddress: zod.z.string(),
|
|
1764
|
-
onchainDepositId:
|
|
2366
|
+
onchainDepositId: nonNegativeBigintString,
|
|
1765
2367
|
order: cashOrderJsonSchema,
|
|
1766
2368
|
source: zod.z.object({
|
|
1767
|
-
amount:
|
|
2369
|
+
amount: nonNegativeBigintString,
|
|
1768
2370
|
requestId: zod.z.string().optional(),
|
|
1769
|
-
txHashes: zod.z.array(zod.z.string())
|
|
2371
|
+
txHashes: zod.z.array(zod.z.string()),
|
|
2372
|
+
transactions: relayTransactionsJsonSchema.optional()
|
|
1770
2373
|
}).optional()
|
|
1771
2374
|
});
|
|
1772
2375
|
var prepareResultJsonSchema = zod.z.object({
|
|
@@ -1796,39 +2399,7 @@ var cashCapabilitiesJsonSchema = zod.z.object({
|
|
|
1796
2399
|
chainId: zod.z.number(),
|
|
1797
2400
|
token: zod.z.object({ address: zod.z.string(), symbol: zod.z.literal("USDC"), decimals: zod.z.number() })
|
|
1798
2401
|
}),
|
|
1799
|
-
relay:
|
|
1800
|
-
destination: zod.z.object({
|
|
1801
|
-
chainId: zod.z.number(),
|
|
1802
|
-
address: zod.z.string(),
|
|
1803
|
-
symbol: zod.z.string(),
|
|
1804
|
-
decimals: zod.z.number(),
|
|
1805
|
-
name: zod.z.string().optional(),
|
|
1806
|
-
isNative: zod.z.boolean().optional()
|
|
1807
|
-
}),
|
|
1808
|
-
chains: zod.z.array(
|
|
1809
|
-
zod.z.object({
|
|
1810
|
-
id: zod.z.number(),
|
|
1811
|
-
name: zod.z.string(),
|
|
1812
|
-
displayName: zod.z.string(),
|
|
1813
|
-
disabled: zod.z.boolean(),
|
|
1814
|
-
depositEnabled: zod.z.boolean(),
|
|
1815
|
-
blockProductionLagging: zod.z.boolean(),
|
|
1816
|
-
vmType: zod.z.string().optional(),
|
|
1817
|
-
tokens: zod.z.array(
|
|
1818
|
-
zod.z.object({
|
|
1819
|
-
chainId: zod.z.number(),
|
|
1820
|
-
address: zod.z.string(),
|
|
1821
|
-
symbol: zod.z.string(),
|
|
1822
|
-
decimals: zod.z.number(),
|
|
1823
|
-
name: zod.z.string().optional(),
|
|
1824
|
-
isNative: zod.z.boolean().optional()
|
|
1825
|
-
})
|
|
1826
|
-
)
|
|
1827
|
-
})
|
|
1828
|
-
),
|
|
1829
|
-
source: zod.z.literal("relay-sdk"),
|
|
1830
|
-
asOf: zod.z.number()
|
|
1831
|
-
}).optional()
|
|
2402
|
+
relay: cashSourceCapabilitiesJsonSchema.optional()
|
|
1832
2403
|
}),
|
|
1833
2404
|
platforms: zod.z.array(
|
|
1834
2405
|
zod.z.object({
|
|
@@ -1839,15 +2410,98 @@ var cashCapabilitiesJsonSchema = zod.z.object({
|
|
|
1839
2410
|
})
|
|
1840
2411
|
),
|
|
1841
2412
|
currencies: zod.z.array(zod.z.string()),
|
|
1842
|
-
amount: zod.z.object({
|
|
2413
|
+
amount: zod.z.object({
|
|
2414
|
+
min: nonNegativeBigintString,
|
|
2415
|
+
recommendedMin: nonNegativeBigintString,
|
|
2416
|
+
max: zod.z.null()
|
|
2417
|
+
}),
|
|
1843
2418
|
pricing: zod.z.object({ kind: zod.z.literal("oracle-market-rate"), spreadBps: zod.z.literal(0) })
|
|
1844
2419
|
});
|
|
2420
|
+
function defineCashErrorCodes(codes) {
|
|
2421
|
+
return codes;
|
|
2422
|
+
}
|
|
2423
|
+
var CASH_ERROR_CODES = defineCashErrorCodes([
|
|
2424
|
+
"ORACLE_UNSUPPORTED_CURRENCY",
|
|
2425
|
+
"ORACLE_READ_FAILED",
|
|
2426
|
+
"UNSUPPORTED_PLATFORM",
|
|
2427
|
+
"UNSUPPORTED_PLATFORM_CURRENCY",
|
|
2428
|
+
"AMOUNT_BELOW_MINIMUM",
|
|
2429
|
+
"INVALID_INTENT_AMOUNT_RANGE",
|
|
2430
|
+
"ACTIVE_INTENT_BLOCKS_WITHDRAWAL",
|
|
2431
|
+
"NOTHING_TO_WITHDRAW",
|
|
2432
|
+
"INSUFFICIENT_AVAILABLE_FUNDS",
|
|
2433
|
+
"INSUFFICIENT_TOKEN_BALANCE",
|
|
2434
|
+
"ORDER_NOT_ACTIVE",
|
|
2435
|
+
"INVALID_DEPOSIT_ID",
|
|
2436
|
+
"ESCROW_PAUSED",
|
|
2437
|
+
"INDEXER_LAG",
|
|
2438
|
+
"INDEXER_UNAVAILABLE",
|
|
2439
|
+
"ORDER_NOT_FOUND",
|
|
2440
|
+
"PAYEE_REGISTRATION_FAILED",
|
|
2441
|
+
"PAYEE_VERIFICATION_REQUIRED",
|
|
2442
|
+
"SOURCE_ROUTE_UNSUPPORTED_IN_PREPARE",
|
|
2443
|
+
"SOURCE_RECIPIENT_MISMATCH",
|
|
2444
|
+
"SOURCE_CAPABILITIES_FAILED",
|
|
2445
|
+
"SOURCE_QUOTE_FAILED",
|
|
2446
|
+
"SOURCE_EXECUTION_FAILED",
|
|
2447
|
+
"SOURCE_STATUS_FAILED",
|
|
2448
|
+
"SOURCE_ROUTE_COMPLETED_CASHOUT_FAILED",
|
|
2449
|
+
"SOURCE_CASHOUT_SUBMISSION_UNKNOWN",
|
|
2450
|
+
"SOURCE_CASHOUT_STATUS_UNKNOWN",
|
|
2451
|
+
"DEPOSIT_RESOLUTION_FAILED",
|
|
2452
|
+
"ALLOWANCE_NOT_VISIBLE",
|
|
2453
|
+
"SIGNER_REQUIRED",
|
|
2454
|
+
"SIGNER_CHAIN_MISMATCH",
|
|
2455
|
+
"SIGNER_CHAIN_UNAVAILABLE",
|
|
2456
|
+
"WATCH_TIMEOUT",
|
|
2457
|
+
"TRANSACTION_FAILED",
|
|
2458
|
+
"TRANSACTION_SUBMISSION_UNKNOWN",
|
|
2459
|
+
"TRANSACTION_STATUS_UNKNOWN"
|
|
2460
|
+
]);
|
|
2461
|
+
var cashSourceRecoveryJsonShape = {
|
|
2462
|
+
amount: nonNegativeBigintString,
|
|
2463
|
+
requestId: zod.z.string().optional(),
|
|
2464
|
+
txHashes: zod.z.array(zod.z.string()),
|
|
2465
|
+
transactions: relayTransactionsJsonSchema.optional()
|
|
2466
|
+
};
|
|
2467
|
+
var cashErrorRecoveryJsonSchema = zod.z.discriminatedUnion("kind", [
|
|
2468
|
+
zod.z.object({
|
|
2469
|
+
...cashSourceRecoveryJsonShape,
|
|
2470
|
+
kind: zod.z.literal("retry-base-usdc-cashout")
|
|
2471
|
+
}).strict(),
|
|
2472
|
+
zod.z.object({
|
|
2473
|
+
...cashSourceRecoveryJsonShape,
|
|
2474
|
+
kind: zod.z.literal("inspect-base-cashout-transaction"),
|
|
2475
|
+
depositTxHash: zod.z.string()
|
|
2476
|
+
}).strict(),
|
|
2477
|
+
zod.z.object({
|
|
2478
|
+
...cashSourceRecoveryJsonShape,
|
|
2479
|
+
kind: zod.z.literal("inspect-base-cashout-submission"),
|
|
2480
|
+
depositor: zod.z.string()
|
|
2481
|
+
}).strict(),
|
|
2482
|
+
zod.z.object({
|
|
2483
|
+
kind: zod.z.literal("inspect-relay-route"),
|
|
2484
|
+
requestId: zod.z.string().optional(),
|
|
2485
|
+
txHashes: zod.z.array(zod.z.string()),
|
|
2486
|
+
transactions: relayTransactionsJsonSchema.optional()
|
|
2487
|
+
}).strict(),
|
|
2488
|
+
zod.z.object({
|
|
2489
|
+
kind: zod.z.literal("inspect-base-operation-submission"),
|
|
2490
|
+
operation: zod.z.string()
|
|
2491
|
+
}).strict(),
|
|
2492
|
+
zod.z.object({
|
|
2493
|
+
kind: zod.z.literal("inspect-base-transaction"),
|
|
2494
|
+
transactionHash: zod.z.string(),
|
|
2495
|
+
operation: zod.z.string()
|
|
2496
|
+
}).strict()
|
|
2497
|
+
]);
|
|
1845
2498
|
var cashErrorJsonSchema = zod.z.object({
|
|
1846
|
-
code: zod.z.
|
|
2499
|
+
code: zod.z.enum(CASH_ERROR_CODES),
|
|
1847
2500
|
message: zod.z.string(),
|
|
1848
2501
|
retryable: zod.z.boolean(),
|
|
1849
|
-
remediation: zod.z.string()
|
|
1850
|
-
|
|
2502
|
+
remediation: zod.z.string(),
|
|
2503
|
+
recovery: cashErrorRecoveryJsonSchema.optional()
|
|
2504
|
+
}).strict();
|
|
1851
2505
|
|
|
1852
2506
|
// src/codecs/json.ts
|
|
1853
2507
|
function omitUndefined(obj) {
|
|
@@ -1878,35 +2532,38 @@ function fillToJson(fill) {
|
|
|
1878
2532
|
});
|
|
1879
2533
|
}
|
|
1880
2534
|
function fillFromJson(json) {
|
|
2535
|
+
const parsed = cashFillJsonSchema.parse(json);
|
|
1881
2536
|
return omitUndefined({
|
|
1882
|
-
...
|
|
1883
|
-
amount: BigInt(
|
|
1884
|
-
conversionRate:
|
|
1885
|
-
releasedAmount:
|
|
2537
|
+
...parsed,
|
|
2538
|
+
amount: BigInt(parsed.amount),
|
|
2539
|
+
conversionRate: parsed.conversionRate !== void 0 ? BigInt(parsed.conversionRate) : void 0,
|
|
2540
|
+
releasedAmount: parsed.releasedAmount !== void 0 ? BigInt(parsed.releasedAmount) : void 0
|
|
1886
2541
|
});
|
|
1887
2542
|
}
|
|
1888
2543
|
function orderToJson(order) {
|
|
1889
|
-
return
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2544
|
+
return cashOrderJsonSchema.parse(
|
|
2545
|
+
omitUndefined({
|
|
2546
|
+
depositId: order.depositId,
|
|
2547
|
+
state: order.state,
|
|
2548
|
+
fills: order.fills.map(fillToJson),
|
|
2549
|
+
totalAmount: order.totalAmount.toString(),
|
|
2550
|
+
filledAmount: order.filledAmount.toString(),
|
|
2551
|
+
pendingAmount: order.pendingAmount.toString(),
|
|
2552
|
+
returnedAmount: order.returnedAmount.toString(),
|
|
2553
|
+
nextActions: order.nextActions,
|
|
2554
|
+
primaryIntentHash: order.primaryIntentHash,
|
|
2555
|
+
matchedAt: order.matchedAt,
|
|
2556
|
+
deliveredAt: order.deliveredAt,
|
|
2557
|
+
updatedAt: order.updatedAt,
|
|
2558
|
+
intentCount: order.intentCount,
|
|
2559
|
+
payouts: order.payouts?.map(
|
|
2560
|
+
(p) => omitUndefined({ ...p, pricing: omitUndefined({ ...p.pricing }) })
|
|
2561
|
+
),
|
|
2562
|
+
successRateBps: order.successRateBps,
|
|
2563
|
+
isInFlight: order.isInFlight,
|
|
2564
|
+
withdrawn: order.withdrawn
|
|
2565
|
+
})
|
|
2566
|
+
);
|
|
1910
2567
|
}
|
|
1911
2568
|
function orderFromJson(json) {
|
|
1912
2569
|
const parsed = cashOrderJsonSchema.parse(json);
|
|
@@ -1932,6 +2589,7 @@ function estimateToJson(estimate) {
|
|
|
1932
2589
|
inputAmount: estimate.source.relayQuote.inputAmount.toString(),
|
|
1933
2590
|
outputAmount: estimate.source.relayQuote.outputAmount.toString(),
|
|
1934
2591
|
txs: estimate.source.relayQuote.txs.map(preparedTxToJson),
|
|
2592
|
+
...estimate.source.relayQuote.fees !== void 0 ? { fees: sanitizeRelayValue(estimate.source.relayQuote.fees) } : {},
|
|
1935
2593
|
raw: sanitizeRelayQuoteRaw(estimate.source.relayQuote.raw)
|
|
1936
2594
|
}
|
|
1937
2595
|
} : void 0
|
|
@@ -1950,11 +2608,108 @@ function estimateFromJson(json) {
|
|
|
1950
2608
|
...parsed.source.relayQuote,
|
|
1951
2609
|
inputAmount: BigInt(parsed.source.relayQuote.inputAmount),
|
|
1952
2610
|
outputAmount: BigInt(parsed.source.relayQuote.outputAmount),
|
|
1953
|
-
txs: parsed.source.relayQuote.txs.map(preparedTxFromJson)
|
|
2611
|
+
txs: parsed.source.relayQuote.txs.map(preparedTxFromJson),
|
|
2612
|
+
...parsed.source.relayQuote.fees !== void 0 ? { fees: restoreRelayValue(parsed.source.relayQuote.fees) } : {},
|
|
2613
|
+
raw: restoreRelayQuoteRaw(parsed.source.relayQuote.raw)
|
|
1954
2614
|
}
|
|
1955
2615
|
} : void 0
|
|
1956
2616
|
});
|
|
1957
2617
|
}
|
|
2618
|
+
function cashAssetFromJson(asset) {
|
|
2619
|
+
return {
|
|
2620
|
+
chainId: asset.chainId,
|
|
2621
|
+
address: asset.address,
|
|
2622
|
+
symbol: asset.symbol,
|
|
2623
|
+
decimals: asset.decimals,
|
|
2624
|
+
...asset.name !== void 0 ? { name: asset.name } : {},
|
|
2625
|
+
...asset.isNative !== void 0 ? { isNative: asset.isNative } : {}
|
|
2626
|
+
};
|
|
2627
|
+
}
|
|
2628
|
+
function relayQuoteToJson(quote) {
|
|
2629
|
+
return relayQuoteJsonSchema.parse({
|
|
2630
|
+
...quote.requestId !== void 0 ? { requestId: quote.requestId } : {},
|
|
2631
|
+
source: quote.source,
|
|
2632
|
+
destination: quote.destination,
|
|
2633
|
+
inputAmount: quote.inputAmount.toString(),
|
|
2634
|
+
outputAmount: quote.outputAmount.toString(),
|
|
2635
|
+
...quote.rate !== void 0 ? { rate: quote.rate } : {},
|
|
2636
|
+
...quote.timeEstimateSeconds !== void 0 ? { timeEstimateSeconds: quote.timeEstimateSeconds } : {},
|
|
2637
|
+
...quote.fees !== void 0 ? { fees: sanitizeRelayValue(quote.fees) } : {},
|
|
2638
|
+
txs: quote.txs.map(preparedTxToJson),
|
|
2639
|
+
raw: sanitizeRelayQuoteRaw(quote.raw)
|
|
2640
|
+
});
|
|
2641
|
+
}
|
|
2642
|
+
function relayQuoteFromJson(json) {
|
|
2643
|
+
const parsed = relayQuoteJsonSchema.parse(json);
|
|
2644
|
+
return {
|
|
2645
|
+
...parsed.requestId !== void 0 ? { requestId: parsed.requestId } : {},
|
|
2646
|
+
source: cashAssetFromJson(parsed.source),
|
|
2647
|
+
destination: cashAssetFromJson(parsed.destination),
|
|
2648
|
+
inputAmount: BigInt(parsed.inputAmount),
|
|
2649
|
+
outputAmount: BigInt(parsed.outputAmount),
|
|
2650
|
+
...parsed.rate !== void 0 ? { rate: parsed.rate } : {},
|
|
2651
|
+
...parsed.timeEstimateSeconds !== void 0 ? { timeEstimateSeconds: parsed.timeEstimateSeconds } : {},
|
|
2652
|
+
...parsed.fees !== void 0 ? { fees: restoreRelayValue(parsed.fees) } : {},
|
|
2653
|
+
txs: parsed.txs.map(preparedTxFromJson),
|
|
2654
|
+
raw: restoreRelayQuoteRaw(parsed.raw)
|
|
2655
|
+
};
|
|
2656
|
+
}
|
|
2657
|
+
function sourceCapabilitiesToJson(capabilities) {
|
|
2658
|
+
return cashSourceCapabilitiesJsonSchema.parse(capabilities);
|
|
2659
|
+
}
|
|
2660
|
+
function sourceCapabilitiesFromJson(json) {
|
|
2661
|
+
const parsed = cashSourceCapabilitiesJsonSchema.parse(json);
|
|
2662
|
+
return {
|
|
2663
|
+
destination: cashAssetFromJson(parsed.destination),
|
|
2664
|
+
chains: parsed.chains.map((chain) => ({
|
|
2665
|
+
id: chain.id,
|
|
2666
|
+
name: chain.name,
|
|
2667
|
+
displayName: chain.displayName,
|
|
2668
|
+
disabled: chain.disabled,
|
|
2669
|
+
depositEnabled: chain.depositEnabled,
|
|
2670
|
+
blockProductionLagging: chain.blockProductionLagging,
|
|
2671
|
+
...chain.vmType !== void 0 ? { vmType: chain.vmType } : {},
|
|
2672
|
+
tokens: chain.tokens.map(cashAssetFromJson)
|
|
2673
|
+
})),
|
|
2674
|
+
source: parsed.source,
|
|
2675
|
+
asOf: parsed.asOf
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
function relayStatusToJson(status) {
|
|
2679
|
+
return relayStatusJsonSchema.parse({ ...status, raw: sanitizeRelayValue(status.raw) });
|
|
2680
|
+
}
|
|
2681
|
+
function relayStatusFromJson(json) {
|
|
2682
|
+
const parsed = relayStatusJsonSchema.parse(json);
|
|
2683
|
+
return {
|
|
2684
|
+
requestId: parsed.requestId,
|
|
2685
|
+
status: parsed.status,
|
|
2686
|
+
...parsed.details !== void 0 ? { details: parsed.details } : {},
|
|
2687
|
+
inTxHashes: parsed.inTxHashes,
|
|
2688
|
+
txHashes: parsed.txHashes,
|
|
2689
|
+
...parsed.updatedAt !== void 0 ? { updatedAt: parsed.updatedAt } : {},
|
|
2690
|
+
...parsed.originChainId !== void 0 ? { originChainId: parsed.originChainId } : {},
|
|
2691
|
+
...parsed.destinationChainId !== void 0 ? { destinationChainId: parsed.destinationChainId } : {},
|
|
2692
|
+
...parsed.quoteCreatedAt !== void 0 ? { quoteCreatedAt: parsed.quoteCreatedAt } : {},
|
|
2693
|
+
raw: restoreRelayValue(parsed.raw)
|
|
2694
|
+
};
|
|
2695
|
+
}
|
|
2696
|
+
function relayExecutionResultToJson(result) {
|
|
2697
|
+
return relayExecutionResultJsonSchema.parse({
|
|
2698
|
+
...result.requestId !== void 0 ? { requestId: result.requestId } : {},
|
|
2699
|
+
txHashes: result.txHashes,
|
|
2700
|
+
...result.transactions !== void 0 ? { transactions: result.transactions } : {},
|
|
2701
|
+
quote: sanitizeRelayQuoteRaw(result.quote)
|
|
2702
|
+
});
|
|
2703
|
+
}
|
|
2704
|
+
function relayExecutionResultFromJson(json) {
|
|
2705
|
+
const parsed = relayExecutionResultJsonSchema.parse(json);
|
|
2706
|
+
return {
|
|
2707
|
+
...parsed.requestId !== void 0 ? { requestId: parsed.requestId } : {},
|
|
2708
|
+
txHashes: parsed.txHashes,
|
|
2709
|
+
...parsed.transactions !== void 0 ? { transactions: parsed.transactions } : {},
|
|
2710
|
+
quote: restoreRelayQuoteRaw(parsed.quote)
|
|
2711
|
+
};
|
|
2712
|
+
}
|
|
1958
2713
|
function preparedTxToJson(tx) {
|
|
1959
2714
|
return { to: tx.to, data: tx.data, value: tx.value.toString(), chainId: tx.chainId };
|
|
1960
2715
|
}
|
|
@@ -2073,6 +2828,69 @@ function capabilitiesFromJson(json) {
|
|
|
2073
2828
|
}
|
|
2074
2829
|
};
|
|
2075
2830
|
}
|
|
2831
|
+
function cashErrorToJson(error) {
|
|
2832
|
+
return cashErrorJsonSchema.parse({
|
|
2833
|
+
code: error.code,
|
|
2834
|
+
message: error.message,
|
|
2835
|
+
retryable: error.retryable,
|
|
2836
|
+
remediation: error.remediation,
|
|
2837
|
+
...error.recovery ? { recovery: error.recovery } : {}
|
|
2838
|
+
});
|
|
2839
|
+
}
|
|
2840
|
+
function cashErrorFromJson(json) {
|
|
2841
|
+
const parsed = cashErrorJsonSchema.parse(json);
|
|
2842
|
+
let recovery;
|
|
2843
|
+
if (parsed.recovery) {
|
|
2844
|
+
if (parsed.recovery.kind === "inspect-base-transaction") {
|
|
2845
|
+
recovery = {
|
|
2846
|
+
kind: parsed.recovery.kind,
|
|
2847
|
+
transactionHash: parsed.recovery.transactionHash,
|
|
2848
|
+
operation: parsed.recovery.operation
|
|
2849
|
+
};
|
|
2850
|
+
} else if (parsed.recovery.kind === "inspect-base-operation-submission") {
|
|
2851
|
+
recovery = {
|
|
2852
|
+
kind: parsed.recovery.kind,
|
|
2853
|
+
operation: parsed.recovery.operation
|
|
2854
|
+
};
|
|
2855
|
+
} else if (parsed.recovery.kind === "inspect-relay-route") {
|
|
2856
|
+
recovery = {
|
|
2857
|
+
kind: parsed.recovery.kind,
|
|
2858
|
+
txHashes: parsed.recovery.txHashes,
|
|
2859
|
+
...parsed.recovery.requestId !== void 0 ? { requestId: parsed.recovery.requestId } : {},
|
|
2860
|
+
...parsed.recovery.transactions !== void 0 ? { transactions: parsed.recovery.transactions } : {}
|
|
2861
|
+
};
|
|
2862
|
+
} else {
|
|
2863
|
+
const common = {
|
|
2864
|
+
amount: parsed.recovery.amount,
|
|
2865
|
+
txHashes: parsed.recovery.txHashes,
|
|
2866
|
+
...parsed.recovery.requestId !== void 0 ? { requestId: parsed.recovery.requestId } : {},
|
|
2867
|
+
...parsed.recovery.transactions !== void 0 ? { transactions: parsed.recovery.transactions } : {}
|
|
2868
|
+
};
|
|
2869
|
+
if (parsed.recovery.kind === "retry-base-usdc-cashout") {
|
|
2870
|
+
recovery = { ...common, kind: parsed.recovery.kind };
|
|
2871
|
+
} else if (parsed.recovery.kind === "inspect-base-cashout-submission") {
|
|
2872
|
+
recovery = {
|
|
2873
|
+
...common,
|
|
2874
|
+
kind: parsed.recovery.kind,
|
|
2875
|
+
depositor: parsed.recovery.depositor
|
|
2876
|
+
};
|
|
2877
|
+
} else {
|
|
2878
|
+
recovery = {
|
|
2879
|
+
...common,
|
|
2880
|
+
kind: parsed.recovery.kind,
|
|
2881
|
+
depositTxHash: parsed.recovery.depositTxHash
|
|
2882
|
+
};
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
return new CashError({
|
|
2887
|
+
code: parsed.code,
|
|
2888
|
+
message: parsed.message,
|
|
2889
|
+
retryable: parsed.retryable,
|
|
2890
|
+
remediation: parsed.remediation,
|
|
2891
|
+
...recovery ? { recovery } : {}
|
|
2892
|
+
});
|
|
2893
|
+
}
|
|
2076
2894
|
|
|
2077
2895
|
exports.BASE_CHAIN_ID = BASE_CHAIN_ID;
|
|
2078
2896
|
exports.BASE_USDC_ADDRESS = BASE_USDC_ADDRESS;
|
|
@@ -2095,9 +2913,14 @@ exports.buyerProfileFromJson = buyerProfileFromJson;
|
|
|
2095
2913
|
exports.buyerProfileToJson = buyerProfileToJson;
|
|
2096
2914
|
exports.capabilitiesFromJson = capabilitiesFromJson;
|
|
2097
2915
|
exports.capabilitiesToJson = capabilitiesToJson;
|
|
2916
|
+
exports.cashAssetJsonSchema = cashAssetJsonSchema;
|
|
2098
2917
|
exports.cashBuyerProfileJsonSchema = cashBuyerProfileJsonSchema;
|
|
2099
2918
|
exports.cashCapabilitiesJsonSchema = cashCapabilitiesJsonSchema;
|
|
2919
|
+
exports.cashChainJsonSchema = cashChainJsonSchema;
|
|
2920
|
+
exports.cashErrorFromJson = cashErrorFromJson;
|
|
2100
2921
|
exports.cashErrorJsonSchema = cashErrorJsonSchema;
|
|
2922
|
+
exports.cashErrorRecoveryJsonSchema = cashErrorRecoveryJsonSchema;
|
|
2923
|
+
exports.cashErrorToJson = cashErrorToJson;
|
|
2101
2924
|
exports.cashEstimateJsonSchema = cashEstimateJsonSchema;
|
|
2102
2925
|
exports.cashFillJsonSchema = cashFillJsonSchema;
|
|
2103
2926
|
exports.cashNextActionSchema = cashNextActionSchema;
|
|
@@ -2106,6 +2929,7 @@ exports.cashOrderStateSchema = cashOrderStateSchema;
|
|
|
2106
2929
|
exports.cashPayoutInfoJsonSchema = cashPayoutInfoJsonSchema;
|
|
2107
2930
|
exports.cashPayoutPricingJsonSchema = cashPayoutPricingJsonSchema;
|
|
2108
2931
|
exports.cashPreparedStepJsonSchema = cashPreparedStepJsonSchema;
|
|
2932
|
+
exports.cashSourceCapabilitiesJsonSchema = cashSourceCapabilitiesJsonSchema;
|
|
2109
2933
|
exports.cashoutResultFromJson = cashoutResultFromJson;
|
|
2110
2934
|
exports.cashoutResultJsonSchema = cashoutResultJsonSchema;
|
|
2111
2935
|
exports.cashoutResultToJson = cashoutResultToJson;
|
|
@@ -2127,6 +2951,7 @@ exports.intentStatusSchema = intentStatusSchema;
|
|
|
2127
2951
|
exports.isCashError = isCashError;
|
|
2128
2952
|
exports.isFillLive = isFillLive;
|
|
2129
2953
|
exports.isMarketRateSupported = isMarketRateSupported;
|
|
2954
|
+
exports.nonNegativeBigintString = nonNegativeBigintString;
|
|
2130
2955
|
exports.orderFromJson = orderFromJson;
|
|
2131
2956
|
exports.orderToJson = orderToJson;
|
|
2132
2957
|
exports.parseCompositeDepositId = parseCompositeDepositId;
|
|
@@ -2140,7 +2965,20 @@ exports.preparedTransactionJsonSchema = preparedTransactionJsonSchema;
|
|
|
2140
2965
|
exports.preparedTxFromJson = preparedTxFromJson;
|
|
2141
2966
|
exports.preparedTxToJson = preparedTxToJson;
|
|
2142
2967
|
exports.rateToNumber = rateToNumber;
|
|
2968
|
+
exports.relayExecutionResultFromJson = relayExecutionResultFromJson;
|
|
2969
|
+
exports.relayExecutionResultJsonSchema = relayExecutionResultJsonSchema;
|
|
2970
|
+
exports.relayExecutionResultToJson = relayExecutionResultToJson;
|
|
2971
|
+
exports.relayQuoteFromJson = relayQuoteFromJson;
|
|
2972
|
+
exports.relayQuoteJsonSchema = relayQuoteJsonSchema;
|
|
2973
|
+
exports.relayQuoteToJson = relayQuoteToJson;
|
|
2974
|
+
exports.relayStatusFromJson = relayStatusFromJson;
|
|
2975
|
+
exports.relayStatusJsonSchema = relayStatusJsonSchema;
|
|
2976
|
+
exports.relayStatusToJson = relayStatusToJson;
|
|
2977
|
+
exports.relayTransactionJsonSchema = relayTransactionJsonSchema;
|
|
2978
|
+
exports.relayTransactionsJsonSchema = relayTransactionsJsonSchema;
|
|
2143
2979
|
exports.resolveCashDepositId = resolveCashDepositId;
|
|
2980
|
+
exports.sourceCapabilitiesFromJson = sourceCapabilitiesFromJson;
|
|
2981
|
+
exports.sourceCapabilitiesToJson = sourceCapabilitiesToJson;
|
|
2144
2982
|
exports.topUpResultFromJson = topUpResultFromJson;
|
|
2145
2983
|
exports.topUpResultJsonSchema = topUpResultJsonSchema;
|
|
2146
2984
|
exports.topUpResultToJson = topUpResultToJson;
|
|
@@ -2149,5 +2987,3 @@ exports.withExplain = withExplain;
|
|
|
2149
2987
|
exports.withdrawResultFromJson = withdrawResultFromJson;
|
|
2150
2988
|
exports.withdrawResultJsonSchema = withdrawResultJsonSchema;
|
|
2151
2989
|
exports.withdrawResultToJson = withdrawResultToJson;
|
|
2152
|
-
//# sourceMappingURL=index.cjs.map
|
|
2153
|
-
//# sourceMappingURL=index.cjs.map
|