@axonfi/sdk 0.8.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,address[] extraTokens,uint256[] extraAmounts,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,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
- /** 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
- /** 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
- /** Token to approve to the protocol — an address, Token enum, or bare symbol string ('USDC'). */
559
- token: TokenInput;
560
- /** Amount to approve: bigint (raw base units), number (human-readable), or string (human-readable). */
561
- 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[];
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
  /**
@@ -1681,25 +1680,17 @@ declare const AxonVaultAbi: readonly [{
1681
1680
  readonly type: "bytes32";
1682
1681
  readonly internalType: "bytes32";
1683
1682
  }, {
1684
- readonly name: "token";
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";
1683
+ readonly name: "tokens";
1697
1684
  readonly type: "address[]";
1698
1685
  readonly internalType: "address[]";
1699
1686
  }, {
1700
- readonly name: "extraAmounts";
1687
+ readonly name: "amounts";
1701
1688
  readonly type: "uint256[]";
1702
1689
  readonly internalType: "uint256[]";
1690
+ }, {
1691
+ readonly name: "value";
1692
+ readonly type: "uint256";
1693
+ readonly internalType: "uint256";
1703
1694
  }, {
1704
1695
  readonly name: "deadline";
1705
1696
  readonly type: "uint256";
@@ -3142,6 +3133,10 @@ declare const AxonVaultAbi: readonly [{
3142
3133
  readonly type: "error";
3143
3134
  readonly name: "TooManySpendingLimits";
3144
3135
  readonly inputs: readonly [];
3136
+ }, {
3137
+ readonly type: "error";
3138
+ readonly name: "TooManyTokens";
3139
+ readonly inputs: readonly [];
3145
3140
  }, {
3146
3141
  readonly type: "error";
3147
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,address[] extraTokens,uint256[] extraAmounts,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,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
- /** 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
- /** 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
- /** Token to approve to the protocol — an address, Token enum, or bare symbol string ('USDC'). */
559
- token: TokenInput;
560
- /** Amount to approve: bigint (raw base units), number (human-readable), or string (human-readable). */
561
- 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[];
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
  /**
@@ -1681,25 +1680,17 @@ declare const AxonVaultAbi: readonly [{
1681
1680
  readonly type: "bytes32";
1682
1681
  readonly internalType: "bytes32";
1683
1682
  }, {
1684
- readonly name: "token";
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";
1683
+ readonly name: "tokens";
1697
1684
  readonly type: "address[]";
1698
1685
  readonly internalType: "address[]";
1699
1686
  }, {
1700
- readonly name: "extraAmounts";
1687
+ readonly name: "amounts";
1701
1688
  readonly type: "uint256[]";
1702
1689
  readonly internalType: "uint256[]";
1690
+ }, {
1691
+ readonly name: "value";
1692
+ readonly type: "uint256";
1693
+ readonly internalType: "uint256";
1703
1694
  }, {
1704
1695
  readonly name: "deadline";
1705
1696
  readonly type: "uint256";
@@ -3142,6 +3133,10 @@ declare const AxonVaultAbi: readonly [{
3142
3133
  readonly type: "error";
3143
3134
  readonly name: "TooManySpendingLimits";
3144
3135
  readonly inputs: readonly [];
3136
+ }, {
3137
+ readonly type: "error";
3138
+ readonly name: "TooManyTokens";
3139
+ readonly inputs: readonly [];
3145
3140
  }, {
3146
3141
  readonly type: "error";
3147
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,address[] extraTokens,uint256[] extraAmounts,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,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: "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
- { 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
- token: intent.token,
213
- amount: intent.amount,
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": "token",
728
- "type": "address",
729
- "internalType": "address"
723
+ "name": "tokens",
724
+ "type": "address[]",
725
+ "internalType": "address[]"
730
726
  },
731
727
  {
732
- "name": "amount",
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",
@@ -4222,15 +4213,30 @@ Timestamp: ${timestamp}`;
4222
4213
  }
4223
4214
  _buildExecuteIntent(input) {
4224
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
+ }
4225
4233
  return {
4226
4234
  bot: this.botAddress,
4227
4235
  protocol: input.protocol,
4228
4236
  calldataHash: keccak256(input.callData),
4229
- token: resolveToken(input.token, this.chainId),
4230
- amount: parseAmount(input.amount, input.token, this.chainId),
4237
+ tokens: resolvedTokens,
4238
+ amounts: inputTokens.map((t, i) => parseAmount(inputAmounts[i], t, this.chainId)),
4231
4239
  value: input.value ?? 0n,
4232
- extraTokens: input.extraTokens ?? [],
4233
- extraAmounts: input.extraAmounts ?? [],
4234
4240
  deadline: input.deadline ?? this._defaultDeadline(),
4235
4241
  ref: this._resolveRef(input.memo, input.ref)
4236
4242
  };
@@ -4273,7 +4279,7 @@ Timestamp: ${timestamp}`;
4273
4279
  async _submitExecute(intent, signature, input) {
4274
4280
  const idempotencyKey = input.idempotencyKey ?? generateUuid();
4275
4281
  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;
4282
+ const maxFromAmount = input.maxFromAmount !== void 0 ? parseAmount(input.maxFromAmount, input.fromToken ?? input.tokens?.[0] ?? "USDC", this.chainId) : void 0;
4277
4283
  const body = {
4278
4284
  chainId: this.chainId,
4279
4285
  vaultAddress: this.vaultAddress,
@@ -4281,8 +4287,8 @@ Timestamp: ${timestamp}`;
4281
4287
  bot: intent.bot,
4282
4288
  protocol: intent.protocol,
4283
4289
  calldataHash: intent.calldataHash,
4284
- token: intent.token,
4285
- amount: intent.amount.toString(),
4290
+ tokens: intent.tokens,
4291
+ amounts: intent.amounts.map((a) => a.toString()),
4286
4292
  value: intent.value.toString(),
4287
4293
  deadline: intent.deadline.toString(),
4288
4294
  ref: intent.ref,