@hypurrquant/defi-cli 0.2.4 → 0.2.5
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/config/tokens/hyperevm.toml +1 -1
- package/dist/index.js +139 -37
- package/dist/index.js.map +1 -1
- package/dist/main.js +139 -37
- package/dist/main.js.map +1 -1
- package/dist/mcp-server.js +123 -21
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -1542,7 +1542,8 @@ var init_dist3 = __esm({
|
|
|
1542
1542
|
to: this.router,
|
|
1543
1543
|
data,
|
|
1544
1544
|
value: 0n,
|
|
1545
|
-
gas_estimate: 2e5
|
|
1545
|
+
gas_estimate: 2e5,
|
|
1546
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
1546
1547
|
};
|
|
1547
1548
|
}
|
|
1548
1549
|
async quote(params) {
|
|
@@ -1712,7 +1713,11 @@ var init_dist3 = __esm({
|
|
|
1712
1713
|
to: pm,
|
|
1713
1714
|
data,
|
|
1714
1715
|
value: 0n,
|
|
1715
|
-
gas_estimate: 5e5
|
|
1716
|
+
gas_estimate: 5e5,
|
|
1717
|
+
approvals: [
|
|
1718
|
+
{ token: token0, spender: pm, amount: amount0 },
|
|
1719
|
+
{ token: token1, spender: pm, amount: amount1 }
|
|
1720
|
+
]
|
|
1716
1721
|
};
|
|
1717
1722
|
}
|
|
1718
1723
|
async buildRemoveLiquidity(_params) {
|
|
@@ -1771,7 +1776,8 @@ var init_dist3 = __esm({
|
|
|
1771
1776
|
to: this.router,
|
|
1772
1777
|
data,
|
|
1773
1778
|
value: 0n,
|
|
1774
|
-
gas_estimate: 15e4
|
|
1779
|
+
gas_estimate: 15e4,
|
|
1780
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
1775
1781
|
};
|
|
1776
1782
|
}
|
|
1777
1783
|
async quote(params) {
|
|
@@ -1890,7 +1896,11 @@ var init_dist3 = __esm({
|
|
|
1890
1896
|
to: this.router,
|
|
1891
1897
|
data,
|
|
1892
1898
|
value: 0n,
|
|
1893
|
-
gas_estimate: 3e5
|
|
1899
|
+
gas_estimate: 3e5,
|
|
1900
|
+
approvals: [
|
|
1901
|
+
{ token: params.token_a, spender: this.router, amount: params.amount_a },
|
|
1902
|
+
{ token: params.token_b, spender: this.router, amount: params.amount_b }
|
|
1903
|
+
]
|
|
1894
1904
|
};
|
|
1895
1905
|
}
|
|
1896
1906
|
async buildRemoveLiquidity(params) {
|
|
@@ -1977,7 +1987,8 @@ var init_dist3 = __esm({
|
|
|
1977
1987
|
to: this.router,
|
|
1978
1988
|
data,
|
|
1979
1989
|
value: 0n,
|
|
1980
|
-
gas_estimate: 25e4
|
|
1990
|
+
gas_estimate: 25e4,
|
|
1991
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
1981
1992
|
};
|
|
1982
1993
|
}
|
|
1983
1994
|
async quote(params) {
|
|
@@ -2095,7 +2106,11 @@ var init_dist3 = __esm({
|
|
|
2095
2106
|
to: pm,
|
|
2096
2107
|
data,
|
|
2097
2108
|
value: 0n,
|
|
2098
|
-
gas_estimate: 5e5
|
|
2109
|
+
gas_estimate: 5e5,
|
|
2110
|
+
approvals: [
|
|
2111
|
+
{ token: token0, spender: pm, amount: amount0 },
|
|
2112
|
+
{ token: token1, spender: pm, amount: amount1 }
|
|
2113
|
+
]
|
|
2099
2114
|
};
|
|
2100
2115
|
}
|
|
2101
2116
|
async buildRemoveLiquidity(_params) {
|
|
@@ -2272,7 +2287,8 @@ var init_dist3 = __esm({
|
|
|
2272
2287
|
to: this.router,
|
|
2273
2288
|
data,
|
|
2274
2289
|
value: 0n,
|
|
2275
|
-
gas_estimate: 2e5
|
|
2290
|
+
gas_estimate: 2e5,
|
|
2291
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
2276
2292
|
};
|
|
2277
2293
|
}
|
|
2278
2294
|
async callGetAmountsOut(client, callData) {
|
|
@@ -2355,7 +2371,11 @@ var init_dist3 = __esm({
|
|
|
2355
2371
|
to: this.router,
|
|
2356
2372
|
data,
|
|
2357
2373
|
value: 0n,
|
|
2358
|
-
gas_estimate: 35e4
|
|
2374
|
+
gas_estimate: 35e4,
|
|
2375
|
+
approvals: [
|
|
2376
|
+
{ token: params.token_a, spender: this.router, amount: params.amount_a },
|
|
2377
|
+
{ token: params.token_b, spender: this.router, amount: params.amount_b }
|
|
2378
|
+
]
|
|
2359
2379
|
};
|
|
2360
2380
|
}
|
|
2361
2381
|
async buildRemoveLiquidity(params) {
|
|
@@ -2481,7 +2501,7 @@ var init_dist3 = __esm({
|
|
|
2481
2501
|
return this.protocolName;
|
|
2482
2502
|
}
|
|
2483
2503
|
// IGauge
|
|
2484
|
-
async buildDeposit(gauge, amount, tokenId) {
|
|
2504
|
+
async buildDeposit(gauge, amount, tokenId, lpToken) {
|
|
2485
2505
|
if (tokenId !== void 0) {
|
|
2486
2506
|
const data2 = encodeFunctionData8({
|
|
2487
2507
|
abi: gaugeAbi,
|
|
@@ -2493,7 +2513,8 @@ var init_dist3 = __esm({
|
|
|
2493
2513
|
to: gauge,
|
|
2494
2514
|
data: data2,
|
|
2495
2515
|
value: 0n,
|
|
2496
|
-
gas_estimate: 2e5
|
|
2516
|
+
gas_estimate: 2e5,
|
|
2517
|
+
approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
|
|
2497
2518
|
};
|
|
2498
2519
|
}
|
|
2499
2520
|
const data = encodeFunctionData8({
|
|
@@ -2506,7 +2527,8 @@ var init_dist3 = __esm({
|
|
|
2506
2527
|
to: gauge,
|
|
2507
2528
|
data,
|
|
2508
2529
|
value: 0n,
|
|
2509
|
-
gas_estimate: 2e5
|
|
2530
|
+
gas_estimate: 2e5,
|
|
2531
|
+
approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
|
|
2510
2532
|
};
|
|
2511
2533
|
}
|
|
2512
2534
|
async buildWithdraw(gauge, amount) {
|
|
@@ -2854,7 +2876,8 @@ var init_dist3 = __esm({
|
|
|
2854
2876
|
to: this.pool,
|
|
2855
2877
|
data,
|
|
2856
2878
|
value: 0n,
|
|
2857
|
-
gas_estimate: 3e5
|
|
2879
|
+
gas_estimate: 3e5,
|
|
2880
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
2858
2881
|
};
|
|
2859
2882
|
}
|
|
2860
2883
|
async buildBorrow(params) {
|
|
@@ -2884,7 +2907,8 @@ var init_dist3 = __esm({
|
|
|
2884
2907
|
to: this.pool,
|
|
2885
2908
|
data,
|
|
2886
2909
|
value: 0n,
|
|
2887
|
-
gas_estimate: 3e5
|
|
2910
|
+
gas_estimate: 3e5,
|
|
2911
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
2888
2912
|
};
|
|
2889
2913
|
}
|
|
2890
2914
|
async buildWithdraw(params) {
|
|
@@ -3183,7 +3207,8 @@ var init_dist3 = __esm({
|
|
|
3183
3207
|
to: this.pool,
|
|
3184
3208
|
data,
|
|
3185
3209
|
value: 0n,
|
|
3186
|
-
gas_estimate: 3e5
|
|
3210
|
+
gas_estimate: 3e5,
|
|
3211
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
3187
3212
|
};
|
|
3188
3213
|
}
|
|
3189
3214
|
async buildBorrow(params) {
|
|
@@ -3213,7 +3238,8 @@ var init_dist3 = __esm({
|
|
|
3213
3238
|
to: this.pool,
|
|
3214
3239
|
data,
|
|
3215
3240
|
value: 0n,
|
|
3216
|
-
gas_estimate: 3e5
|
|
3241
|
+
gas_estimate: 3e5,
|
|
3242
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
3217
3243
|
};
|
|
3218
3244
|
}
|
|
3219
3245
|
async buildWithdraw(params) {
|
|
@@ -4747,10 +4773,15 @@ import { z } from "zod";
|
|
|
4747
4773
|
|
|
4748
4774
|
// src/executor.ts
|
|
4749
4775
|
init_dist2();
|
|
4750
|
-
import { createPublicClient as createPublicClient20, createWalletClient, http as http20 } from "viem";
|
|
4776
|
+
import { createPublicClient as createPublicClient20, createWalletClient, http as http20, parseAbi as parseAbi26, encodeFunctionData as encodeFunctionData23 } from "viem";
|
|
4751
4777
|
import { privateKeyToAccount } from "viem/accounts";
|
|
4778
|
+
var ERC20_ABI4 = parseAbi26([
|
|
4779
|
+
"function allowance(address owner, address spender) external view returns (uint256)",
|
|
4780
|
+
"function approve(address spender, uint256 amount) external returns (bool)"
|
|
4781
|
+
]);
|
|
4752
4782
|
var GAS_BUFFER_BPS = 12000n;
|
|
4753
|
-
var DEFAULT_PRIORITY_FEE_WEI =
|
|
4783
|
+
var DEFAULT_PRIORITY_FEE_WEI = 20000000000n;
|
|
4784
|
+
var MAX_GAS_LIMIT = 5000000000n;
|
|
4754
4785
|
var Executor = class _Executor {
|
|
4755
4786
|
dryRun;
|
|
4756
4787
|
rpcUrl;
|
|
@@ -4764,6 +4795,62 @@ var Executor = class _Executor {
|
|
|
4764
4795
|
static applyGasBuffer(gas) {
|
|
4765
4796
|
return gas * GAS_BUFFER_BPS / 10000n;
|
|
4766
4797
|
}
|
|
4798
|
+
/**
|
|
4799
|
+
* Check allowance for a single token/spender pair and send an approve tx if needed.
|
|
4800
|
+
* Only called in broadcast mode (not dry-run).
|
|
4801
|
+
*/
|
|
4802
|
+
async checkAndApprove(token, spender, amount, owner, publicClient, walletClient) {
|
|
4803
|
+
const allowance = await publicClient.readContract({
|
|
4804
|
+
address: token,
|
|
4805
|
+
abi: ERC20_ABI4,
|
|
4806
|
+
functionName: "allowance",
|
|
4807
|
+
args: [owner, spender]
|
|
4808
|
+
});
|
|
4809
|
+
if (allowance >= amount) return;
|
|
4810
|
+
process.stderr.write(
|
|
4811
|
+
` Approving ${amount} of ${token} for ${spender}...
|
|
4812
|
+
`
|
|
4813
|
+
);
|
|
4814
|
+
const approveData = encodeFunctionData23({
|
|
4815
|
+
abi: ERC20_ABI4,
|
|
4816
|
+
functionName: "approve",
|
|
4817
|
+
args: [spender, amount]
|
|
4818
|
+
});
|
|
4819
|
+
const rpcUrl = this.rpcUrl;
|
|
4820
|
+
const gasLimit = await (async () => {
|
|
4821
|
+
try {
|
|
4822
|
+
const estimated = await publicClient.estimateGas({
|
|
4823
|
+
to: token,
|
|
4824
|
+
data: approveData,
|
|
4825
|
+
account: owner
|
|
4826
|
+
});
|
|
4827
|
+
const buffered = _Executor.applyGasBuffer(estimated);
|
|
4828
|
+
return buffered > MAX_GAS_LIMIT ? MAX_GAS_LIMIT : buffered;
|
|
4829
|
+
} catch {
|
|
4830
|
+
return 80000n;
|
|
4831
|
+
}
|
|
4832
|
+
})();
|
|
4833
|
+
const [maxFeePerGas, maxPriorityFeePerGas] = await this.fetchEip1559Fees(rpcUrl);
|
|
4834
|
+
const approveTxHash = await walletClient.sendTransaction({
|
|
4835
|
+
chain: null,
|
|
4836
|
+
account: walletClient.account,
|
|
4837
|
+
to: token,
|
|
4838
|
+
data: approveData,
|
|
4839
|
+
gas: gasLimit > 0n ? gasLimit : void 0,
|
|
4840
|
+
maxFeePerGas: maxFeePerGas > 0n ? maxFeePerGas : void 0,
|
|
4841
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas > 0n ? maxPriorityFeePerGas : void 0
|
|
4842
|
+
});
|
|
4843
|
+
const approveTxUrl = this.explorerUrl ? `${this.explorerUrl}/tx/${approveTxHash}` : void 0;
|
|
4844
|
+
process.stderr.write(` Approve tx: ${approveTxHash}
|
|
4845
|
+
`);
|
|
4846
|
+
if (approveTxUrl) process.stderr.write(` Explorer: ${approveTxUrl}
|
|
4847
|
+
`);
|
|
4848
|
+
await publicClient.waitForTransactionReceipt({ hash: approveTxHash });
|
|
4849
|
+
process.stderr.write(
|
|
4850
|
+
` Approved ${amount} of ${token} for ${spender}
|
|
4851
|
+
`
|
|
4852
|
+
);
|
|
4853
|
+
}
|
|
4767
4854
|
/** Fetch EIP-1559 fee params from the network. Returns [maxFeePerGas, maxPriorityFeePerGas]. */
|
|
4768
4855
|
async fetchEip1559Fees(rpcUrl) {
|
|
4769
4856
|
try {
|
|
@@ -4790,7 +4877,10 @@ var Executor = class _Executor {
|
|
|
4790
4877
|
value: tx.value,
|
|
4791
4878
|
account: from
|
|
4792
4879
|
});
|
|
4793
|
-
if (estimated > 0n)
|
|
4880
|
+
if (estimated > 0n) {
|
|
4881
|
+
const buffered = _Executor.applyGasBuffer(estimated);
|
|
4882
|
+
return buffered > MAX_GAS_LIMIT ? MAX_GAS_LIMIT : buffered;
|
|
4883
|
+
}
|
|
4794
4884
|
} catch {
|
|
4795
4885
|
}
|
|
4796
4886
|
return tx.gas_estimate ? BigInt(tx.gas_estimate) : 0n;
|
|
@@ -4876,6 +4966,18 @@ var Executor = class _Executor {
|
|
|
4876
4966
|
}
|
|
4877
4967
|
const publicClient = createPublicClient20({ transport: http20(rpcUrl) });
|
|
4878
4968
|
const walletClient = createWalletClient({ account, transport: http20(rpcUrl) });
|
|
4969
|
+
if (tx.approvals && tx.approvals.length > 0) {
|
|
4970
|
+
for (const approval of tx.approvals) {
|
|
4971
|
+
await this.checkAndApprove(
|
|
4972
|
+
approval.token,
|
|
4973
|
+
approval.spender,
|
|
4974
|
+
approval.amount,
|
|
4975
|
+
account.address,
|
|
4976
|
+
publicClient,
|
|
4977
|
+
walletClient
|
|
4978
|
+
);
|
|
4979
|
+
}
|
|
4980
|
+
}
|
|
4879
4981
|
const gasLimit = await this.estimateGasWithBuffer(rpcUrl, tx, account.address);
|
|
4880
4982
|
const [maxFeePerGas, maxPriorityFeePerGas] = await this.fetchEip1559Fees(rpcUrl);
|
|
4881
4983
|
process.stderr.write(`Broadcasting transaction to ${rpcUrl}...
|
|
@@ -5502,8 +5604,8 @@ server.tool(
|
|
|
5502
5604
|
const user = address;
|
|
5503
5605
|
const { ProtocolCategory: ProtocolCategory2, multicallRead: multicallRead2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
5504
5606
|
const { createLending: _createLending } = await Promise.resolve().then(() => (init_dist3(), dist_exports2));
|
|
5505
|
-
const { encodeFunctionData:
|
|
5506
|
-
const POOL_ABI3 =
|
|
5607
|
+
const { encodeFunctionData: encodeFunctionData24, parseAbi: parseAbi27 } = await import("viem");
|
|
5608
|
+
const POOL_ABI3 = parseAbi27([
|
|
5507
5609
|
"function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)"
|
|
5508
5610
|
]);
|
|
5509
5611
|
const lendingProtos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory2.Lending);
|
|
@@ -5512,7 +5614,7 @@ server.tool(
|
|
|
5512
5614
|
const poolAddr = p.contracts?.pool;
|
|
5513
5615
|
if (!poolAddr) continue;
|
|
5514
5616
|
try {
|
|
5515
|
-
const callData =
|
|
5617
|
+
const callData = encodeFunctionData24({ abi: POOL_ABI3, functionName: "getUserAccountData", args: [user] });
|
|
5516
5618
|
const results = await multicallRead2(rpcUrl, [[poolAddr, callData]]);
|
|
5517
5619
|
const raw = results[0];
|
|
5518
5620
|
if (!raw || raw.length < 2 + 6 * 64) continue;
|