@axonfi/sdk 0.5.5 → 0.7.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 deadline,bytes32 ref)"
21
+ "ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address token,uint256 amount,uint256 value,uint256 deadline,bytes32 ref)"
22
22
  )
23
23
  );
24
24
  var SWAP_INTENT_TYPEHASH = viem.keccak256(
@@ -155,6 +155,7 @@ var EXECUTE_INTENT_TYPES = {
155
155
  { name: "calldataHash", type: "bytes32" },
156
156
  { name: "token", type: "address" },
157
157
  { name: "amount", type: "uint256" },
158
+ { name: "value", type: "uint256" },
158
159
  { name: "deadline", type: "uint256" },
159
160
  { name: "ref", type: "bytes32" }
160
161
  ]
@@ -210,6 +211,7 @@ async function signExecuteIntent(walletClient, vaultAddress, chainId, intent) {
210
211
  calldataHash: intent.calldataHash,
211
212
  token: intent.token,
212
213
  amount: intent.amount,
214
+ value: intent.value,
213
215
  deadline: intent.deadline,
214
216
  ref: intent.ref
215
217
  }
@@ -241,18 +243,7 @@ function encodeRef(memo) {
241
243
  var AxonVaultAbi = [
242
244
  {
243
245
  "type": "constructor",
244
- "inputs": [
245
- {
246
- "name": "_owner",
247
- "type": "address",
248
- "internalType": "address"
249
- },
250
- {
251
- "name": "_axonRegistry",
252
- "type": "address",
253
- "internalType": "address"
254
- }
255
- ],
246
+ "inputs": [],
256
247
  "stateMutability": "nonpayable"
257
248
  },
258
249
  {
@@ -727,6 +718,11 @@ var AxonVaultAbi = [
727
718
  "type": "uint256",
728
719
  "internalType": "uint256"
729
720
  },
721
+ {
722
+ "name": "value",
723
+ "type": "uint256",
724
+ "internalType": "uint256"
725
+ },
730
726
  {
731
727
  "name": "deadline",
732
728
  "type": "uint256",
@@ -981,6 +977,24 @@ var AxonVaultAbi = [
981
977
  ],
982
978
  "stateMutability": "view"
983
979
  },
980
+ {
981
+ "type": "function",
982
+ "name": "initialize",
983
+ "inputs": [
984
+ {
985
+ "name": "_owner",
986
+ "type": "address",
987
+ "internalType": "address"
988
+ },
989
+ {
990
+ "name": "_axonRegistry",
991
+ "type": "address",
992
+ "internalType": "address"
993
+ }
994
+ ],
995
+ "outputs": [],
996
+ "stateMutability": "nonpayable"
997
+ },
984
998
  {
985
999
  "type": "function",
986
1000
  "name": "isBotActive",
@@ -1019,6 +1033,56 @@ var AxonVaultAbi = [
1019
1033
  ],
1020
1034
  "stateMutability": "view"
1021
1035
  },
1036
+ {
1037
+ "type": "function",
1038
+ "name": "isValidSignature",
1039
+ "inputs": [
1040
+ {
1041
+ "name": "hash",
1042
+ "type": "bytes32",
1043
+ "internalType": "bytes32"
1044
+ },
1045
+ {
1046
+ "name": "signature",
1047
+ "type": "bytes",
1048
+ "internalType": "bytes"
1049
+ }
1050
+ ],
1051
+ "outputs": [
1052
+ {
1053
+ "name": "",
1054
+ "type": "bytes4",
1055
+ "internalType": "bytes4"
1056
+ }
1057
+ ],
1058
+ "stateMutability": "view"
1059
+ },
1060
+ {
1061
+ "type": "function",
1062
+ "name": "erc1271BotsEnabled",
1063
+ "inputs": [],
1064
+ "outputs": [
1065
+ {
1066
+ "name": "",
1067
+ "type": "bool",
1068
+ "internalType": "bool"
1069
+ }
1070
+ ],
1071
+ "stateMutability": "view"
1072
+ },
1073
+ {
1074
+ "type": "function",
1075
+ "name": "setErc1271Bots",
1076
+ "inputs": [
1077
+ {
1078
+ "name": "enabled",
1079
+ "type": "bool",
1080
+ "internalType": "bool"
1081
+ }
1082
+ ],
1083
+ "outputs": [],
1084
+ "stateMutability": "nonpayable"
1085
+ },
1022
1086
  {
1023
1087
  "type": "function",
1024
1088
  "name": "onERC1155BatchReceived",
@@ -1618,6 +1682,19 @@ var AxonVaultAbi = [
1618
1682
  "outputs": [],
1619
1683
  "stateMutability": "nonpayable"
1620
1684
  },
1685
+ {
1686
+ "type": "event",
1687
+ "name": "ERC1271BotsToggled",
1688
+ "inputs": [
1689
+ {
1690
+ "name": "enabled",
1691
+ "type": "bool",
1692
+ "indexed": false,
1693
+ "internalType": "bool"
1694
+ }
1695
+ ],
1696
+ "anonymous": false
1697
+ },
1621
1698
  {
1622
1699
  "type": "event",
1623
1700
  "name": "BotAdded",
@@ -1858,6 +1935,19 @@ var AxonVaultAbi = [
1858
1935
  ],
1859
1936
  "anonymous": false
1860
1937
  },
1938
+ {
1939
+ "type": "event",
1940
+ "name": "Initialized",
1941
+ "inputs": [
1942
+ {
1943
+ "name": "version",
1944
+ "type": "uint64",
1945
+ "indexed": false,
1946
+ "internalType": "uint64"
1947
+ }
1948
+ ],
1949
+ "anonymous": false
1950
+ },
1861
1951
  {
1862
1952
  "type": "event",
1863
1953
  "name": "OperatorCeilingsUpdated",
@@ -2046,6 +2136,12 @@ var AxonVaultAbi = [
2046
2136
  "indexed": false,
2047
2137
  "internalType": "uint256"
2048
2138
  },
2139
+ {
2140
+ "name": "value",
2141
+ "type": "uint256",
2142
+ "indexed": false,
2143
+ "internalType": "uint256"
2144
+ },
2049
2145
  {
2050
2146
  "name": "ref",
2051
2147
  "type": "bytes32",
@@ -2333,7 +2429,7 @@ var AxonVaultAbi = [
2333
2429
  },
2334
2430
  {
2335
2431
  "type": "error",
2336
- "name": "InvalidShortString",
2432
+ "name": "InvalidInitialization",
2337
2433
  "inputs": []
2338
2434
  },
2339
2435
  {
@@ -2366,6 +2462,11 @@ var AxonVaultAbi = [
2366
2462
  "name": "NotAuthorizedRelayer",
2367
2463
  "inputs": []
2368
2464
  },
2465
+ {
2466
+ "type": "error",
2467
+ "name": "NotInitializing",
2468
+ "inputs": []
2469
+ },
2369
2470
  {
2370
2471
  "type": "error",
2371
2472
  "name": "OperatorBotLimitReached",
@@ -2464,17 +2565,6 @@ var AxonVaultAbi = [
2464
2565
  "name": "SelfPayment",
2465
2566
  "inputs": []
2466
2567
  },
2467
- {
2468
- "type": "error",
2469
- "name": "StringTooLong",
2470
- "inputs": [
2471
- {
2472
- "name": "str",
2473
- "type": "string",
2474
- "internalType": "string"
2475
- }
2476
- ]
2477
- },
2478
2568
  {
2479
2569
  "type": "error",
2480
2570
  "name": "SwapFailed",
@@ -2577,6 +2667,19 @@ var AxonVaultFactoryAbi = [
2577
2667
  ],
2578
2668
  "stateMutability": "nonpayable"
2579
2669
  },
2670
+ {
2671
+ "type": "function",
2672
+ "name": "implementation",
2673
+ "inputs": [],
2674
+ "outputs": [
2675
+ {
2676
+ "name": "",
2677
+ "type": "address",
2678
+ "internalType": "address"
2679
+ }
2680
+ ],
2681
+ "stateMutability": "view"
2682
+ },
2580
2683
  {
2581
2684
  "type": "function",
2582
2685
  "name": "owner",
@@ -2646,6 +2749,30 @@ var AxonVaultFactoryAbi = [
2646
2749
  ],
2647
2750
  "stateMutability": "view"
2648
2751
  },
2752
+ {
2753
+ "type": "function",
2754
+ "name": "predictVaultAddress",
2755
+ "inputs": [
2756
+ {
2757
+ "name": "owner",
2758
+ "type": "address",
2759
+ "internalType": "address"
2760
+ },
2761
+ {
2762
+ "name": "nonce",
2763
+ "type": "uint256",
2764
+ "internalType": "uint256"
2765
+ }
2766
+ ],
2767
+ "outputs": [
2768
+ {
2769
+ "name": "",
2770
+ "type": "address",
2771
+ "internalType": "address"
2772
+ }
2773
+ ],
2774
+ "stateMutability": "view"
2775
+ },
2649
2776
  {
2650
2777
  "type": "function",
2651
2778
  "name": "renounceOwnership",
@@ -2748,6 +2875,27 @@ var AxonVaultFactoryAbi = [
2748
2875
  ],
2749
2876
  "anonymous": false
2750
2877
  },
2878
+ {
2879
+ "type": "error",
2880
+ "name": "FailedDeployment",
2881
+ "inputs": []
2882
+ },
2883
+ {
2884
+ "type": "error",
2885
+ "name": "InsufficientBalance",
2886
+ "inputs": [
2887
+ {
2888
+ "name": "balance",
2889
+ "type": "uint256",
2890
+ "internalType": "uint256"
2891
+ },
2892
+ {
2893
+ "name": "needed",
2894
+ "type": "uint256",
2895
+ "internalType": "uint256"
2896
+ }
2897
+ ]
2898
+ },
2751
2899
  {
2752
2900
  "type": "error",
2753
2901
  "name": "OwnableInvalidOwner",
@@ -3167,6 +3315,13 @@ async function operatorMaxDrainPerDay(publicClient, vaultAddress) {
3167
3315
  functionName: "operatorMaxDrainPerDay"
3168
3316
  });
3169
3317
  }
3318
+ async function isErc1271BotsEnabled(publicClient, vaultAddress) {
3319
+ return publicClient.readContract({
3320
+ address: vaultAddress,
3321
+ abi: AxonVaultAbi,
3322
+ functionName: "erc1271BotsEnabled"
3323
+ });
3324
+ }
3170
3325
  async function isVaultPaused(publicClient, vaultAddress) {
3171
3326
  return publicClient.readContract({
3172
3327
  address: vaultAddress,
@@ -3291,6 +3446,16 @@ async function deployVault(walletClient, publicClient, relayerUrl) {
3291
3446
  }
3292
3447
  throw new Error("VaultDeployed event not found in transaction receipt");
3293
3448
  }
3449
+ async function predictVaultAddress(publicClient, owner, nonce, relayerUrl) {
3450
+ const chainId = await publicClient.getChainId();
3451
+ const factoryAddress = await getFactoryAddress(chainId, relayerUrl);
3452
+ return publicClient.readContract({
3453
+ address: factoryAddress,
3454
+ abi: AxonVaultFactoryAbi,
3455
+ functionName: "predictVaultAddress",
3456
+ args: [owner, BigInt(nonce)]
3457
+ });
3458
+ }
3294
3459
  async function addBot(walletClient, publicClient, vaultAddress, botAddress, config) {
3295
3460
  if (!walletClient.account) {
3296
3461
  throw new Error("walletClient has no account attached");
@@ -4046,6 +4211,7 @@ Timestamp: ${timestamp}`;
4046
4211
  calldataHash: viem.keccak256(input.callData),
4047
4212
  token: resolveToken(input.token, this.chainId),
4048
4213
  amount: parseAmount(input.amount, input.token, this.chainId),
4214
+ value: input.value ?? 0n,
4049
4215
  deadline: input.deadline ?? this._defaultDeadline(),
4050
4216
  ref: this._resolveRef(input.memo, input.ref)
4051
4217
  };
@@ -4098,6 +4264,7 @@ Timestamp: ${timestamp}`;
4098
4264
  calldataHash: intent.calldataHash,
4099
4265
  token: intent.token,
4100
4266
  amount: intent.amount.toString(),
4267
+ value: intent.value.toString(),
4101
4268
  deadline: intent.deadline.toString(),
4102
4269
  ref: intent.ref,
4103
4270
  signature,
@@ -4330,6 +4497,38 @@ var AxonRegistryAbi = [
4330
4497
  "outputs": [],
4331
4498
  "stateMutability": "nonpayable"
4332
4499
  },
4500
+ {
4501
+ "type": "function",
4502
+ "name": "approveProtocol",
4503
+ "inputs": [
4504
+ {
4505
+ "name": "protocol",
4506
+ "type": "address",
4507
+ "internalType": "address"
4508
+ }
4509
+ ],
4510
+ "outputs": [],
4511
+ "stateMutability": "nonpayable"
4512
+ },
4513
+ {
4514
+ "type": "function",
4515
+ "name": "isApprovedProtocol",
4516
+ "inputs": [
4517
+ {
4518
+ "name": "protocol",
4519
+ "type": "address",
4520
+ "internalType": "address"
4521
+ }
4522
+ ],
4523
+ "outputs": [
4524
+ {
4525
+ "name": "",
4526
+ "type": "bool",
4527
+ "internalType": "bool"
4528
+ }
4529
+ ],
4530
+ "stateMutability": "view"
4531
+ },
4333
4532
  {
4334
4533
  "type": "function",
4335
4534
  "name": "isApprovedSwapRouter",
@@ -4459,6 +4658,19 @@ var AxonRegistryAbi = [
4459
4658
  "outputs": [],
4460
4659
  "stateMutability": "nonpayable"
4461
4660
  },
4661
+ {
4662
+ "type": "function",
4663
+ "name": "revokeProtocol",
4664
+ "inputs": [
4665
+ {
4666
+ "name": "protocol",
4667
+ "type": "address",
4668
+ "internalType": "address"
4669
+ }
4670
+ ],
4671
+ "outputs": [],
4672
+ "stateMutability": "nonpayable"
4673
+ },
4462
4674
  {
4463
4675
  "type": "function",
4464
4676
  "name": "setOracleConfig",
@@ -4623,6 +4835,32 @@ var AxonRegistryAbi = [
4623
4835
  ],
4624
4836
  "anonymous": false
4625
4837
  },
4838
+ {
4839
+ "type": "event",
4840
+ "name": "ProtocolApproved",
4841
+ "inputs": [
4842
+ {
4843
+ "name": "protocol",
4844
+ "type": "address",
4845
+ "indexed": true,
4846
+ "internalType": "address"
4847
+ }
4848
+ ],
4849
+ "anonymous": false
4850
+ },
4851
+ {
4852
+ "type": "event",
4853
+ "name": "ProtocolRevoked",
4854
+ "inputs": [
4855
+ {
4856
+ "name": "protocol",
4857
+ "type": "address",
4858
+ "indexed": true,
4859
+ "internalType": "address"
4860
+ }
4861
+ ],
4862
+ "anonymous": false
4863
+ },
4626
4864
  {
4627
4865
  "type": "event",
4628
4866
  "name": "RelayerAdded",
@@ -4775,12 +5013,14 @@ exports.getVaultOwner = getVaultOwner;
4775
5013
  exports.getVaultVersion = getVaultVersion;
4776
5014
  exports.isBotActive = isBotActive;
4777
5015
  exports.isDestinationAllowed = isDestinationAllowed;
5016
+ exports.isErc1271BotsEnabled = isErc1271BotsEnabled;
4778
5017
  exports.isRebalanceTokenWhitelisted = isRebalanceTokenWhitelisted;
4779
5018
  exports.isVaultPaused = isVaultPaused;
4780
5019
  exports.operatorMaxDrainPerDay = operatorMaxDrainPerDay;
4781
5020
  exports.parseAmount = parseAmount;
4782
5021
  exports.parseChainId = parseChainId;
4783
5022
  exports.parsePaymentRequired = parsePaymentRequired;
5023
+ exports.predictVaultAddress = predictVaultAddress;
4784
5024
  exports.randomNonce = randomNonce;
4785
5025
  exports.randomPermit2Nonce = randomPermit2Nonce;
4786
5026
  exports.removeBot = removeBot;