@axonfi/sdk 0.8.0 → 0.10.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 +6 -6
- package/dist/index.cjs +89 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -37
- package/dist/index.d.ts +40 -37
- package/dist/index.js +89 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -238,8 +238,8 @@ Interact with DeFi and Web3 protocols (Uniswap, Aave, GMX, Ostium, etc.) from yo
|
|
|
238
238
|
const result = await axon.execute({
|
|
239
239
|
protocol: '0xUniswapRouter',
|
|
240
240
|
callData: '0x...',
|
|
241
|
-
|
|
242
|
-
|
|
241
|
+
tokens: [Token.USDC],
|
|
242
|
+
amounts: [100],
|
|
243
243
|
});
|
|
244
244
|
```
|
|
245
245
|
|
|
@@ -268,8 +268,8 @@ const OSTIUM_TRADING_STORAGE = '0x...'; // pulls USDC via transferFrom()
|
|
|
268
268
|
await axon.execute({
|
|
269
269
|
protocol: USDC, // call target: the token contract itself
|
|
270
270
|
callData: encodeApprove(OSTIUM_TRADING_STORAGE, MaxUint256),
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
tokens: [USDC],
|
|
272
|
+
amounts: [0], // no token spend, just setting an allowance
|
|
273
273
|
protocolName: 'USDC Approve',
|
|
274
274
|
});
|
|
275
275
|
|
|
@@ -277,8 +277,8 @@ await axon.execute({
|
|
|
277
277
|
await axon.execute({
|
|
278
278
|
protocol: OSTIUM_TRADING, // call target: the Trading contract
|
|
279
279
|
callData: encodeOpenTrade(...),
|
|
280
|
-
|
|
281
|
-
|
|
280
|
+
tokens: [USDC],
|
|
281
|
+
amounts: [50_000_000], // 50 USDC — passed for dashboard/AI visibility
|
|
282
282
|
protocolName: 'Ostium',
|
|
283
283
|
});
|
|
284
284
|
```
|
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
|
|
21
|
+
"ExecuteIntent(address bot,address protocol,bytes32 calldataHash,address[] tokens,uint256[] amounts,uint256 value,uint256 deadline,bytes32 ref)"
|
|
22
22
|
)
|
|
23
23
|
);
|
|
24
24
|
var SWAP_INTENT_TYPEHASH = viem.keccak256(
|
|
@@ -153,11 +153,9 @@ var EXECUTE_INTENT_TYPES = {
|
|
|
153
153
|
{ name: "bot", type: "address" },
|
|
154
154
|
{ name: "protocol", type: "address" },
|
|
155
155
|
{ name: "calldataHash", type: "bytes32" },
|
|
156
|
-
{ name: "
|
|
157
|
-
{ name: "
|
|
156
|
+
{ name: "tokens", type: "address[]" },
|
|
157
|
+
{ name: "amounts", type: "uint256[]" },
|
|
158
158
|
{ name: "value", type: "uint256" },
|
|
159
|
-
{ name: "extraTokens", type: "address[]" },
|
|
160
|
-
{ name: "extraAmounts", type: "uint256[]" },
|
|
161
159
|
{ name: "deadline", type: "uint256" },
|
|
162
160
|
{ name: "ref", type: "bytes32" }
|
|
163
161
|
]
|
|
@@ -211,11 +209,9 @@ async function signExecuteIntent(walletClient, vaultAddress, chainId, intent) {
|
|
|
211
209
|
bot: intent.bot,
|
|
212
210
|
protocol: intent.protocol,
|
|
213
211
|
calldataHash: intent.calldataHash,
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
tokens: intent.tokens,
|
|
213
|
+
amounts: intent.amounts,
|
|
216
214
|
value: intent.value,
|
|
217
|
-
extraTokens: intent.extraTokens,
|
|
218
|
-
extraAmounts: intent.extraAmounts,
|
|
219
215
|
deadline: intent.deadline,
|
|
220
216
|
ref: intent.ref
|
|
221
217
|
}
|
|
@@ -726,30 +722,20 @@ var AxonVaultAbi = [
|
|
|
726
722
|
"internalType": "bytes32"
|
|
727
723
|
},
|
|
728
724
|
{
|
|
729
|
-
"name": "
|
|
730
|
-
"type": "address",
|
|
731
|
-
"internalType": "address"
|
|
725
|
+
"name": "tokens",
|
|
726
|
+
"type": "address[]",
|
|
727
|
+
"internalType": "address[]"
|
|
732
728
|
},
|
|
733
729
|
{
|
|
734
|
-
"name": "
|
|
735
|
-
"type": "uint256",
|
|
736
|
-
"internalType": "uint256"
|
|
730
|
+
"name": "amounts",
|
|
731
|
+
"type": "uint256[]",
|
|
732
|
+
"internalType": "uint256[]"
|
|
737
733
|
},
|
|
738
734
|
{
|
|
739
735
|
"name": "value",
|
|
740
736
|
"type": "uint256",
|
|
741
737
|
"internalType": "uint256"
|
|
742
738
|
},
|
|
743
|
-
{
|
|
744
|
-
"name": "extraTokens",
|
|
745
|
-
"type": "address[]",
|
|
746
|
-
"internalType": "address[]"
|
|
747
|
-
},
|
|
748
|
-
{
|
|
749
|
-
"name": "extraAmounts",
|
|
750
|
-
"type": "uint256[]",
|
|
751
|
-
"internalType": "uint256[]"
|
|
752
|
-
},
|
|
753
739
|
{
|
|
754
740
|
"name": "deadline",
|
|
755
741
|
"type": "uint256",
|
|
@@ -2599,6 +2585,11 @@ var AxonVaultAbi = [
|
|
|
2599
2585
|
"name": "TooManySpendingLimits",
|
|
2600
2586
|
"inputs": []
|
|
2601
2587
|
},
|
|
2588
|
+
{
|
|
2589
|
+
"type": "error",
|
|
2590
|
+
"name": "TooManyTokens",
|
|
2591
|
+
"inputs": []
|
|
2592
|
+
},
|
|
2602
2593
|
{
|
|
2603
2594
|
"type": "error",
|
|
2604
2595
|
"name": "UnexpectedETH",
|
|
@@ -3984,11 +3975,30 @@ var AxonClient = class {
|
|
|
3984
3975
|
* - `"approved"`: fast path — txHash available immediately
|
|
3985
3976
|
* - `"pending_review"`: AI scan or human review in progress — poll for status
|
|
3986
3977
|
* - `"rejected"`: payment was rejected — reason field explains why
|
|
3978
|
+
*
|
|
3979
|
+
* If the vault doesn't hold enough of the payment token, the relayer returns
|
|
3980
|
+
* `errorCode: 'SWAP_REQUIRED'`. The SDK automatically signs a SwapIntent and
|
|
3981
|
+
* resubmits the payment with swap fields — no action needed from the caller.
|
|
3987
3982
|
*/
|
|
3988
3983
|
async pay(input) {
|
|
3989
3984
|
const intent = this._buildPaymentIntent(input);
|
|
3990
3985
|
const signature = await signPayment(this.walletClient, this.vaultAddress, this.chainId, intent);
|
|
3991
|
-
|
|
3986
|
+
const result = await this._submitPayment(intent, signature, input);
|
|
3987
|
+
if (result.status === "rejected" && result.errorCode === "SWAP_REQUIRED") {
|
|
3988
|
+
const swapIntent = {
|
|
3989
|
+
bot: this.botAddress,
|
|
3990
|
+
toToken: intent.token,
|
|
3991
|
+
// swap TO the payment token
|
|
3992
|
+
minToAmount: intent.amount,
|
|
3993
|
+
// need at least the payment amount
|
|
3994
|
+
deadline: intent.deadline,
|
|
3995
|
+
// same deadline
|
|
3996
|
+
ref: intent.ref
|
|
3997
|
+
};
|
|
3998
|
+
const swapSig = await signSwapIntent(this.walletClient, this.vaultAddress, this.chainId, swapIntent);
|
|
3999
|
+
return this._submitPaymentWithSwap(intent, signature, input, swapIntent, swapSig);
|
|
4000
|
+
}
|
|
4001
|
+
return result;
|
|
3992
4002
|
}
|
|
3993
4003
|
// ============================================================================
|
|
3994
4004
|
// execute()
|
|
@@ -4224,15 +4234,30 @@ Timestamp: ${timestamp}`;
|
|
|
4224
4234
|
}
|
|
4225
4235
|
_buildExecuteIntent(input) {
|
|
4226
4236
|
_rejectBurnAddress(input.protocol, "Protocol address");
|
|
4237
|
+
const inputTokens = input.tokens ?? [];
|
|
4238
|
+
const inputAmounts = input.amounts ?? [];
|
|
4239
|
+
if (inputTokens.length !== inputAmounts.length) {
|
|
4240
|
+
throw new Error(`tokens length (${inputTokens.length}) must match amounts length (${inputAmounts.length})`);
|
|
4241
|
+
}
|
|
4242
|
+
if (inputTokens.length > 5) {
|
|
4243
|
+
throw new Error(`Too many tokens (${inputTokens.length}): maximum 5 allowed. Contact Axon if you need more.`);
|
|
4244
|
+
}
|
|
4245
|
+
const resolvedTokens = inputTokens.map((t) => resolveToken(t, this.chainId));
|
|
4246
|
+
const zeroAddr = "0x0000000000000000000000000000000000000000";
|
|
4247
|
+
for (const t of resolvedTokens) {
|
|
4248
|
+
if (t.toLowerCase() === zeroAddr) throw new Error("Zero address not allowed in tokens array");
|
|
4249
|
+
}
|
|
4250
|
+
const uniqueTokens = new Set(resolvedTokens.map((t) => t.toLowerCase()));
|
|
4251
|
+
if (uniqueTokens.size !== resolvedTokens.length) {
|
|
4252
|
+
throw new Error("Duplicate token addresses in tokens array");
|
|
4253
|
+
}
|
|
4227
4254
|
return {
|
|
4228
4255
|
bot: this.botAddress,
|
|
4229
4256
|
protocol: input.protocol,
|
|
4230
4257
|
calldataHash: viem.keccak256(input.callData),
|
|
4231
|
-
|
|
4232
|
-
|
|
4258
|
+
tokens: resolvedTokens,
|
|
4259
|
+
amounts: inputTokens.map((t, i) => parseAmount(inputAmounts[i], t, this.chainId)),
|
|
4233
4260
|
value: input.value ?? 0n,
|
|
4234
|
-
extraTokens: input.extraTokens ?? [],
|
|
4235
|
-
extraAmounts: input.extraAmounts ?? [],
|
|
4236
4261
|
deadline: input.deadline ?? this._defaultDeadline(),
|
|
4237
4262
|
ref: this._resolveRef(input.memo, input.ref)
|
|
4238
4263
|
};
|
|
@@ -4246,6 +4271,38 @@ Timestamp: ${timestamp}`;
|
|
|
4246
4271
|
ref: this._resolveRef(input.memo, input.ref)
|
|
4247
4272
|
};
|
|
4248
4273
|
}
|
|
4274
|
+
async _submitPaymentWithSwap(intent, signature, input, swapIntent, swapSignature) {
|
|
4275
|
+
const idempotencyKey = generateUuid();
|
|
4276
|
+
const body = {
|
|
4277
|
+
// Routing
|
|
4278
|
+
chainId: this.chainId,
|
|
4279
|
+
vaultAddress: this.vaultAddress,
|
|
4280
|
+
// Flat intent fields (matches relayer DTO)
|
|
4281
|
+
bot: intent.bot,
|
|
4282
|
+
to: intent.to,
|
|
4283
|
+
token: intent.token,
|
|
4284
|
+
amount: intent.amount.toString(),
|
|
4285
|
+
deadline: intent.deadline.toString(),
|
|
4286
|
+
ref: intent.ref,
|
|
4287
|
+
signature,
|
|
4288
|
+
// Swap fields
|
|
4289
|
+
swapSignature,
|
|
4290
|
+
swapToToken: swapIntent.toToken,
|
|
4291
|
+
swapMinToAmount: swapIntent.minToAmount.toString(),
|
|
4292
|
+
swapDeadline: swapIntent.deadline.toString(),
|
|
4293
|
+
swapRef: swapIntent.ref,
|
|
4294
|
+
// Off-chain metadata
|
|
4295
|
+
idempotencyKey,
|
|
4296
|
+
...input.memo !== void 0 && { memo: input.memo },
|
|
4297
|
+
...input.resourceUrl !== void 0 && { resourceUrl: input.resourceUrl },
|
|
4298
|
+
...input.invoiceId !== void 0 && { invoiceId: input.invoiceId },
|
|
4299
|
+
...input.orderId !== void 0 && { orderId: input.orderId },
|
|
4300
|
+
...input.recipientLabel !== void 0 && { recipientLabel: input.recipientLabel },
|
|
4301
|
+
...input.metadata !== void 0 && { metadata: input.metadata },
|
|
4302
|
+
...input.x402Funding !== void 0 && { x402Funding: input.x402Funding }
|
|
4303
|
+
};
|
|
4304
|
+
return this._post(RELAYER_API.PAYMENTS, idempotencyKey, body);
|
|
4305
|
+
}
|
|
4249
4306
|
async _submitPayment(intent, signature, input) {
|
|
4250
4307
|
const idempotencyKey = input.idempotencyKey ?? generateUuid();
|
|
4251
4308
|
const body = {
|
|
@@ -4274,8 +4331,6 @@ Timestamp: ${timestamp}`;
|
|
|
4274
4331
|
}
|
|
4275
4332
|
async _submitExecute(intent, signature, input) {
|
|
4276
4333
|
const idempotencyKey = input.idempotencyKey ?? generateUuid();
|
|
4277
|
-
const fromToken = input.fromToken !== void 0 ? resolveToken(input.fromToken, this.chainId) : void 0;
|
|
4278
|
-
const maxFromAmount = input.maxFromAmount !== void 0 ? parseAmount(input.maxFromAmount, input.fromToken ?? input.token, this.chainId) : void 0;
|
|
4279
4334
|
const body = {
|
|
4280
4335
|
chainId: this.chainId,
|
|
4281
4336
|
vaultAddress: this.vaultAddress,
|
|
@@ -4283,17 +4338,14 @@ Timestamp: ${timestamp}`;
|
|
|
4283
4338
|
bot: intent.bot,
|
|
4284
4339
|
protocol: intent.protocol,
|
|
4285
4340
|
calldataHash: intent.calldataHash,
|
|
4286
|
-
|
|
4287
|
-
|
|
4341
|
+
tokens: intent.tokens,
|
|
4342
|
+
amounts: intent.amounts.map((a) => a.toString()),
|
|
4288
4343
|
value: intent.value.toString(),
|
|
4289
4344
|
deadline: intent.deadline.toString(),
|
|
4290
4345
|
ref: intent.ref,
|
|
4291
4346
|
signature,
|
|
4292
4347
|
// Protocol calldata
|
|
4293
4348
|
callData: input.callData,
|
|
4294
|
-
// Optional pre-swap
|
|
4295
|
-
...fromToken !== void 0 && { fromToken },
|
|
4296
|
-
...maxFromAmount !== void 0 && { maxFromAmount: maxFromAmount.toString() },
|
|
4297
4349
|
// Off-chain metadata
|
|
4298
4350
|
idempotencyKey,
|
|
4299
4351
|
...input.memo !== void 0 && { memo: input.memo },
|