@axonfi/sdk 0.4.3 → 0.4.4
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 +64 -1
- package/dist/index.cjs +150 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -29
- package/dist/index.d.ts +114 -29
- package/dist/index.js +149 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -139,7 +139,7 @@ const result = await axon.swap({
|
|
|
139
139
|
|
|
140
140
|
### DeFi Protocol Execution
|
|
141
141
|
|
|
142
|
-
Interact with DeFi and Web3 protocols (Uniswap, Aave, GMX, etc.)
|
|
142
|
+
Interact with DeFi and Web3 protocols (Uniswap, Aave, GMX, Ostium, etc.) from your vault. The bot signs an `ExecuteIntent` specifying the target contract and calldata. The relayer handles token approvals, execution, and revocation in a single atomic transaction. All executions are subject to the bot's per-transaction and daily spending limits.
|
|
143
143
|
|
|
144
144
|
```typescript
|
|
145
145
|
const result = await axon.execute({
|
|
@@ -150,6 +150,69 @@ const result = await axon.execute({
|
|
|
150
150
|
});
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
+
#### When the approval target differs from the call target
|
|
154
|
+
|
|
155
|
+
In simple cases (Uniswap, Aave), the contract you call is the same contract that pulls your tokens — `execute()` handles this automatically in a single call.
|
|
156
|
+
|
|
157
|
+
But many DeFi protocols split these into two contracts:
|
|
158
|
+
|
|
159
|
+
- **Call target** (`protocol`) — the contract you send the transaction to (e.g., Ostium's `Trading` for `openTrade()`)
|
|
160
|
+
- **Approval target** — the contract that actually calls `transferFrom()` to pull tokens from your vault (e.g., Ostium's `TradingStorage`)
|
|
161
|
+
|
|
162
|
+
When these differ, you need a **two-step pattern**: first give the approval target a persistent token allowance, then call the action.
|
|
163
|
+
|
|
164
|
+
**Example — Ostium perpetual futures:**
|
|
165
|
+
|
|
166
|
+
Ostium's `openTrade()` lives on the Trading contract, but collateral gets pulled by TradingStorage. The vault must approve TradingStorage, not Trading.
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const USDC = '0x...'; // USDC on your chain
|
|
170
|
+
const OSTIUM_TRADING = '0x...'; // calls openTrade()
|
|
171
|
+
const OSTIUM_TRADING_STORAGE = '0x...'; // pulls USDC via transferFrom()
|
|
172
|
+
|
|
173
|
+
// Step 1: Persistent approval (one-time) — call approve() on the token contract
|
|
174
|
+
// This tells USDC to let TradingStorage spend from the vault.
|
|
175
|
+
await axon.execute({
|
|
176
|
+
protocol: USDC, // call target: the token contract itself
|
|
177
|
+
callData: encodeApprove(OSTIUM_TRADING_STORAGE, MaxUint256),
|
|
178
|
+
token: USDC,
|
|
179
|
+
amount: 0, // no token spend, just setting an allowance
|
|
180
|
+
protocolName: 'USDC Approve',
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Step 2: Open trade — call the action contract
|
|
184
|
+
await axon.execute({
|
|
185
|
+
protocol: OSTIUM_TRADING, // call target: the Trading contract
|
|
186
|
+
callData: encodeOpenTrade(...),
|
|
187
|
+
token: USDC,
|
|
188
|
+
amount: 50_000_000, // 50 USDC — passed for dashboard/AI visibility
|
|
189
|
+
protocolName: 'Ostium',
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Vault setup (owner, one-time):** Two contracts must be approved via `approveProtocol()`:
|
|
194
|
+
1. **USDC** (the token contract) — because the vault calls `approve()` on it directly
|
|
195
|
+
2. **Trading** — because the vault calls `openTrade()` on it
|
|
196
|
+
|
|
197
|
+
TradingStorage does *not* need to be approved — it's just an argument to `approve()`, not a contract the vault calls.
|
|
198
|
+
|
|
199
|
+
> **Note:** Common tokens (USDC, USDT, WETH, etc.) are pre-approved globally via the Axon registry as default tokens, so you typically only need to approve the DeFi protocol contract itself. You only need to approve a token if it's uncommon and not in the registry defaults.
|
|
200
|
+
|
|
201
|
+
> **Testnet note:** If the protocol uses a custom token that isn't on Uniswap (e.g., Ostium's testnet USDC), set the bot's `maxPerTxAmount` to `0` to skip TWAP oracle pricing.
|
|
202
|
+
|
|
203
|
+
This pattern applies to any protocol where the approval target differs from the call target (GMX, some lending protocols, etc.).
|
|
204
|
+
|
|
205
|
+
#### `ContractNotApproved` error
|
|
206
|
+
|
|
207
|
+
If `execute()` reverts with `ContractNotApproved`, the `protocol` address you're calling isn't approved. Two possible causes:
|
|
208
|
+
|
|
209
|
+
1. **The DeFi protocol contract isn't approved** — the vault owner must call `approveProtocol(address)` on the vault for the protocol contract (e.g., Uniswap Router, Ostium Trading, Lido stETH).
|
|
210
|
+
2. **The token contract isn't approved** — when doing a token approval (Step 1 above), the token must either be approved on the vault via `approveProtocol(tokenAddress)` or be a registry default token. Common tokens (USDC, USDT, WETH, DAI, etc.) are pre-approved globally by Axon, but uncommon tokens (e.g., stETH, aUSDC, cTokens) may need manual approval.
|
|
211
|
+
|
|
212
|
+
**Example — Lido staking/unstaking:** To unstake stETH, Lido's withdrawal contract calls `transferFrom()` to pull stETH from your vault. You need:
|
|
213
|
+
- `approveProtocol(stETH)` — so the vault can call `approve()` on the stETH token to grant Lido an allowance
|
|
214
|
+
- `approveProtocol(lidoWithdrawalQueue)` — so the vault can call `requestWithdrawals()` on Lido
|
|
215
|
+
|
|
153
216
|
### Vault Reads
|
|
154
217
|
|
|
155
218
|
Query your vault's on-chain state — balances, bot status, pause state, and destination checks. All reads go through the relayer (no RPC connection needed).
|
package/dist/index.cjs
CHANGED
|
@@ -439,12 +439,12 @@ var AxonVaultAbi = [
|
|
|
439
439
|
},
|
|
440
440
|
{
|
|
441
441
|
"type": "function",
|
|
442
|
-
"name": "
|
|
442
|
+
"name": "addRebalanceTokens",
|
|
443
443
|
"inputs": [
|
|
444
444
|
{
|
|
445
|
-
"name": "
|
|
446
|
-
"type": "address",
|
|
447
|
-
"internalType": "address"
|
|
445
|
+
"name": "tokens",
|
|
446
|
+
"type": "address[]",
|
|
447
|
+
"internalType": "address[]"
|
|
448
448
|
}
|
|
449
449
|
],
|
|
450
450
|
"outputs": [],
|
|
@@ -452,12 +452,12 @@ var AxonVaultAbi = [
|
|
|
452
452
|
},
|
|
453
453
|
{
|
|
454
454
|
"type": "function",
|
|
455
|
-
"name": "
|
|
455
|
+
"name": "approveProtocol",
|
|
456
456
|
"inputs": [
|
|
457
457
|
{
|
|
458
|
-
"name": "
|
|
459
|
-
"type": "address
|
|
460
|
-
"internalType": "address
|
|
458
|
+
"name": "protocol",
|
|
459
|
+
"type": "address",
|
|
460
|
+
"internalType": "address"
|
|
461
461
|
}
|
|
462
462
|
],
|
|
463
463
|
"outputs": [],
|
|
@@ -1015,7 +1015,7 @@ var AxonVaultAbi = [
|
|
|
1015
1015
|
},
|
|
1016
1016
|
{
|
|
1017
1017
|
"type": "function",
|
|
1018
|
-
"name": "
|
|
1018
|
+
"name": "isContractApproved",
|
|
1019
1019
|
"inputs": [
|
|
1020
1020
|
{
|
|
1021
1021
|
"name": "protocol",
|
|
@@ -1239,19 +1239,6 @@ var AxonVaultAbi = [
|
|
|
1239
1239
|
"outputs": [],
|
|
1240
1240
|
"stateMutability": "nonpayable"
|
|
1241
1241
|
},
|
|
1242
|
-
{
|
|
1243
|
-
"type": "function",
|
|
1244
|
-
"name": "removeProtocol",
|
|
1245
|
-
"inputs": [
|
|
1246
|
-
{
|
|
1247
|
-
"name": "protocol",
|
|
1248
|
-
"type": "address",
|
|
1249
|
-
"internalType": "address"
|
|
1250
|
-
}
|
|
1251
|
-
],
|
|
1252
|
-
"outputs": [],
|
|
1253
|
-
"stateMutability": "nonpayable"
|
|
1254
|
-
},
|
|
1255
1242
|
{
|
|
1256
1243
|
"type": "function",
|
|
1257
1244
|
"name": "removeRebalanceTokens",
|
|
@@ -1272,6 +1259,19 @@ var AxonVaultAbi = [
|
|
|
1272
1259
|
"outputs": [],
|
|
1273
1260
|
"stateMutability": "nonpayable"
|
|
1274
1261
|
},
|
|
1262
|
+
{
|
|
1263
|
+
"type": "function",
|
|
1264
|
+
"name": "revokeProtocol",
|
|
1265
|
+
"inputs": [
|
|
1266
|
+
{
|
|
1267
|
+
"name": "protocol",
|
|
1268
|
+
"type": "address",
|
|
1269
|
+
"internalType": "address"
|
|
1270
|
+
}
|
|
1271
|
+
],
|
|
1272
|
+
"outputs": [],
|
|
1273
|
+
"stateMutability": "nonpayable"
|
|
1274
|
+
},
|
|
1275
1275
|
{
|
|
1276
1276
|
"type": "function",
|
|
1277
1277
|
"name": "setOperator",
|
|
@@ -1782,7 +1782,7 @@ var AxonVaultAbi = [
|
|
|
1782
1782
|
},
|
|
1783
1783
|
{
|
|
1784
1784
|
"type": "event",
|
|
1785
|
-
"name": "
|
|
1785
|
+
"name": "ProtocolApproved",
|
|
1786
1786
|
"inputs": [
|
|
1787
1787
|
{
|
|
1788
1788
|
"name": "protocol",
|
|
@@ -1832,7 +1832,7 @@ var AxonVaultAbi = [
|
|
|
1832
1832
|
},
|
|
1833
1833
|
{
|
|
1834
1834
|
"type": "event",
|
|
1835
|
-
"name": "
|
|
1835
|
+
"name": "ProtocolRevoked",
|
|
1836
1836
|
"inputs": [
|
|
1837
1837
|
{
|
|
1838
1838
|
"name": "protocol",
|
|
@@ -2029,6 +2029,11 @@ var AxonVaultAbi = [
|
|
|
2029
2029
|
"name": "CalldataHashMismatch",
|
|
2030
2030
|
"inputs": []
|
|
2031
2031
|
},
|
|
2032
|
+
{
|
|
2033
|
+
"type": "error",
|
|
2034
|
+
"name": "ContractNotApproved",
|
|
2035
|
+
"inputs": []
|
|
2036
|
+
},
|
|
2032
2037
|
{
|
|
2033
2038
|
"type": "error",
|
|
2034
2039
|
"name": "DeadlineExpired",
|
|
@@ -2193,11 +2198,6 @@ var AxonVaultAbi = [
|
|
|
2193
2198
|
"name": "ProtocolNotApproved",
|
|
2194
2199
|
"inputs": []
|
|
2195
2200
|
},
|
|
2196
|
-
{
|
|
2197
|
-
"type": "error",
|
|
2198
|
-
"name": "ProtocolNotInList",
|
|
2199
|
-
"inputs": []
|
|
2200
|
-
},
|
|
2201
2201
|
{
|
|
2202
2202
|
"type": "error",
|
|
2203
2203
|
"name": "RebalanceTokenNotAllowed",
|
|
@@ -2763,6 +2763,7 @@ var Token = /* @__PURE__ */ ((Token2) => {
|
|
|
2763
2763
|
Token2["cbETH"] = "cbETH";
|
|
2764
2764
|
Token2["wstETH"] = "wstETH";
|
|
2765
2765
|
Token2["rETH"] = "rETH";
|
|
2766
|
+
Token2["weETH"] = "weETH";
|
|
2766
2767
|
Token2["LINK"] = "LINK";
|
|
2767
2768
|
Token2["UNI"] = "UNI";
|
|
2768
2769
|
Token2["AAVE"] = "AAVE";
|
|
@@ -2860,9 +2861,19 @@ var KNOWN_TOKENS = {
|
|
|
2860
2861
|
name: "Rocket Pool ETH",
|
|
2861
2862
|
decimals: 18,
|
|
2862
2863
|
addresses: {
|
|
2864
|
+
8453: "0xB6fe221Fe9EeF5aBa221c348bA20A1Bf5e73624c",
|
|
2863
2865
|
42161: "0xEC70Dcb4A1EFa46b8F2D97C310C9c4790ba5ffA8"
|
|
2864
2866
|
}
|
|
2865
2867
|
},
|
|
2868
|
+
weETH: {
|
|
2869
|
+
symbol: "weETH",
|
|
2870
|
+
name: "EtherFi Wrapped eETH",
|
|
2871
|
+
decimals: 18,
|
|
2872
|
+
addresses: {
|
|
2873
|
+
8453: "0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A",
|
|
2874
|
+
42161: "0x35751007a407ca6FEFfE80b3cB397736D2cf4dbe"
|
|
2875
|
+
}
|
|
2876
|
+
},
|
|
2866
2877
|
// ── DeFi blue-chips ─────────────────────────────────────
|
|
2867
2878
|
LINK: {
|
|
2868
2879
|
symbol: "LINK",
|
|
@@ -2944,6 +2955,27 @@ var KNOWN_TOKENS = {
|
|
|
2944
2955
|
}
|
|
2945
2956
|
}
|
|
2946
2957
|
};
|
|
2958
|
+
var DEFAULT_APPROVED_TOKENS = [
|
|
2959
|
+
"USDC",
|
|
2960
|
+
"USDT",
|
|
2961
|
+
"DAI",
|
|
2962
|
+
"WETH",
|
|
2963
|
+
"WBTC",
|
|
2964
|
+
"cbBTC",
|
|
2965
|
+
"wstETH",
|
|
2966
|
+
"weETH",
|
|
2967
|
+
"cbETH",
|
|
2968
|
+
"rETH"
|
|
2969
|
+
];
|
|
2970
|
+
function getDefaultApprovedTokens(chainId) {
|
|
2971
|
+
const addresses = [];
|
|
2972
|
+
for (const symbol of DEFAULT_APPROVED_TOKENS) {
|
|
2973
|
+
const entry = KNOWN_TOKENS[symbol];
|
|
2974
|
+
const addr = entry.addresses[chainId];
|
|
2975
|
+
if (addr) addresses.push(addr);
|
|
2976
|
+
}
|
|
2977
|
+
return addresses;
|
|
2978
|
+
}
|
|
2947
2979
|
var addressToSymbol = /* @__PURE__ */ new Map();
|
|
2948
2980
|
for (const token of Object.values(KNOWN_TOKENS)) {
|
|
2949
2981
|
for (const addr of Object.values(token.addresses)) {
|
|
@@ -3525,10 +3557,10 @@ var AxonClient = class {
|
|
|
3525
3557
|
return this._get(path);
|
|
3526
3558
|
}
|
|
3527
3559
|
// ============================================================================
|
|
3528
|
-
//
|
|
3560
|
+
// isContractApproved() — via relayer
|
|
3529
3561
|
// ============================================================================
|
|
3530
|
-
/** Returns whether a
|
|
3531
|
-
async
|
|
3562
|
+
/** Returns whether a contract address (protocol or token) is approved for executeProtocol() calls (via relayer). */
|
|
3563
|
+
async isContractApproved(protocol) {
|
|
3532
3564
|
const path = RELAYER_API.protocolCheck(this.vaultAddress, protocol, this.chainId);
|
|
3533
3565
|
const data = await this._get(path);
|
|
3534
3566
|
return data.approved;
|
|
@@ -3890,6 +3922,19 @@ var AxonRegistryAbi = [
|
|
|
3890
3922
|
],
|
|
3891
3923
|
"stateMutability": "nonpayable"
|
|
3892
3924
|
},
|
|
3925
|
+
{
|
|
3926
|
+
"type": "function",
|
|
3927
|
+
"name": "VERSION",
|
|
3928
|
+
"inputs": [],
|
|
3929
|
+
"outputs": [
|
|
3930
|
+
{
|
|
3931
|
+
"name": "",
|
|
3932
|
+
"type": "uint256",
|
|
3933
|
+
"internalType": "uint256"
|
|
3934
|
+
}
|
|
3935
|
+
],
|
|
3936
|
+
"stateMutability": "view"
|
|
3937
|
+
},
|
|
3893
3938
|
{
|
|
3894
3939
|
"type": "function",
|
|
3895
3940
|
"name": "acceptOwnership",
|
|
@@ -3923,6 +3968,19 @@ var AxonRegistryAbi = [
|
|
|
3923
3968
|
"outputs": [],
|
|
3924
3969
|
"stateMutability": "nonpayable"
|
|
3925
3970
|
},
|
|
3971
|
+
{
|
|
3972
|
+
"type": "function",
|
|
3973
|
+
"name": "approveDefaultToken",
|
|
3974
|
+
"inputs": [
|
|
3975
|
+
{
|
|
3976
|
+
"name": "token",
|
|
3977
|
+
"type": "address",
|
|
3978
|
+
"internalType": "address"
|
|
3979
|
+
}
|
|
3980
|
+
],
|
|
3981
|
+
"outputs": [],
|
|
3982
|
+
"stateMutability": "nonpayable"
|
|
3983
|
+
},
|
|
3926
3984
|
{
|
|
3927
3985
|
"type": "function",
|
|
3928
3986
|
"name": "isApprovedSwapRouter",
|
|
@@ -3961,6 +4019,25 @@ var AxonRegistryAbi = [
|
|
|
3961
4019
|
],
|
|
3962
4020
|
"stateMutability": "view"
|
|
3963
4021
|
},
|
|
4022
|
+
{
|
|
4023
|
+
"type": "function",
|
|
4024
|
+
"name": "isDefaultToken",
|
|
4025
|
+
"inputs": [
|
|
4026
|
+
{
|
|
4027
|
+
"name": "token",
|
|
4028
|
+
"type": "address",
|
|
4029
|
+
"internalType": "address"
|
|
4030
|
+
}
|
|
4031
|
+
],
|
|
4032
|
+
"outputs": [
|
|
4033
|
+
{
|
|
4034
|
+
"name": "",
|
|
4035
|
+
"type": "bool",
|
|
4036
|
+
"internalType": "bool"
|
|
4037
|
+
}
|
|
4038
|
+
],
|
|
4039
|
+
"stateMutability": "view"
|
|
4040
|
+
},
|
|
3964
4041
|
{
|
|
3965
4042
|
"type": "function",
|
|
3966
4043
|
"name": "owner",
|
|
@@ -4020,6 +4097,19 @@ var AxonRegistryAbi = [
|
|
|
4020
4097
|
"outputs": [],
|
|
4021
4098
|
"stateMutability": "nonpayable"
|
|
4022
4099
|
},
|
|
4100
|
+
{
|
|
4101
|
+
"type": "function",
|
|
4102
|
+
"name": "revokeDefaultToken",
|
|
4103
|
+
"inputs": [
|
|
4104
|
+
{
|
|
4105
|
+
"name": "token",
|
|
4106
|
+
"type": "address",
|
|
4107
|
+
"internalType": "address"
|
|
4108
|
+
}
|
|
4109
|
+
],
|
|
4110
|
+
"outputs": [],
|
|
4111
|
+
"stateMutability": "nonpayable"
|
|
4112
|
+
},
|
|
4023
4113
|
{
|
|
4024
4114
|
"type": "function",
|
|
4025
4115
|
"name": "setOracleConfig",
|
|
@@ -4095,6 +4185,32 @@ var AxonRegistryAbi = [
|
|
|
4095
4185
|
],
|
|
4096
4186
|
"stateMutability": "view"
|
|
4097
4187
|
},
|
|
4188
|
+
{
|
|
4189
|
+
"type": "event",
|
|
4190
|
+
"name": "DefaultTokenApproved",
|
|
4191
|
+
"inputs": [
|
|
4192
|
+
{
|
|
4193
|
+
"name": "token",
|
|
4194
|
+
"type": "address",
|
|
4195
|
+
"indexed": true,
|
|
4196
|
+
"internalType": "address"
|
|
4197
|
+
}
|
|
4198
|
+
],
|
|
4199
|
+
"anonymous": false
|
|
4200
|
+
},
|
|
4201
|
+
{
|
|
4202
|
+
"type": "event",
|
|
4203
|
+
"name": "DefaultTokenRevoked",
|
|
4204
|
+
"inputs": [
|
|
4205
|
+
{
|
|
4206
|
+
"name": "token",
|
|
4207
|
+
"type": "address",
|
|
4208
|
+
"indexed": true,
|
|
4209
|
+
"internalType": "address"
|
|
4210
|
+
}
|
|
4211
|
+
],
|
|
4212
|
+
"anonymous": false
|
|
4213
|
+
},
|
|
4098
4214
|
{
|
|
4099
4215
|
"type": "event",
|
|
4100
4216
|
"name": "OracleConfigUpdated",
|
|
@@ -4265,6 +4381,7 @@ exports.AxonVaultAbi = AxonVaultAbi;
|
|
|
4265
4381
|
exports.AxonVaultFactoryAbi = AxonVaultFactoryAbi;
|
|
4266
4382
|
exports.CHAIN_NAMES = CHAIN_NAMES;
|
|
4267
4383
|
exports.Chain = Chain;
|
|
4384
|
+
exports.DEFAULT_APPROVED_TOKENS = DEFAULT_APPROVED_TOKENS;
|
|
4268
4385
|
exports.DEFAULT_DEADLINE_SECONDS = DEFAULT_DEADLINE_SECONDS;
|
|
4269
4386
|
exports.EIP712_DOMAIN_NAME = EIP712_DOMAIN_NAME;
|
|
4270
4387
|
exports.EIP712_DOMAIN_VERSION = EIP712_DOMAIN_VERSION;
|
|
@@ -4296,6 +4413,7 @@ exports.findMatchingOption = findMatchingOption;
|
|
|
4296
4413
|
exports.formatPaymentSignature = formatPaymentSignature;
|
|
4297
4414
|
exports.getBotConfig = getBotConfig;
|
|
4298
4415
|
exports.getChain = getChain;
|
|
4416
|
+
exports.getDefaultApprovedTokens = getDefaultApprovedTokens;
|
|
4299
4417
|
exports.getDomainSeparator = getDomainSeparator;
|
|
4300
4418
|
exports.getKnownTokensForChain = getKnownTokensForChain;
|
|
4301
4419
|
exports.getOperatorCeilings = getOperatorCeilings;
|