@hypurrquant/defi-cli 0.2.3 → 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.
@@ -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 = 100000000n;
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) return _Executor.applyGasBuffer(estimated);
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: encodeFunctionData23, parseAbi: parseAbi26 } = await import("viem");
5506
- const POOL_ABI3 = parseAbi26([
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 = encodeFunctionData23({ abi: POOL_ABI3, functionName: "getUserAccountData", args: [user] });
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;