@axonfi/sdk 0.7.0 → 0.9.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/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 `token` to `protocol`,
503
- * calls it with `callData`, then revokes the approval.
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 token,uint256 amount,uint256 value,uint256 deadline,bytes32 ref)")
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,10 +511,10 @@ interface ExecuteIntent {
511
511
  protocol: Address;
512
512
  /** keccak256 of the callData bytes. Verified by relayer before submission. */
513
513
  calldataHash: Hex;
514
- /** Token to approve to the protocol before calling. */
515
- token: Address;
516
- /** Amount to approve (in token base units). */
517
- amount: bigint;
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
520
  /** Unix timestamp after which this intent is invalid. */
@@ -551,10 +551,17 @@ interface ExecuteInput {
551
551
  protocol: Address;
552
552
  /** The actual calldata bytes to send to the protocol. */
553
553
  callData: Hex;
554
- /** Token to approve to the protocol — an address, Token enum, or bare symbol string ('USDC'). */
555
- token: TokenInput;
556
- /** Amount to approve: bigint (raw base units), number (human-readable), or string (human-readable). */
557
- amount: AmountInput;
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[];
558
565
  /** Native ETH to send with the call (wei). Optional, defaults to 0. Used for payable functions like WETH.deposit() or Lido.submit(). */
559
566
  value?: bigint;
560
567
  /** Human-readable description. Gets keccak256-hashed to ref. */
@@ -1588,6 +1595,16 @@ declare const AxonVaultAbi: readonly [{
1588
1595
  readonly internalType: "uint256[]";
1589
1596
  }];
1590
1597
  readonly stateMutability: "view";
1598
+ }, {
1599
+ readonly type: "function";
1600
+ readonly name: "erc1271BotsEnabled";
1601
+ readonly inputs: readonly [];
1602
+ readonly outputs: readonly [{
1603
+ readonly name: "";
1604
+ readonly type: "bool";
1605
+ readonly internalType: "bool";
1606
+ }];
1607
+ readonly stateMutability: "view";
1591
1608
  }, {
1592
1609
  readonly type: "function";
1593
1610
  readonly name: "executePayment";
@@ -1663,13 +1680,13 @@ declare const AxonVaultAbi: readonly [{
1663
1680
  readonly type: "bytes32";
1664
1681
  readonly internalType: "bytes32";
1665
1682
  }, {
1666
- readonly name: "token";
1667
- readonly type: "address";
1668
- readonly internalType: "address";
1683
+ readonly name: "tokens";
1684
+ readonly type: "address[]";
1685
+ readonly internalType: "address[]";
1669
1686
  }, {
1670
- readonly name: "amount";
1671
- readonly type: "uint256";
1672
- readonly internalType: "uint256";
1687
+ readonly name: "amounts";
1688
+ readonly type: "uint256[]";
1689
+ readonly internalType: "uint256[]";
1673
1690
  }, {
1674
1691
  readonly name: "value";
1675
1692
  readonly type: "uint256";
@@ -1929,26 +1946,6 @@ declare const AxonVaultAbi: readonly [{
1929
1946
  readonly internalType: "bytes4";
1930
1947
  }];
1931
1948
  readonly stateMutability: "view";
1932
- }, {
1933
- readonly type: "function";
1934
- readonly name: "erc1271BotsEnabled";
1935
- readonly inputs: readonly [];
1936
- readonly outputs: readonly [{
1937
- readonly name: "";
1938
- readonly type: "bool";
1939
- readonly internalType: "bool";
1940
- }];
1941
- readonly stateMutability: "view";
1942
- }, {
1943
- readonly type: "function";
1944
- readonly name: "setErc1271Bots";
1945
- readonly inputs: readonly [{
1946
- readonly name: "enabled";
1947
- readonly type: "bool";
1948
- readonly internalType: "bool";
1949
- }];
1950
- readonly outputs: readonly [];
1951
- readonly stateMutability: "nonpayable";
1952
1949
  }, {
1953
1950
  readonly type: "function";
1954
1951
  readonly name: "onERC1155BatchReceived";
@@ -2221,6 +2218,16 @@ declare const AxonVaultAbi: readonly [{
2221
2218
  }];
2222
2219
  readonly outputs: readonly [];
2223
2220
  readonly stateMutability: "nonpayable";
2221
+ }, {
2222
+ readonly type: "function";
2223
+ readonly name: "setErc1271Bots";
2224
+ readonly inputs: readonly [{
2225
+ readonly name: "enabled";
2226
+ readonly type: "bool";
2227
+ readonly internalType: "bool";
2228
+ }];
2229
+ readonly outputs: readonly [];
2230
+ readonly stateMutability: "nonpayable";
2224
2231
  }, {
2225
2232
  readonly type: "function";
2226
2233
  readonly name: "setOperator";
@@ -2412,16 +2419,6 @@ declare const AxonVaultAbi: readonly [{
2412
2419
  }];
2413
2420
  readonly outputs: readonly [];
2414
2421
  readonly stateMutability: "nonpayable";
2415
- }, {
2416
- readonly type: "event";
2417
- readonly name: "ERC1271BotsToggled";
2418
- readonly inputs: readonly [{
2419
- readonly name: "enabled";
2420
- readonly type: "bool";
2421
- readonly indexed: false;
2422
- readonly internalType: "bool";
2423
- }];
2424
- readonly anonymous: false;
2425
2422
  }, {
2426
2423
  readonly type: "event";
2427
2424
  readonly name: "BotAdded";
@@ -2552,6 +2549,16 @@ declare const AxonVaultAbi: readonly [{
2552
2549
  readonly internalType: "address";
2553
2550
  }];
2554
2551
  readonly anonymous: false;
2552
+ }, {
2553
+ readonly type: "event";
2554
+ readonly name: "ERC1271BotsToggled";
2555
+ readonly inputs: readonly [{
2556
+ readonly name: "enabled";
2557
+ readonly type: "bool";
2558
+ readonly indexed: false;
2559
+ readonly internalType: "bool";
2560
+ }];
2561
+ readonly anonymous: false;
2555
2562
  }, {
2556
2563
  readonly type: "event";
2557
2564
  readonly name: "ERC721Withdrawn";
@@ -2926,6 +2933,10 @@ declare const AxonVaultAbi: readonly [{
2926
2933
  readonly type: "error";
2927
2934
  readonly name: "AmountMismatch";
2928
2935
  readonly inputs: readonly [];
2936
+ }, {
2937
+ readonly type: "error";
2938
+ readonly name: "ArrayLengthMismatch";
2939
+ readonly inputs: readonly [];
2929
2940
  }, {
2930
2941
  readonly type: "error";
2931
2942
  readonly name: "BotAlreadyExists";
@@ -3122,6 +3133,10 @@ declare const AxonVaultAbi: readonly [{
3122
3133
  readonly type: "error";
3123
3134
  readonly name: "TooManySpendingLimits";
3124
3135
  readonly inputs: readonly [];
3136
+ }, {
3137
+ readonly type: "error";
3138
+ readonly name: "TooManyTokens";
3139
+ readonly inputs: readonly [];
3125
3140
  }, {
3126
3141
  readonly type: "error";
3127
3142
  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 `token` to `protocol`,
503
- * calls it with `callData`, then revokes the approval.
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 token,uint256 amount,uint256 value,uint256 deadline,bytes32 ref)")
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,10 +511,10 @@ interface ExecuteIntent {
511
511
  protocol: Address;
512
512
  /** keccak256 of the callData bytes. Verified by relayer before submission. */
513
513
  calldataHash: Hex;
514
- /** Token to approve to the protocol before calling. */
515
- token: Address;
516
- /** Amount to approve (in token base units). */
517
- amount: bigint;
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
520
  /** Unix timestamp after which this intent is invalid. */
@@ -551,10 +551,17 @@ interface ExecuteInput {
551
551
  protocol: Address;
552
552
  /** The actual calldata bytes to send to the protocol. */
553
553
  callData: Hex;
554
- /** Token to approve to the protocol — an address, Token enum, or bare symbol string ('USDC'). */
555
- token: TokenInput;
556
- /** Amount to approve: bigint (raw base units), number (human-readable), or string (human-readable). */
557
- amount: AmountInput;
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[];
558
565
  /** Native ETH to send with the call (wei). Optional, defaults to 0. Used for payable functions like WETH.deposit() or Lido.submit(). */
559
566
  value?: bigint;
560
567
  /** Human-readable description. Gets keccak256-hashed to ref. */
@@ -1588,6 +1595,16 @@ declare const AxonVaultAbi: readonly [{
1588
1595
  readonly internalType: "uint256[]";
1589
1596
  }];
1590
1597
  readonly stateMutability: "view";
1598
+ }, {
1599
+ readonly type: "function";
1600
+ readonly name: "erc1271BotsEnabled";
1601
+ readonly inputs: readonly [];
1602
+ readonly outputs: readonly [{
1603
+ readonly name: "";
1604
+ readonly type: "bool";
1605
+ readonly internalType: "bool";
1606
+ }];
1607
+ readonly stateMutability: "view";
1591
1608
  }, {
1592
1609
  readonly type: "function";
1593
1610
  readonly name: "executePayment";
@@ -1663,13 +1680,13 @@ declare const AxonVaultAbi: readonly [{
1663
1680
  readonly type: "bytes32";
1664
1681
  readonly internalType: "bytes32";
1665
1682
  }, {
1666
- readonly name: "token";
1667
- readonly type: "address";
1668
- readonly internalType: "address";
1683
+ readonly name: "tokens";
1684
+ readonly type: "address[]";
1685
+ readonly internalType: "address[]";
1669
1686
  }, {
1670
- readonly name: "amount";
1671
- readonly type: "uint256";
1672
- readonly internalType: "uint256";
1687
+ readonly name: "amounts";
1688
+ readonly type: "uint256[]";
1689
+ readonly internalType: "uint256[]";
1673
1690
  }, {
1674
1691
  readonly name: "value";
1675
1692
  readonly type: "uint256";
@@ -1929,26 +1946,6 @@ declare const AxonVaultAbi: readonly [{
1929
1946
  readonly internalType: "bytes4";
1930
1947
  }];
1931
1948
  readonly stateMutability: "view";
1932
- }, {
1933
- readonly type: "function";
1934
- readonly name: "erc1271BotsEnabled";
1935
- readonly inputs: readonly [];
1936
- readonly outputs: readonly [{
1937
- readonly name: "";
1938
- readonly type: "bool";
1939
- readonly internalType: "bool";
1940
- }];
1941
- readonly stateMutability: "view";
1942
- }, {
1943
- readonly type: "function";
1944
- readonly name: "setErc1271Bots";
1945
- readonly inputs: readonly [{
1946
- readonly name: "enabled";
1947
- readonly type: "bool";
1948
- readonly internalType: "bool";
1949
- }];
1950
- readonly outputs: readonly [];
1951
- readonly stateMutability: "nonpayable";
1952
1949
  }, {
1953
1950
  readonly type: "function";
1954
1951
  readonly name: "onERC1155BatchReceived";
@@ -2221,6 +2218,16 @@ declare const AxonVaultAbi: readonly [{
2221
2218
  }];
2222
2219
  readonly outputs: readonly [];
2223
2220
  readonly stateMutability: "nonpayable";
2221
+ }, {
2222
+ readonly type: "function";
2223
+ readonly name: "setErc1271Bots";
2224
+ readonly inputs: readonly [{
2225
+ readonly name: "enabled";
2226
+ readonly type: "bool";
2227
+ readonly internalType: "bool";
2228
+ }];
2229
+ readonly outputs: readonly [];
2230
+ readonly stateMutability: "nonpayable";
2224
2231
  }, {
2225
2232
  readonly type: "function";
2226
2233
  readonly name: "setOperator";
@@ -2412,16 +2419,6 @@ declare const AxonVaultAbi: readonly [{
2412
2419
  }];
2413
2420
  readonly outputs: readonly [];
2414
2421
  readonly stateMutability: "nonpayable";
2415
- }, {
2416
- readonly type: "event";
2417
- readonly name: "ERC1271BotsToggled";
2418
- readonly inputs: readonly [{
2419
- readonly name: "enabled";
2420
- readonly type: "bool";
2421
- readonly indexed: false;
2422
- readonly internalType: "bool";
2423
- }];
2424
- readonly anonymous: false;
2425
2422
  }, {
2426
2423
  readonly type: "event";
2427
2424
  readonly name: "BotAdded";
@@ -2552,6 +2549,16 @@ declare const AxonVaultAbi: readonly [{
2552
2549
  readonly internalType: "address";
2553
2550
  }];
2554
2551
  readonly anonymous: false;
2552
+ }, {
2553
+ readonly type: "event";
2554
+ readonly name: "ERC1271BotsToggled";
2555
+ readonly inputs: readonly [{
2556
+ readonly name: "enabled";
2557
+ readonly type: "bool";
2558
+ readonly indexed: false;
2559
+ readonly internalType: "bool";
2560
+ }];
2561
+ readonly anonymous: false;
2555
2562
  }, {
2556
2563
  readonly type: "event";
2557
2564
  readonly name: "ERC721Withdrawn";
@@ -2926,6 +2933,10 @@ declare const AxonVaultAbi: readonly [{
2926
2933
  readonly type: "error";
2927
2934
  readonly name: "AmountMismatch";
2928
2935
  readonly inputs: readonly [];
2936
+ }, {
2937
+ readonly type: "error";
2938
+ readonly name: "ArrayLengthMismatch";
2939
+ readonly inputs: readonly [];
2929
2940
  }, {
2930
2941
  readonly type: "error";
2931
2942
  readonly name: "BotAlreadyExists";
@@ -3122,6 +3133,10 @@ declare const AxonVaultAbi: readonly [{
3122
3133
  readonly type: "error";
3123
3134
  readonly name: "TooManySpendingLimits";
3124
3135
  readonly inputs: readonly [];
3136
+ }, {
3137
+ readonly type: "error";
3138
+ readonly name: "TooManyTokens";
3139
+ readonly inputs: readonly [];
3125
3140
  }, {
3126
3141
  readonly type: "error";
3127
3142
  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 token,uint256 amount,uint256 value,uint256 deadline,bytes32 ref)"
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,8 +151,8 @@ var EXECUTE_INTENT_TYPES = {
151
151
  { name: "bot", type: "address" },
152
152
  { name: "protocol", type: "address" },
153
153
  { name: "calldataHash", type: "bytes32" },
154
- { name: "token", type: "address" },
155
- { name: "amount", type: "uint256" },
154
+ { name: "tokens", type: "address[]" },
155
+ { name: "amounts", type: "uint256[]" },
156
156
  { name: "value", type: "uint256" },
157
157
  { name: "deadline", type: "uint256" },
158
158
  { name: "ref", type: "bytes32" }
@@ -207,8 +207,8 @@ async function signExecuteIntent(walletClient, vaultAddress, chainId, intent) {
207
207
  bot: intent.bot,
208
208
  protocol: intent.protocol,
209
209
  calldataHash: intent.calldataHash,
210
- token: intent.token,
211
- amount: intent.amount,
210
+ tokens: intent.tokens,
211
+ amounts: intent.amounts,
212
212
  value: intent.value,
213
213
  deadline: intent.deadline,
214
214
  ref: intent.ref
@@ -612,6 +612,19 @@ var AxonVaultAbi = [
612
612
  ],
613
613
  "stateMutability": "view"
614
614
  },
615
+ {
616
+ "type": "function",
617
+ "name": "erc1271BotsEnabled",
618
+ "inputs": [],
619
+ "outputs": [
620
+ {
621
+ "name": "",
622
+ "type": "bool",
623
+ "internalType": "bool"
624
+ }
625
+ ],
626
+ "stateMutability": "view"
627
+ },
615
628
  {
616
629
  "type": "function",
617
630
  "name": "executePayment",
@@ -707,14 +720,14 @@ var AxonVaultAbi = [
707
720
  "internalType": "bytes32"
708
721
  },
709
722
  {
710
- "name": "token",
711
- "type": "address",
712
- "internalType": "address"
723
+ "name": "tokens",
724
+ "type": "address[]",
725
+ "internalType": "address[]"
713
726
  },
714
727
  {
715
- "name": "amount",
716
- "type": "uint256",
717
- "internalType": "uint256"
728
+ "name": "amounts",
729
+ "type": "uint256[]",
730
+ "internalType": "uint256[]"
718
731
  },
719
732
  {
720
733
  "name": "value",
@@ -1055,32 +1068,6 @@ var AxonVaultAbi = [
1055
1068
  ],
1056
1069
  "stateMutability": "view"
1057
1070
  },
1058
- {
1059
- "type": "function",
1060
- "name": "erc1271BotsEnabled",
1061
- "inputs": [],
1062
- "outputs": [
1063
- {
1064
- "name": "",
1065
- "type": "bool",
1066
- "internalType": "bool"
1067
- }
1068
- ],
1069
- "stateMutability": "view"
1070
- },
1071
- {
1072
- "type": "function",
1073
- "name": "setErc1271Bots",
1074
- "inputs": [
1075
- {
1076
- "name": "enabled",
1077
- "type": "bool",
1078
- "internalType": "bool"
1079
- }
1080
- ],
1081
- "outputs": [],
1082
- "stateMutability": "nonpayable"
1083
- },
1084
1071
  {
1085
1072
  "type": "function",
1086
1073
  "name": "onERC1155BatchReceived",
@@ -1433,6 +1420,19 @@ var AxonVaultAbi = [
1433
1420
  "outputs": [],
1434
1421
  "stateMutability": "nonpayable"
1435
1422
  },
1423
+ {
1424
+ "type": "function",
1425
+ "name": "setErc1271Bots",
1426
+ "inputs": [
1427
+ {
1428
+ "name": "enabled",
1429
+ "type": "bool",
1430
+ "internalType": "bool"
1431
+ }
1432
+ ],
1433
+ "outputs": [],
1434
+ "stateMutability": "nonpayable"
1435
+ },
1436
1436
  {
1437
1437
  "type": "function",
1438
1438
  "name": "setOperator",
@@ -1680,19 +1680,6 @@ var AxonVaultAbi = [
1680
1680
  "outputs": [],
1681
1681
  "stateMutability": "nonpayable"
1682
1682
  },
1683
- {
1684
- "type": "event",
1685
- "name": "ERC1271BotsToggled",
1686
- "inputs": [
1687
- {
1688
- "name": "enabled",
1689
- "type": "bool",
1690
- "indexed": false,
1691
- "internalType": "bool"
1692
- }
1693
- ],
1694
- "anonymous": false
1695
- },
1696
1683
  {
1697
1684
  "type": "event",
1698
1685
  "name": "BotAdded",
@@ -1856,6 +1843,19 @@ var AxonVaultAbi = [
1856
1843
  ],
1857
1844
  "anonymous": false
1858
1845
  },
1846
+ {
1847
+ "type": "event",
1848
+ "name": "ERC1271BotsToggled",
1849
+ "inputs": [
1850
+ {
1851
+ "name": "enabled",
1852
+ "type": "bool",
1853
+ "indexed": false,
1854
+ "internalType": "bool"
1855
+ }
1856
+ ],
1857
+ "anonymous": false
1858
+ },
1859
1859
  {
1860
1860
  "type": "event",
1861
1861
  "name": "ERC721Withdrawn",
@@ -2328,6 +2328,11 @@ var AxonVaultAbi = [
2328
2328
  "name": "AmountMismatch",
2329
2329
  "inputs": []
2330
2330
  },
2331
+ {
2332
+ "type": "error",
2333
+ "name": "ArrayLengthMismatch",
2334
+ "inputs": []
2335
+ },
2331
2336
  {
2332
2337
  "type": "error",
2333
2338
  "name": "BotAlreadyExists",
@@ -2578,6 +2583,11 @@ var AxonVaultAbi = [
2578
2583
  "name": "TooManySpendingLimits",
2579
2584
  "inputs": []
2580
2585
  },
2586
+ {
2587
+ "type": "error",
2588
+ "name": "TooManyTokens",
2589
+ "inputs": []
2590
+ },
2581
2591
  {
2582
2592
  "type": "error",
2583
2593
  "name": "UnexpectedETH",
@@ -4203,12 +4213,29 @@ Timestamp: ${timestamp}`;
4203
4213
  }
4204
4214
  _buildExecuteIntent(input) {
4205
4215
  _rejectBurnAddress(input.protocol, "Protocol address");
4216
+ const inputTokens = input.tokens ?? [];
4217
+ const inputAmounts = input.amounts ?? [];
4218
+ if (inputTokens.length !== inputAmounts.length) {
4219
+ throw new Error(`tokens length (${inputTokens.length}) must match amounts length (${inputAmounts.length})`);
4220
+ }
4221
+ if (inputTokens.length > 5) {
4222
+ throw new Error(`Too many tokens (${inputTokens.length}): maximum 5 allowed. Contact Axon if you need more.`);
4223
+ }
4224
+ const resolvedTokens = inputTokens.map((t) => resolveToken(t, this.chainId));
4225
+ const zeroAddr = "0x0000000000000000000000000000000000000000";
4226
+ for (const t of resolvedTokens) {
4227
+ if (t.toLowerCase() === zeroAddr) throw new Error("Zero address not allowed in tokens array");
4228
+ }
4229
+ const uniqueTokens = new Set(resolvedTokens.map((t) => t.toLowerCase()));
4230
+ if (uniqueTokens.size !== resolvedTokens.length) {
4231
+ throw new Error("Duplicate token addresses in tokens array");
4232
+ }
4206
4233
  return {
4207
4234
  bot: this.botAddress,
4208
4235
  protocol: input.protocol,
4209
4236
  calldataHash: keccak256(input.callData),
4210
- token: resolveToken(input.token, this.chainId),
4211
- amount: parseAmount(input.amount, input.token, this.chainId),
4237
+ tokens: resolvedTokens,
4238
+ amounts: inputTokens.map((t, i) => parseAmount(inputAmounts[i], t, this.chainId)),
4212
4239
  value: input.value ?? 0n,
4213
4240
  deadline: input.deadline ?? this._defaultDeadline(),
4214
4241
  ref: this._resolveRef(input.memo, input.ref)
@@ -4252,7 +4279,7 @@ Timestamp: ${timestamp}`;
4252
4279
  async _submitExecute(intent, signature, input) {
4253
4280
  const idempotencyKey = input.idempotencyKey ?? generateUuid();
4254
4281
  const fromToken = input.fromToken !== void 0 ? resolveToken(input.fromToken, this.chainId) : void 0;
4255
- const maxFromAmount = input.maxFromAmount !== void 0 ? parseAmount(input.maxFromAmount, input.fromToken ?? input.token, this.chainId) : void 0;
4282
+ const maxFromAmount = input.maxFromAmount !== void 0 ? parseAmount(input.maxFromAmount, input.fromToken ?? input.tokens?.[0] ?? "USDC", this.chainId) : void 0;
4256
4283
  const body = {
4257
4284
  chainId: this.chainId,
4258
4285
  vaultAddress: this.vaultAddress,
@@ -4260,8 +4287,8 @@ Timestamp: ${timestamp}`;
4260
4287
  bot: intent.bot,
4261
4288
  protocol: intent.protocol,
4262
4289
  calldataHash: intent.calldataHash,
4263
- token: intent.token,
4264
- amount: intent.amount.toString(),
4290
+ tokens: intent.tokens,
4291
+ amounts: intent.amounts.map((a) => a.toString()),
4265
4292
  value: intent.value.toString(),
4266
4293
  deadline: intent.deadline.toString(),
4267
4294
  ref: intent.ref,