@axonfi/sdk 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/index.cjs +89 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -37
- package/dist/index.d.ts +40 -37
- package/dist/index.js +89 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -499,10 +499,10 @@ interface PayInput {
|
|
|
499
499
|
* Signed execute intent for DeFi protocol interactions.
|
|
500
500
|
*
|
|
501
501
|
* The bot signs this struct using EIP-712. The relayer submits it to
|
|
502
|
-
* executeProtocol() on-chain. The contract approves `
|
|
503
|
-
* calls it with `callData`, then revokes the
|
|
502
|
+
* executeProtocol() on-chain. The contract approves `tokens` to `protocol`,
|
|
503
|
+
* calls it with `callData`, then revokes the approvals.
|
|
504
504
|
*
|
|
505
|
-
* TypeHash: keccak256("ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address
|
|
505
|
+
* TypeHash: keccak256("ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address[] tokens,uint256[] amounts,uint256 value,uint256 deadline,bytes32 ref)")
|
|
506
506
|
*/
|
|
507
507
|
interface ExecuteIntent {
|
|
508
508
|
/** Bot's own address. Must be registered in the vault. */
|
|
@@ -511,16 +511,12 @@ interface ExecuteIntent {
|
|
|
511
511
|
protocol: Address;
|
|
512
512
|
/** keccak256 of the callData bytes. Verified by relayer before submission. */
|
|
513
513
|
calldataHash: Hex;
|
|
514
|
-
/**
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
|
|
514
|
+
/** Tokens to approve to the protocol (e.g. [USDC, WETH] for GMX). Empty = no approvals. */
|
|
515
|
+
tokens: Address[];
|
|
516
|
+
/** Approval amounts for each token (must match tokens length). */
|
|
517
|
+
amounts: bigint[];
|
|
518
518
|
/** Native ETH to send with the protocol call (e.g. WETH.deposit, Lido.submit). 0 = no ETH. */
|
|
519
519
|
value: bigint;
|
|
520
|
-
/** Additional tokens to approve to the SAME protocol (e.g. WETH for GMX execution fee). Bot-signed. */
|
|
521
|
-
extraTokens: Address[];
|
|
522
|
-
/** Approval amounts for each extra token. Must match extraTokens length. */
|
|
523
|
-
extraAmounts: bigint[];
|
|
524
520
|
/** Unix timestamp after which this intent is invalid. */
|
|
525
521
|
deadline: bigint;
|
|
526
522
|
/** keccak256 of the off-chain memo. Full memo text stored by relayer. */
|
|
@@ -555,16 +551,19 @@ interface ExecuteInput {
|
|
|
555
551
|
protocol: Address;
|
|
556
552
|
/** The actual calldata bytes to send to the protocol. */
|
|
557
553
|
callData: Hex;
|
|
558
|
-
/**
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
554
|
+
/**
|
|
555
|
+
* Tokens to approve to the protocol. Each entry is an address, Token enum, or bare symbol string.
|
|
556
|
+
* Example: ['USDC'] for single token, ['USDC', 'WETH'] for multi-token (GMX).
|
|
557
|
+
* Empty or omitted = no token approvals (e.g. closing a position).
|
|
558
|
+
*/
|
|
559
|
+
tokens?: TokenInput[];
|
|
560
|
+
/**
|
|
561
|
+
* Approval amounts for each token. Must match tokens length.
|
|
562
|
+
* Each entry: bigint (raw base units), number (human-readable), or string (human-readable).
|
|
563
|
+
*/
|
|
564
|
+
amounts?: AmountInput[];
|
|
562
565
|
/** Native ETH to send with the call (wei). Optional, defaults to 0. Used for payable functions like WETH.deposit() or Lido.submit(). */
|
|
563
566
|
value?: bigint;
|
|
564
|
-
/** Additional tokens to approve to the protocol (e.g. WETH for GMX execution fee). Bot signs these. */
|
|
565
|
-
extraTokens?: Address[];
|
|
566
|
-
/** Approval amounts for each extra token (raw base units). Must match extraTokens length. */
|
|
567
|
-
extraAmounts?: bigint[];
|
|
568
567
|
/** Human-readable description. Gets keccak256-hashed to ref. */
|
|
569
568
|
memo?: string;
|
|
570
569
|
/**
|
|
@@ -580,10 +579,6 @@ interface ExecuteInput {
|
|
|
580
579
|
deadline?: bigint;
|
|
581
580
|
/** Arbitrary metadata stored off-chain. */
|
|
582
581
|
metadata?: Record<string, string>;
|
|
583
|
-
/** Source token for pre-swap — an address, Token enum, or bare symbol string. */
|
|
584
|
-
fromToken?: TokenInput;
|
|
585
|
-
/** Max input for pre-swap: bigint (raw), number (human), or string (human). */
|
|
586
|
-
maxFromAmount?: AmountInput;
|
|
587
582
|
}
|
|
588
583
|
/**
|
|
589
584
|
* Input for AxonClient.swap(). Signs a SwapIntent and submits to
|
|
@@ -621,6 +616,13 @@ interface PaymentResult {
|
|
|
621
616
|
estimatedResolutionMs?: number;
|
|
622
617
|
/** Rejection reason. Present when status === 'rejected'. */
|
|
623
618
|
reason?: string;
|
|
619
|
+
/**
|
|
620
|
+
* Machine-readable error code. Present when status === 'rejected'.
|
|
621
|
+
* Notable values:
|
|
622
|
+
* - `'SWAP_REQUIRED'` — vault lacks the payment token. The SDK auto-handles
|
|
623
|
+
* this by signing a SwapIntent and resubmitting.
|
|
624
|
+
*/
|
|
625
|
+
errorCode?: string;
|
|
624
626
|
}
|
|
625
627
|
/** High-level vault info returned by AxonClient.getVaultInfo(). */
|
|
626
628
|
interface VaultInfo {
|
|
@@ -798,6 +800,10 @@ declare class AxonClient {
|
|
|
798
800
|
* - `"approved"`: fast path — txHash available immediately
|
|
799
801
|
* - `"pending_review"`: AI scan or human review in progress — poll for status
|
|
800
802
|
* - `"rejected"`: payment was rejected — reason field explains why
|
|
803
|
+
*
|
|
804
|
+
* If the vault doesn't hold enough of the payment token, the relayer returns
|
|
805
|
+
* `errorCode: 'SWAP_REQUIRED'`. The SDK automatically signs a SwapIntent and
|
|
806
|
+
* resubmits the payment with swap fields — no action needed from the caller.
|
|
801
807
|
*/
|
|
802
808
|
pay(input: PayInput): Promise<PaymentResult>;
|
|
803
809
|
/**
|
|
@@ -939,6 +945,7 @@ declare class AxonClient {
|
|
|
939
945
|
private _buildPaymentIntent;
|
|
940
946
|
private _buildExecuteIntent;
|
|
941
947
|
private _buildSwapIntent;
|
|
948
|
+
private _submitPaymentWithSwap;
|
|
942
949
|
private _submitPayment;
|
|
943
950
|
private _submitExecute;
|
|
944
951
|
private _submitSwap;
|
|
@@ -1681,25 +1688,17 @@ declare const AxonVaultAbi: readonly [{
|
|
|
1681
1688
|
readonly type: "bytes32";
|
|
1682
1689
|
readonly internalType: "bytes32";
|
|
1683
1690
|
}, {
|
|
1684
|
-
readonly name: "
|
|
1685
|
-
readonly type: "address";
|
|
1686
|
-
readonly internalType: "address";
|
|
1687
|
-
}, {
|
|
1688
|
-
readonly name: "amount";
|
|
1689
|
-
readonly type: "uint256";
|
|
1690
|
-
readonly internalType: "uint256";
|
|
1691
|
-
}, {
|
|
1692
|
-
readonly name: "value";
|
|
1693
|
-
readonly type: "uint256";
|
|
1694
|
-
readonly internalType: "uint256";
|
|
1695
|
-
}, {
|
|
1696
|
-
readonly name: "extraTokens";
|
|
1691
|
+
readonly name: "tokens";
|
|
1697
1692
|
readonly type: "address[]";
|
|
1698
1693
|
readonly internalType: "address[]";
|
|
1699
1694
|
}, {
|
|
1700
|
-
readonly name: "
|
|
1695
|
+
readonly name: "amounts";
|
|
1701
1696
|
readonly type: "uint256[]";
|
|
1702
1697
|
readonly internalType: "uint256[]";
|
|
1698
|
+
}, {
|
|
1699
|
+
readonly name: "value";
|
|
1700
|
+
readonly type: "uint256";
|
|
1701
|
+
readonly internalType: "uint256";
|
|
1703
1702
|
}, {
|
|
1704
1703
|
readonly name: "deadline";
|
|
1705
1704
|
readonly type: "uint256";
|
|
@@ -3142,6 +3141,10 @@ declare const AxonVaultAbi: readonly [{
|
|
|
3142
3141
|
readonly type: "error";
|
|
3143
3142
|
readonly name: "TooManySpendingLimits";
|
|
3144
3143
|
readonly inputs: readonly [];
|
|
3144
|
+
}, {
|
|
3145
|
+
readonly type: "error";
|
|
3146
|
+
readonly name: "TooManyTokens";
|
|
3147
|
+
readonly inputs: readonly [];
|
|
3145
3148
|
}, {
|
|
3146
3149
|
readonly type: "error";
|
|
3147
3150
|
readonly name: "UnexpectedETH";
|
package/dist/index.d.ts
CHANGED
|
@@ -499,10 +499,10 @@ interface PayInput {
|
|
|
499
499
|
* Signed execute intent for DeFi protocol interactions.
|
|
500
500
|
*
|
|
501
501
|
* The bot signs this struct using EIP-712. The relayer submits it to
|
|
502
|
-
* executeProtocol() on-chain. The contract approves `
|
|
503
|
-
* calls it with `callData`, then revokes the
|
|
502
|
+
* executeProtocol() on-chain. The contract approves `tokens` to `protocol`,
|
|
503
|
+
* calls it with `callData`, then revokes the approvals.
|
|
504
504
|
*
|
|
505
|
-
* TypeHash: keccak256("ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address
|
|
505
|
+
* TypeHash: keccak256("ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address[] tokens,uint256[] amounts,uint256 value,uint256 deadline,bytes32 ref)")
|
|
506
506
|
*/
|
|
507
507
|
interface ExecuteIntent {
|
|
508
508
|
/** Bot's own address. Must be registered in the vault. */
|
|
@@ -511,16 +511,12 @@ interface ExecuteIntent {
|
|
|
511
511
|
protocol: Address;
|
|
512
512
|
/** keccak256 of the callData bytes. Verified by relayer before submission. */
|
|
513
513
|
calldataHash: Hex;
|
|
514
|
-
/**
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
|
|
514
|
+
/** Tokens to approve to the protocol (e.g. [USDC, WETH] for GMX). Empty = no approvals. */
|
|
515
|
+
tokens: Address[];
|
|
516
|
+
/** Approval amounts for each token (must match tokens length). */
|
|
517
|
+
amounts: bigint[];
|
|
518
518
|
/** Native ETH to send with the protocol call (e.g. WETH.deposit, Lido.submit). 0 = no ETH. */
|
|
519
519
|
value: bigint;
|
|
520
|
-
/** Additional tokens to approve to the SAME protocol (e.g. WETH for GMX execution fee). Bot-signed. */
|
|
521
|
-
extraTokens: Address[];
|
|
522
|
-
/** Approval amounts for each extra token. Must match extraTokens length. */
|
|
523
|
-
extraAmounts: bigint[];
|
|
524
520
|
/** Unix timestamp after which this intent is invalid. */
|
|
525
521
|
deadline: bigint;
|
|
526
522
|
/** keccak256 of the off-chain memo. Full memo text stored by relayer. */
|
|
@@ -555,16 +551,19 @@ interface ExecuteInput {
|
|
|
555
551
|
protocol: Address;
|
|
556
552
|
/** The actual calldata bytes to send to the protocol. */
|
|
557
553
|
callData: Hex;
|
|
558
|
-
/**
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
554
|
+
/**
|
|
555
|
+
* Tokens to approve to the protocol. Each entry is an address, Token enum, or bare symbol string.
|
|
556
|
+
* Example: ['USDC'] for single token, ['USDC', 'WETH'] for multi-token (GMX).
|
|
557
|
+
* Empty or omitted = no token approvals (e.g. closing a position).
|
|
558
|
+
*/
|
|
559
|
+
tokens?: TokenInput[];
|
|
560
|
+
/**
|
|
561
|
+
* Approval amounts for each token. Must match tokens length.
|
|
562
|
+
* Each entry: bigint (raw base units), number (human-readable), or string (human-readable).
|
|
563
|
+
*/
|
|
564
|
+
amounts?: AmountInput[];
|
|
562
565
|
/** Native ETH to send with the call (wei). Optional, defaults to 0. Used for payable functions like WETH.deposit() or Lido.submit(). */
|
|
563
566
|
value?: bigint;
|
|
564
|
-
/** Additional tokens to approve to the protocol (e.g. WETH for GMX execution fee). Bot signs these. */
|
|
565
|
-
extraTokens?: Address[];
|
|
566
|
-
/** Approval amounts for each extra token (raw base units). Must match extraTokens length. */
|
|
567
|
-
extraAmounts?: bigint[];
|
|
568
567
|
/** Human-readable description. Gets keccak256-hashed to ref. */
|
|
569
568
|
memo?: string;
|
|
570
569
|
/**
|
|
@@ -580,10 +579,6 @@ interface ExecuteInput {
|
|
|
580
579
|
deadline?: bigint;
|
|
581
580
|
/** Arbitrary metadata stored off-chain. */
|
|
582
581
|
metadata?: Record<string, string>;
|
|
583
|
-
/** Source token for pre-swap — an address, Token enum, or bare symbol string. */
|
|
584
|
-
fromToken?: TokenInput;
|
|
585
|
-
/** Max input for pre-swap: bigint (raw), number (human), or string (human). */
|
|
586
|
-
maxFromAmount?: AmountInput;
|
|
587
582
|
}
|
|
588
583
|
/**
|
|
589
584
|
* Input for AxonClient.swap(). Signs a SwapIntent and submits to
|
|
@@ -621,6 +616,13 @@ interface PaymentResult {
|
|
|
621
616
|
estimatedResolutionMs?: number;
|
|
622
617
|
/** Rejection reason. Present when status === 'rejected'. */
|
|
623
618
|
reason?: string;
|
|
619
|
+
/**
|
|
620
|
+
* Machine-readable error code. Present when status === 'rejected'.
|
|
621
|
+
* Notable values:
|
|
622
|
+
* - `'SWAP_REQUIRED'` — vault lacks the payment token. The SDK auto-handles
|
|
623
|
+
* this by signing a SwapIntent and resubmitting.
|
|
624
|
+
*/
|
|
625
|
+
errorCode?: string;
|
|
624
626
|
}
|
|
625
627
|
/** High-level vault info returned by AxonClient.getVaultInfo(). */
|
|
626
628
|
interface VaultInfo {
|
|
@@ -798,6 +800,10 @@ declare class AxonClient {
|
|
|
798
800
|
* - `"approved"`: fast path — txHash available immediately
|
|
799
801
|
* - `"pending_review"`: AI scan or human review in progress — poll for status
|
|
800
802
|
* - `"rejected"`: payment was rejected — reason field explains why
|
|
803
|
+
*
|
|
804
|
+
* If the vault doesn't hold enough of the payment token, the relayer returns
|
|
805
|
+
* `errorCode: 'SWAP_REQUIRED'`. The SDK automatically signs a SwapIntent and
|
|
806
|
+
* resubmits the payment with swap fields — no action needed from the caller.
|
|
801
807
|
*/
|
|
802
808
|
pay(input: PayInput): Promise<PaymentResult>;
|
|
803
809
|
/**
|
|
@@ -939,6 +945,7 @@ declare class AxonClient {
|
|
|
939
945
|
private _buildPaymentIntent;
|
|
940
946
|
private _buildExecuteIntent;
|
|
941
947
|
private _buildSwapIntent;
|
|
948
|
+
private _submitPaymentWithSwap;
|
|
942
949
|
private _submitPayment;
|
|
943
950
|
private _submitExecute;
|
|
944
951
|
private _submitSwap;
|
|
@@ -1681,25 +1688,17 @@ declare const AxonVaultAbi: readonly [{
|
|
|
1681
1688
|
readonly type: "bytes32";
|
|
1682
1689
|
readonly internalType: "bytes32";
|
|
1683
1690
|
}, {
|
|
1684
|
-
readonly name: "
|
|
1685
|
-
readonly type: "address";
|
|
1686
|
-
readonly internalType: "address";
|
|
1687
|
-
}, {
|
|
1688
|
-
readonly name: "amount";
|
|
1689
|
-
readonly type: "uint256";
|
|
1690
|
-
readonly internalType: "uint256";
|
|
1691
|
-
}, {
|
|
1692
|
-
readonly name: "value";
|
|
1693
|
-
readonly type: "uint256";
|
|
1694
|
-
readonly internalType: "uint256";
|
|
1695
|
-
}, {
|
|
1696
|
-
readonly name: "extraTokens";
|
|
1691
|
+
readonly name: "tokens";
|
|
1697
1692
|
readonly type: "address[]";
|
|
1698
1693
|
readonly internalType: "address[]";
|
|
1699
1694
|
}, {
|
|
1700
|
-
readonly name: "
|
|
1695
|
+
readonly name: "amounts";
|
|
1701
1696
|
readonly type: "uint256[]";
|
|
1702
1697
|
readonly internalType: "uint256[]";
|
|
1698
|
+
}, {
|
|
1699
|
+
readonly name: "value";
|
|
1700
|
+
readonly type: "uint256";
|
|
1701
|
+
readonly internalType: "uint256";
|
|
1703
1702
|
}, {
|
|
1704
1703
|
readonly name: "deadline";
|
|
1705
1704
|
readonly type: "uint256";
|
|
@@ -3142,6 +3141,10 @@ declare const AxonVaultAbi: readonly [{
|
|
|
3142
3141
|
readonly type: "error";
|
|
3143
3142
|
readonly name: "TooManySpendingLimits";
|
|
3144
3143
|
readonly inputs: readonly [];
|
|
3144
|
+
}, {
|
|
3145
|
+
readonly type: "error";
|
|
3146
|
+
readonly name: "TooManyTokens";
|
|
3147
|
+
readonly inputs: readonly [];
|
|
3145
3148
|
}, {
|
|
3146
3149
|
readonly type: "error";
|
|
3147
3150
|
readonly name: "UnexpectedETH";
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ var PAYMENT_INTENT_TYPEHASH = keccak256(
|
|
|
16
16
|
);
|
|
17
17
|
var EXECUTE_INTENT_TYPEHASH = keccak256(
|
|
18
18
|
stringToBytes(
|
|
19
|
-
"ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address
|
|
19
|
+
"ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address[] tokens,uint256[] amounts,uint256 value,uint256 deadline,bytes32 ref)"
|
|
20
20
|
)
|
|
21
21
|
);
|
|
22
22
|
var SWAP_INTENT_TYPEHASH = keccak256(
|
|
@@ -151,11 +151,9 @@ var EXECUTE_INTENT_TYPES = {
|
|
|
151
151
|
{ name: "bot", type: "address" },
|
|
152
152
|
{ name: "protocol", type: "address" },
|
|
153
153
|
{ name: "calldataHash", type: "bytes32" },
|
|
154
|
-
{ name: "
|
|
155
|
-
{ name: "
|
|
154
|
+
{ name: "tokens", type: "address[]" },
|
|
155
|
+
{ name: "amounts", type: "uint256[]" },
|
|
156
156
|
{ name: "value", type: "uint256" },
|
|
157
|
-
{ name: "extraTokens", type: "address[]" },
|
|
158
|
-
{ name: "extraAmounts", type: "uint256[]" },
|
|
159
157
|
{ name: "deadline", type: "uint256" },
|
|
160
158
|
{ name: "ref", type: "bytes32" }
|
|
161
159
|
]
|
|
@@ -209,11 +207,9 @@ async function signExecuteIntent(walletClient, vaultAddress, chainId, intent) {
|
|
|
209
207
|
bot: intent.bot,
|
|
210
208
|
protocol: intent.protocol,
|
|
211
209
|
calldataHash: intent.calldataHash,
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
tokens: intent.tokens,
|
|
211
|
+
amounts: intent.amounts,
|
|
214
212
|
value: intent.value,
|
|
215
|
-
extraTokens: intent.extraTokens,
|
|
216
|
-
extraAmounts: intent.extraAmounts,
|
|
217
213
|
deadline: intent.deadline,
|
|
218
214
|
ref: intent.ref
|
|
219
215
|
}
|
|
@@ -724,30 +720,20 @@ var AxonVaultAbi = [
|
|
|
724
720
|
"internalType": "bytes32"
|
|
725
721
|
},
|
|
726
722
|
{
|
|
727
|
-
"name": "
|
|
728
|
-
"type": "address",
|
|
729
|
-
"internalType": "address"
|
|
723
|
+
"name": "tokens",
|
|
724
|
+
"type": "address[]",
|
|
725
|
+
"internalType": "address[]"
|
|
730
726
|
},
|
|
731
727
|
{
|
|
732
|
-
"name": "
|
|
733
|
-
"type": "uint256",
|
|
734
|
-
"internalType": "uint256"
|
|
728
|
+
"name": "amounts",
|
|
729
|
+
"type": "uint256[]",
|
|
730
|
+
"internalType": "uint256[]"
|
|
735
731
|
},
|
|
736
732
|
{
|
|
737
733
|
"name": "value",
|
|
738
734
|
"type": "uint256",
|
|
739
735
|
"internalType": "uint256"
|
|
740
736
|
},
|
|
741
|
-
{
|
|
742
|
-
"name": "extraTokens",
|
|
743
|
-
"type": "address[]",
|
|
744
|
-
"internalType": "address[]"
|
|
745
|
-
},
|
|
746
|
-
{
|
|
747
|
-
"name": "extraAmounts",
|
|
748
|
-
"type": "uint256[]",
|
|
749
|
-
"internalType": "uint256[]"
|
|
750
|
-
},
|
|
751
737
|
{
|
|
752
738
|
"name": "deadline",
|
|
753
739
|
"type": "uint256",
|
|
@@ -2597,6 +2583,11 @@ var AxonVaultAbi = [
|
|
|
2597
2583
|
"name": "TooManySpendingLimits",
|
|
2598
2584
|
"inputs": []
|
|
2599
2585
|
},
|
|
2586
|
+
{
|
|
2587
|
+
"type": "error",
|
|
2588
|
+
"name": "TooManyTokens",
|
|
2589
|
+
"inputs": []
|
|
2590
|
+
},
|
|
2600
2591
|
{
|
|
2601
2592
|
"type": "error",
|
|
2602
2593
|
"name": "UnexpectedETH",
|
|
@@ -3982,11 +3973,30 @@ var AxonClient = class {
|
|
|
3982
3973
|
* - `"approved"`: fast path — txHash available immediately
|
|
3983
3974
|
* - `"pending_review"`: AI scan or human review in progress — poll for status
|
|
3984
3975
|
* - `"rejected"`: payment was rejected — reason field explains why
|
|
3976
|
+
*
|
|
3977
|
+
* If the vault doesn't hold enough of the payment token, the relayer returns
|
|
3978
|
+
* `errorCode: 'SWAP_REQUIRED'`. The SDK automatically signs a SwapIntent and
|
|
3979
|
+
* resubmits the payment with swap fields — no action needed from the caller.
|
|
3985
3980
|
*/
|
|
3986
3981
|
async pay(input) {
|
|
3987
3982
|
const intent = this._buildPaymentIntent(input);
|
|
3988
3983
|
const signature = await signPayment(this.walletClient, this.vaultAddress, this.chainId, intent);
|
|
3989
|
-
|
|
3984
|
+
const result = await this._submitPayment(intent, signature, input);
|
|
3985
|
+
if (result.status === "rejected" && result.errorCode === "SWAP_REQUIRED") {
|
|
3986
|
+
const swapIntent = {
|
|
3987
|
+
bot: this.botAddress,
|
|
3988
|
+
toToken: intent.token,
|
|
3989
|
+
// swap TO the payment token
|
|
3990
|
+
minToAmount: intent.amount,
|
|
3991
|
+
// need at least the payment amount
|
|
3992
|
+
deadline: intent.deadline,
|
|
3993
|
+
// same deadline
|
|
3994
|
+
ref: intent.ref
|
|
3995
|
+
};
|
|
3996
|
+
const swapSig = await signSwapIntent(this.walletClient, this.vaultAddress, this.chainId, swapIntent);
|
|
3997
|
+
return this._submitPaymentWithSwap(intent, signature, input, swapIntent, swapSig);
|
|
3998
|
+
}
|
|
3999
|
+
return result;
|
|
3990
4000
|
}
|
|
3991
4001
|
// ============================================================================
|
|
3992
4002
|
// execute()
|
|
@@ -4222,15 +4232,30 @@ Timestamp: ${timestamp}`;
|
|
|
4222
4232
|
}
|
|
4223
4233
|
_buildExecuteIntent(input) {
|
|
4224
4234
|
_rejectBurnAddress(input.protocol, "Protocol address");
|
|
4235
|
+
const inputTokens = input.tokens ?? [];
|
|
4236
|
+
const inputAmounts = input.amounts ?? [];
|
|
4237
|
+
if (inputTokens.length !== inputAmounts.length) {
|
|
4238
|
+
throw new Error(`tokens length (${inputTokens.length}) must match amounts length (${inputAmounts.length})`);
|
|
4239
|
+
}
|
|
4240
|
+
if (inputTokens.length > 5) {
|
|
4241
|
+
throw new Error(`Too many tokens (${inputTokens.length}): maximum 5 allowed. Contact Axon if you need more.`);
|
|
4242
|
+
}
|
|
4243
|
+
const resolvedTokens = inputTokens.map((t) => resolveToken(t, this.chainId));
|
|
4244
|
+
const zeroAddr = "0x0000000000000000000000000000000000000000";
|
|
4245
|
+
for (const t of resolvedTokens) {
|
|
4246
|
+
if (t.toLowerCase() === zeroAddr) throw new Error("Zero address not allowed in tokens array");
|
|
4247
|
+
}
|
|
4248
|
+
const uniqueTokens = new Set(resolvedTokens.map((t) => t.toLowerCase()));
|
|
4249
|
+
if (uniqueTokens.size !== resolvedTokens.length) {
|
|
4250
|
+
throw new Error("Duplicate token addresses in tokens array");
|
|
4251
|
+
}
|
|
4225
4252
|
return {
|
|
4226
4253
|
bot: this.botAddress,
|
|
4227
4254
|
protocol: input.protocol,
|
|
4228
4255
|
calldataHash: keccak256(input.callData),
|
|
4229
|
-
|
|
4230
|
-
|
|
4256
|
+
tokens: resolvedTokens,
|
|
4257
|
+
amounts: inputTokens.map((t, i) => parseAmount(inputAmounts[i], t, this.chainId)),
|
|
4231
4258
|
value: input.value ?? 0n,
|
|
4232
|
-
extraTokens: input.extraTokens ?? [],
|
|
4233
|
-
extraAmounts: input.extraAmounts ?? [],
|
|
4234
4259
|
deadline: input.deadline ?? this._defaultDeadline(),
|
|
4235
4260
|
ref: this._resolveRef(input.memo, input.ref)
|
|
4236
4261
|
};
|
|
@@ -4244,6 +4269,38 @@ Timestamp: ${timestamp}`;
|
|
|
4244
4269
|
ref: this._resolveRef(input.memo, input.ref)
|
|
4245
4270
|
};
|
|
4246
4271
|
}
|
|
4272
|
+
async _submitPaymentWithSwap(intent, signature, input, swapIntent, swapSignature) {
|
|
4273
|
+
const idempotencyKey = generateUuid();
|
|
4274
|
+
const body = {
|
|
4275
|
+
// Routing
|
|
4276
|
+
chainId: this.chainId,
|
|
4277
|
+
vaultAddress: this.vaultAddress,
|
|
4278
|
+
// Flat intent fields (matches relayer DTO)
|
|
4279
|
+
bot: intent.bot,
|
|
4280
|
+
to: intent.to,
|
|
4281
|
+
token: intent.token,
|
|
4282
|
+
amount: intent.amount.toString(),
|
|
4283
|
+
deadline: intent.deadline.toString(),
|
|
4284
|
+
ref: intent.ref,
|
|
4285
|
+
signature,
|
|
4286
|
+
// Swap fields
|
|
4287
|
+
swapSignature,
|
|
4288
|
+
swapToToken: swapIntent.toToken,
|
|
4289
|
+
swapMinToAmount: swapIntent.minToAmount.toString(),
|
|
4290
|
+
swapDeadline: swapIntent.deadline.toString(),
|
|
4291
|
+
swapRef: swapIntent.ref,
|
|
4292
|
+
// Off-chain metadata
|
|
4293
|
+
idempotencyKey,
|
|
4294
|
+
...input.memo !== void 0 && { memo: input.memo },
|
|
4295
|
+
...input.resourceUrl !== void 0 && { resourceUrl: input.resourceUrl },
|
|
4296
|
+
...input.invoiceId !== void 0 && { invoiceId: input.invoiceId },
|
|
4297
|
+
...input.orderId !== void 0 && { orderId: input.orderId },
|
|
4298
|
+
...input.recipientLabel !== void 0 && { recipientLabel: input.recipientLabel },
|
|
4299
|
+
...input.metadata !== void 0 && { metadata: input.metadata },
|
|
4300
|
+
...input.x402Funding !== void 0 && { x402Funding: input.x402Funding }
|
|
4301
|
+
};
|
|
4302
|
+
return this._post(RELAYER_API.PAYMENTS, idempotencyKey, body);
|
|
4303
|
+
}
|
|
4247
4304
|
async _submitPayment(intent, signature, input) {
|
|
4248
4305
|
const idempotencyKey = input.idempotencyKey ?? generateUuid();
|
|
4249
4306
|
const body = {
|
|
@@ -4272,8 +4329,6 @@ Timestamp: ${timestamp}`;
|
|
|
4272
4329
|
}
|
|
4273
4330
|
async _submitExecute(intent, signature, input) {
|
|
4274
4331
|
const idempotencyKey = input.idempotencyKey ?? generateUuid();
|
|
4275
|
-
const fromToken = input.fromToken !== void 0 ? resolveToken(input.fromToken, this.chainId) : void 0;
|
|
4276
|
-
const maxFromAmount = input.maxFromAmount !== void 0 ? parseAmount(input.maxFromAmount, input.fromToken ?? input.token, this.chainId) : void 0;
|
|
4277
4332
|
const body = {
|
|
4278
4333
|
chainId: this.chainId,
|
|
4279
4334
|
vaultAddress: this.vaultAddress,
|
|
@@ -4281,17 +4336,14 @@ Timestamp: ${timestamp}`;
|
|
|
4281
4336
|
bot: intent.bot,
|
|
4282
4337
|
protocol: intent.protocol,
|
|
4283
4338
|
calldataHash: intent.calldataHash,
|
|
4284
|
-
|
|
4285
|
-
|
|
4339
|
+
tokens: intent.tokens,
|
|
4340
|
+
amounts: intent.amounts.map((a) => a.toString()),
|
|
4286
4341
|
value: intent.value.toString(),
|
|
4287
4342
|
deadline: intent.deadline.toString(),
|
|
4288
4343
|
ref: intent.ref,
|
|
4289
4344
|
signature,
|
|
4290
4345
|
// Protocol calldata
|
|
4291
4346
|
callData: input.callData,
|
|
4292
|
-
// Optional pre-swap
|
|
4293
|
-
...fromToken !== void 0 && { fromToken },
|
|
4294
|
-
...maxFromAmount !== void 0 && { maxFromAmount: maxFromAmount.toString() },
|
|
4295
4347
|
// Off-chain metadata
|
|
4296
4348
|
idempotencyKey,
|
|
4297
4349
|
...input.memo !== void 0 && { memo: input.memo },
|