@axonfi/sdk 0.6.0 → 0.8.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 CHANGED
@@ -318,6 +318,31 @@ await axon.getVaultInfo(); // owner, operator, version
318
318
  await axon.canPayTo('0xRecipient'); // destination allowed?
319
319
  ```
320
320
 
321
+ ### ERC-1271 Bot Signatures (External Protocol Signing)
322
+
323
+ By default, only the vault owner's signatures are accepted by external protocols that check ERC-1271 (e.g., Permit2, Cowswap, Seaport). Bot signatures are rejected.
324
+
325
+ If your bot needs to sign messages that external protocols validate against the vault (e.g., signing a Cowswap order, a Permit2 approval, or a Seaport listing), the vault owner must explicitly enable bot signing:
326
+
327
+ ```typescript
328
+ // Check if ERC-1271 bot signing is enabled (direct chain read)
329
+ import { isErc1271BotsEnabled, createAxonPublicClient } from '@axonfi/sdk';
330
+
331
+ const publicClient = createAxonPublicClient(chainId, rpcUrl);
332
+ const enabled = await isErc1271BotsEnabled(publicClient, vaultAddress);
333
+
334
+ if (!enabled) {
335
+ console.log('ERC-1271 bot signatures are disabled on this vault.');
336
+ console.log('The vault owner must enable it via the dashboard or by calling setErc1271Bots(true).');
337
+ }
338
+ ```
339
+
340
+ **When to enable:** Only if your bots interact with protocols that verify signatures via ERC-1271 — Cowswap (off-chain order signing), Permit2 (gasless token approvals), Seaport (NFT marketplace listings).
341
+
342
+ **When to keep disabled (default):** If your bots only make payments, execute DeFi calls, or rebalance tokens through Axon's standard `pay()` / `execute()` / `swap()` endpoints.
343
+
344
+ **Security note:** If a bot key is compromised while ERC-1271 is enabled, the attacker could sign Permit2 approvals or marketplace listings that drain vault funds. The owner can disable it instantly via the dashboard or `setErc1271Bots(false)`.
345
+
321
346
  ### Utilities
322
347
 
323
348
  Helper functions for amount conversion, token resolution, and reference encoding.
@@ -366,7 +391,7 @@ Supports EIP-3009 (USDC, gasless) and Permit2 (any ERC-20) settlement schemes.
366
391
  ## Security Model
367
392
 
368
393
  - **Owners** control everything: bot whitelist, spending limits, withdrawal. Hardware wallet recommended.
369
- - **Bots** only sign payment intents. They never hold ETH, never submit transactions, and can be removed instantly.
394
+ - **Bots** only sign payment intents. They never hold ETH, never submit transactions, and can be removed instantly. External protocol signing (ERC-1271) is disabled by default — must be explicitly enabled by the owner.
370
395
  - **Relayer** (Axon) can only execute bot-signed intents within configured limits. Cannot withdraw or modify vault config.
371
396
  - **If Axon goes offline**, the owner retains full withdrawal access directly through the on-chain vault contract.
372
397
 
package/dist/index.cjs CHANGED
@@ -18,7 +18,7 @@ var PAYMENT_INTENT_TYPEHASH = viem.keccak256(
18
18
  );
19
19
  var EXECUTE_INTENT_TYPEHASH = viem.keccak256(
20
20
  viem.stringToBytes(
21
- "ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address token,uint256 amount,uint256 value,uint256 deadline,bytes32 ref)"
21
+ "ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address token,uint256 amount,uint256 value,address[] extraTokens,uint256[] extraAmounts,uint256 deadline,bytes32 ref)"
22
22
  )
23
23
  );
24
24
  var SWAP_INTENT_TYPEHASH = viem.keccak256(
@@ -156,6 +156,8 @@ var EXECUTE_INTENT_TYPES = {
156
156
  { name: "token", type: "address" },
157
157
  { name: "amount", type: "uint256" },
158
158
  { name: "value", type: "uint256" },
159
+ { name: "extraTokens", type: "address[]" },
160
+ { name: "extraAmounts", type: "uint256[]" },
159
161
  { name: "deadline", type: "uint256" },
160
162
  { name: "ref", type: "bytes32" }
161
163
  ]
@@ -212,6 +214,8 @@ async function signExecuteIntent(walletClient, vaultAddress, chainId, intent) {
212
214
  token: intent.token,
213
215
  amount: intent.amount,
214
216
  value: intent.value,
217
+ extraTokens: intent.extraTokens,
218
+ extraAmounts: intent.extraAmounts,
215
219
  deadline: intent.deadline,
216
220
  ref: intent.ref
217
221
  }
@@ -614,6 +618,19 @@ var AxonVaultAbi = [
614
618
  ],
615
619
  "stateMutability": "view"
616
620
  },
621
+ {
622
+ "type": "function",
623
+ "name": "erc1271BotsEnabled",
624
+ "inputs": [],
625
+ "outputs": [
626
+ {
627
+ "name": "",
628
+ "type": "bool",
629
+ "internalType": "bool"
630
+ }
631
+ ],
632
+ "stateMutability": "view"
633
+ },
617
634
  {
618
635
  "type": "function",
619
636
  "name": "executePayment",
@@ -723,6 +740,16 @@ var AxonVaultAbi = [
723
740
  "type": "uint256",
724
741
  "internalType": "uint256"
725
742
  },
743
+ {
744
+ "name": "extraTokens",
745
+ "type": "address[]",
746
+ "internalType": "address[]"
747
+ },
748
+ {
749
+ "name": "extraAmounts",
750
+ "type": "uint256[]",
751
+ "internalType": "uint256[]"
752
+ },
726
753
  {
727
754
  "name": "deadline",
728
755
  "type": "uint256",
@@ -1409,6 +1436,19 @@ var AxonVaultAbi = [
1409
1436
  "outputs": [],
1410
1437
  "stateMutability": "nonpayable"
1411
1438
  },
1439
+ {
1440
+ "type": "function",
1441
+ "name": "setErc1271Bots",
1442
+ "inputs": [
1443
+ {
1444
+ "name": "enabled",
1445
+ "type": "bool",
1446
+ "internalType": "bool"
1447
+ }
1448
+ ],
1449
+ "outputs": [],
1450
+ "stateMutability": "nonpayable"
1451
+ },
1412
1452
  {
1413
1453
  "type": "function",
1414
1454
  "name": "setOperator",
@@ -1819,6 +1859,19 @@ var AxonVaultAbi = [
1819
1859
  ],
1820
1860
  "anonymous": false
1821
1861
  },
1862
+ {
1863
+ "type": "event",
1864
+ "name": "ERC1271BotsToggled",
1865
+ "inputs": [
1866
+ {
1867
+ "name": "enabled",
1868
+ "type": "bool",
1869
+ "indexed": false,
1870
+ "internalType": "bool"
1871
+ }
1872
+ ],
1873
+ "anonymous": false
1874
+ },
1822
1875
  {
1823
1876
  "type": "event",
1824
1877
  "name": "ERC721Withdrawn",
@@ -2097,6 +2150,12 @@ var AxonVaultAbi = [
2097
2150
  "indexed": false,
2098
2151
  "internalType": "uint256"
2099
2152
  },
2153
+ {
2154
+ "name": "value",
2155
+ "type": "uint256",
2156
+ "indexed": false,
2157
+ "internalType": "uint256"
2158
+ },
2100
2159
  {
2101
2160
  "name": "ref",
2102
2161
  "type": "bytes32",
@@ -2285,6 +2344,11 @@ var AxonVaultAbi = [
2285
2344
  "name": "AmountMismatch",
2286
2345
  "inputs": []
2287
2346
  },
2347
+ {
2348
+ "type": "error",
2349
+ "name": "ArrayLengthMismatch",
2350
+ "inputs": []
2351
+ },
2288
2352
  {
2289
2353
  "type": "error",
2290
2354
  "name": "BotAlreadyExists",
@@ -3270,6 +3334,13 @@ async function operatorMaxDrainPerDay(publicClient, vaultAddress) {
3270
3334
  functionName: "operatorMaxDrainPerDay"
3271
3335
  });
3272
3336
  }
3337
+ async function isErc1271BotsEnabled(publicClient, vaultAddress) {
3338
+ return publicClient.readContract({
3339
+ address: vaultAddress,
3340
+ abi: AxonVaultAbi,
3341
+ functionName: "erc1271BotsEnabled"
3342
+ });
3343
+ }
3273
3344
  async function isVaultPaused(publicClient, vaultAddress) {
3274
3345
  return publicClient.readContract({
3275
3346
  address: vaultAddress,
@@ -4160,6 +4231,8 @@ Timestamp: ${timestamp}`;
4160
4231
  token: resolveToken(input.token, this.chainId),
4161
4232
  amount: parseAmount(input.amount, input.token, this.chainId),
4162
4233
  value: input.value ?? 0n,
4234
+ extraTokens: input.extraTokens ?? [],
4235
+ extraAmounts: input.extraAmounts ?? [],
4163
4236
  deadline: input.deadline ?? this._defaultDeadline(),
4164
4237
  ref: this._resolveRef(input.memo, input.ref)
4165
4238
  };
@@ -4961,6 +5034,7 @@ exports.getVaultOwner = getVaultOwner;
4961
5034
  exports.getVaultVersion = getVaultVersion;
4962
5035
  exports.isBotActive = isBotActive;
4963
5036
  exports.isDestinationAllowed = isDestinationAllowed;
5037
+ exports.isErc1271BotsEnabled = isErc1271BotsEnabled;
4964
5038
  exports.isRebalanceTokenWhitelisted = isRebalanceTokenWhitelisted;
4965
5039
  exports.isVaultPaused = isVaultPaused;
4966
5040
  exports.operatorMaxDrainPerDay = operatorMaxDrainPerDay;