@hypurrquant/defi-cli 1.0.7 → 1.0.9
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/dist/index.js +250 -52
- package/dist/index.js.map +1 -1
- package/dist/main.js +250 -52
- package/dist/main.js.map +1 -1
- package/dist/mcp-server.js +231 -47
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
- package/skills/defi-cli/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4077,6 +4077,79 @@ var init_dist2 = __esm({
|
|
|
4077
4077
|
gas_estimate: 3e5
|
|
4078
4078
|
};
|
|
4079
4079
|
}
|
|
4080
|
+
/**
|
|
4081
|
+
* List every LB pair from the factory with basic pair info (no rewarder /
|
|
4082
|
+
* APR enrichment). Useful when the factory has pools but none have hooks
|
|
4083
|
+
* deployed yet (e.g. early-stage Monad TraderJoe).
|
|
4084
|
+
*
|
|
4085
|
+
* Three multicall batches: pair addresses, token addresses, token symbols.
|
|
4086
|
+
*/
|
|
4087
|
+
async discoverAllPools() {
|
|
4088
|
+
const rpcUrl = this.requireRpc();
|
|
4089
|
+
const client = createPublicClient8({ transport: http8(rpcUrl) });
|
|
4090
|
+
const pairCount = await client.readContract({
|
|
4091
|
+
address: this.lbFactory,
|
|
4092
|
+
abi: lbFactoryAbi,
|
|
4093
|
+
functionName: "getNumberOfLBPairs"
|
|
4094
|
+
});
|
|
4095
|
+
const count = Number(pairCount);
|
|
4096
|
+
if (count === 0) return [];
|
|
4097
|
+
const indexCalls = Array.from({ length: count }, (_, i) => [
|
|
4098
|
+
this.lbFactory,
|
|
4099
|
+
encodeFunctionData12({ abi: lbFactoryAbi, functionName: "getLBPairAtIndex", args: [BigInt(i)] })
|
|
4100
|
+
]);
|
|
4101
|
+
const indexResults = await multicallRead(rpcUrl, indexCalls);
|
|
4102
|
+
const pairs = indexResults.map((r) => decodeAddressResult(r)).filter((a) => a !== null);
|
|
4103
|
+
if (pairs.length === 0) return [];
|
|
4104
|
+
const tokenCalls = [];
|
|
4105
|
+
for (const pool of pairs) {
|
|
4106
|
+
tokenCalls.push([pool, encodeFunctionData12({ abi: lbPairAbi, functionName: "getTokenX" })]);
|
|
4107
|
+
tokenCalls.push([pool, encodeFunctionData12({ abi: lbPairAbi, functionName: "getTokenY" })]);
|
|
4108
|
+
}
|
|
4109
|
+
const tokenResults = await multicallRead(rpcUrl, tokenCalls);
|
|
4110
|
+
const tokensX = [];
|
|
4111
|
+
const tokensY = [];
|
|
4112
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
4113
|
+
tokensX.push(decodeAddressResult(tokenResults[i * 2] ?? null));
|
|
4114
|
+
tokensY.push(decodeAddressResult(tokenResults[i * 2 + 1] ?? null));
|
|
4115
|
+
}
|
|
4116
|
+
const uniqueTokens = Array.from(
|
|
4117
|
+
new Set([...tokensX, ...tokensY].filter((a) => a !== null))
|
|
4118
|
+
);
|
|
4119
|
+
const symbolCalls = uniqueTokens.map((t) => [
|
|
4120
|
+
t,
|
|
4121
|
+
encodeFunctionData12({ abi: erc20Abi2, functionName: "symbol" })
|
|
4122
|
+
]);
|
|
4123
|
+
const symbolResults = await multicallRead(rpcUrl, symbolCalls);
|
|
4124
|
+
const symbolMap = /* @__PURE__ */ new Map();
|
|
4125
|
+
for (let i = 0; i < uniqueTokens.length; i++) {
|
|
4126
|
+
const raw = symbolResults[i];
|
|
4127
|
+
if (!raw) continue;
|
|
4128
|
+
try {
|
|
4129
|
+
const sym = decodeFunctionResult4({
|
|
4130
|
+
abi: parseAbi12(["function f() external view returns (string)"]),
|
|
4131
|
+
functionName: "f",
|
|
4132
|
+
data: raw
|
|
4133
|
+
});
|
|
4134
|
+
symbolMap.set(uniqueTokens[i].toLowerCase(), sym);
|
|
4135
|
+
} catch {
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
const out = [];
|
|
4139
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
4140
|
+
const tx = tokensX[i];
|
|
4141
|
+
const ty = tokensY[i];
|
|
4142
|
+
if (!tx || !ty) continue;
|
|
4143
|
+
out.push({
|
|
4144
|
+
pool: pairs[i],
|
|
4145
|
+
tokenX: tx,
|
|
4146
|
+
tokenY: ty,
|
|
4147
|
+
symbolX: symbolMap.get(tx.toLowerCase()) ?? "?",
|
|
4148
|
+
symbolY: symbolMap.get(ty.toLowerCase()) ?? "?"
|
|
4149
|
+
});
|
|
4150
|
+
}
|
|
4151
|
+
return out;
|
|
4152
|
+
}
|
|
4080
4153
|
/**
|
|
4081
4154
|
* Discover all active rewarded LB pools by iterating the factory.
|
|
4082
4155
|
* Uses 7 multicall batches to minimise RPC round-trips and avoid 429s.
|
|
@@ -5057,6 +5130,7 @@ var init_dist2 = __esm({
|
|
|
5057
5130
|
"function repay(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf) external returns (uint256)",
|
|
5058
5131
|
"function withdraw(address asset, uint256 amount, address to) external returns (uint256)",
|
|
5059
5132
|
"function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)",
|
|
5133
|
+
"function getReservesList() external view returns (address[])",
|
|
5060
5134
|
"function getReserveData(address asset) external view returns (uint256 configuration, uint128 liquidityIndex, uint128 currentLiquidityRate, uint128 variableBorrowIndex, uint128 currentVariableBorrowRate, uint128 currentStableBorrowRate, uint40 lastUpdateTimestamp, uint16 id, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint128 accruedToTreasury, uint128 unbacked, uint128 isolationModeTotalDebt)"
|
|
5061
5135
|
]);
|
|
5062
5136
|
ERC20_ABI2 = parseAbi14([
|
|
@@ -5143,13 +5217,37 @@ var init_dist2 = __esm({
|
|
|
5143
5217
|
};
|
|
5144
5218
|
}
|
|
5145
5219
|
async buildWithdraw(params) {
|
|
5220
|
+
let withdrawAmount = params.amount;
|
|
5221
|
+
if (this.rpcUrl) {
|
|
5222
|
+
try {
|
|
5223
|
+
const client = createPublicClient10({ transport: http10(this.rpcUrl) });
|
|
5224
|
+
const reserveData = await client.readContract({
|
|
5225
|
+
address: this.pool,
|
|
5226
|
+
abi: POOL_ABI,
|
|
5227
|
+
functionName: "getReserveData",
|
|
5228
|
+
args: [params.asset]
|
|
5229
|
+
});
|
|
5230
|
+
const aToken = reserveData[8];
|
|
5231
|
+
const aBal = await client.readContract({
|
|
5232
|
+
address: aToken,
|
|
5233
|
+
abi: parseAbi14(["function balanceOf(address) view returns (uint256)"]),
|
|
5234
|
+
functionName: "balanceOf",
|
|
5235
|
+
args: [params.to]
|
|
5236
|
+
});
|
|
5237
|
+
if (aBal > 0n && params.amount >= aBal) {
|
|
5238
|
+
withdrawAmount = (1n << 256n) - 1n;
|
|
5239
|
+
}
|
|
5240
|
+
} catch {
|
|
5241
|
+
}
|
|
5242
|
+
}
|
|
5146
5243
|
const data = encodeFunctionData14({
|
|
5147
5244
|
abi: POOL_ABI,
|
|
5148
5245
|
functionName: "withdraw",
|
|
5149
|
-
args: [params.asset,
|
|
5246
|
+
args: [params.asset, withdrawAmount, params.to]
|
|
5150
5247
|
});
|
|
5248
|
+
const isMax = withdrawAmount === (1n << 256n) - 1n;
|
|
5151
5249
|
return {
|
|
5152
|
-
description: `[${this.protocolName}] Withdraw ${
|
|
5250
|
+
description: `[${this.protocolName}] Withdraw ${isMax ? "all (auto-max)" : withdrawAmount} from pool`,
|
|
5153
5251
|
to: this.pool,
|
|
5154
5252
|
data,
|
|
5155
5253
|
value: 0n,
|
|
@@ -5343,7 +5441,7 @@ var init_dist2 = __esm({
|
|
|
5343
5441
|
async getUserPosition(user) {
|
|
5344
5442
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
5345
5443
|
const client = createPublicClient10({ transport: http10(this.rpcUrl) });
|
|
5346
|
-
const
|
|
5444
|
+
const accountData = await client.readContract({
|
|
5347
5445
|
address: this.pool,
|
|
5348
5446
|
abi: POOL_ABI,
|
|
5349
5447
|
functionName: "getUserAccountData",
|
|
@@ -5351,21 +5449,63 @@ var init_dist2 = __esm({
|
|
|
5351
5449
|
}).catch((e) => {
|
|
5352
5450
|
throw DefiError.rpcError(`[${this.protocolName}] getUserAccountData failed: ${e}`);
|
|
5353
5451
|
});
|
|
5354
|
-
const [totalCollateralBase, totalDebtBase, , , ltv, healthFactor] =
|
|
5452
|
+
const [totalCollateralBase, totalDebtBase, , , ltv, healthFactor] = accountData;
|
|
5355
5453
|
const MAX_UINT2562 = 2n ** 256n - 1n;
|
|
5356
|
-
const hf = healthFactor >= MAX_UINT2562 ?
|
|
5454
|
+
const hf = healthFactor >= MAX_UINT2562 ? null : Number(healthFactor) / 1e18;
|
|
5357
5455
|
const collateralUsd = u256ToF64(totalCollateralBase) / 1e8;
|
|
5358
5456
|
const debtUsd = u256ToF64(totalDebtBase) / 1e8;
|
|
5359
|
-
const
|
|
5360
|
-
const supplies =
|
|
5361
|
-
const borrows =
|
|
5457
|
+
const ltvPct = u256ToF64(ltv) / 100;
|
|
5458
|
+
const supplies = [];
|
|
5459
|
+
const borrows = [];
|
|
5460
|
+
try {
|
|
5461
|
+
const reserves = await client.readContract({
|
|
5462
|
+
address: this.pool,
|
|
5463
|
+
abi: POOL_ABI,
|
|
5464
|
+
functionName: "getReservesList"
|
|
5465
|
+
});
|
|
5466
|
+
const reserveData = await Promise.allSettled(reserves.map(async (asset) => {
|
|
5467
|
+
const data = await client.readContract({
|
|
5468
|
+
address: this.pool,
|
|
5469
|
+
abi: POOL_ABI,
|
|
5470
|
+
functionName: "getReserveData",
|
|
5471
|
+
args: [asset]
|
|
5472
|
+
});
|
|
5473
|
+
const aToken = data[8];
|
|
5474
|
+
const debtToken = data[10];
|
|
5475
|
+
return { asset, aToken, debtToken };
|
|
5476
|
+
}));
|
|
5477
|
+
const ERC20_ABI42 = parseAbi14([
|
|
5478
|
+
"function balanceOf(address) view returns (uint256)",
|
|
5479
|
+
"function symbol() view returns (string)"
|
|
5480
|
+
]);
|
|
5481
|
+
const positions = await Promise.allSettled(reserveData.map(async (r) => {
|
|
5482
|
+
if (r.status !== "fulfilled") return null;
|
|
5483
|
+
const { asset, aToken, debtToken } = r.value;
|
|
5484
|
+
const [aBal, dBal, sym] = await Promise.all([
|
|
5485
|
+
client.readContract({ address: aToken, abi: ERC20_ABI42, functionName: "balanceOf", args: [user] }),
|
|
5486
|
+
client.readContract({ address: debtToken, abi: ERC20_ABI42, functionName: "balanceOf", args: [user] }),
|
|
5487
|
+
client.readContract({ address: asset, abi: ERC20_ABI42, functionName: "symbol" }).catch(() => "?")
|
|
5488
|
+
]);
|
|
5489
|
+
return { asset, symbol: sym, supply: aBal, borrow: dBal };
|
|
5490
|
+
}));
|
|
5491
|
+
for (const p of positions) {
|
|
5492
|
+
if (p.status !== "fulfilled" || !p.value) continue;
|
|
5493
|
+
if (p.value.supply > 0n) supplies.push({ asset: p.value.asset, symbol: p.value.symbol, amount: p.value.supply });
|
|
5494
|
+
if (p.value.borrow > 0n) borrows.push({ asset: p.value.asset, symbol: p.value.symbol, amount: p.value.borrow });
|
|
5495
|
+
}
|
|
5496
|
+
} catch {
|
|
5497
|
+
if (collateralUsd > 0) supplies.push({ asset: zeroAddress8, symbol: "Total Collateral (per-asset breakdown unavailable)", amount: totalCollateralBase });
|
|
5498
|
+
if (debtUsd > 0) borrows.push({ asset: zeroAddress8, symbol: "Total Debt (per-asset breakdown unavailable)", amount: totalDebtBase });
|
|
5499
|
+
}
|
|
5362
5500
|
return {
|
|
5363
5501
|
protocol: this.protocolName,
|
|
5364
5502
|
user,
|
|
5365
5503
|
supplies,
|
|
5366
5504
|
borrows,
|
|
5367
5505
|
health_factor: hf,
|
|
5368
|
-
|
|
5506
|
+
ltv_pct: ltvPct,
|
|
5507
|
+
total_collateral_usd: collateralUsd,
|
|
5508
|
+
total_debt_usd: debtUsd
|
|
5369
5509
|
};
|
|
5370
5510
|
}
|
|
5371
5511
|
};
|
|
@@ -5622,6 +5762,7 @@ var init_dist2 = __esm({
|
|
|
5622
5762
|
"function borrowBalanceStored(address account) external view returns (uint256)",
|
|
5623
5763
|
"function mint(uint256 mintAmount) external returns (uint256)",
|
|
5624
5764
|
"function redeem(uint256 redeemTokens) external returns (uint256)",
|
|
5765
|
+
"function redeemUnderlying(uint256 redeemAmount) external returns (uint256)",
|
|
5625
5766
|
"function borrow(uint256 borrowAmount) external returns (uint256)",
|
|
5626
5767
|
"function repayBorrow(uint256 repayAmount) external returns (uint256)"
|
|
5627
5768
|
]);
|
|
@@ -5664,57 +5805,55 @@ var init_dist2 = __esm({
|
|
|
5664
5805
|
name() {
|
|
5665
5806
|
return this.protocolName;
|
|
5666
5807
|
}
|
|
5808
|
+
// Resolve the vToken whose underlying() matches params.asset. Compound V2 has
|
|
5809
|
+
// a separate vToken per asset, so all builders must dispatch on the request
|
|
5810
|
+
// asset. Returns the resolved vToken or throws if no candidate matches.
|
|
5811
|
+
async vtokenFor(asset) {
|
|
5812
|
+
const v = await this.resolveVtoken(asset);
|
|
5813
|
+
if (!v) throw DefiError.contractError(`[${this.protocolName}] no vToken for asset ${asset}`);
|
|
5814
|
+
return v;
|
|
5815
|
+
}
|
|
5667
5816
|
async buildSupply(params) {
|
|
5668
|
-
const
|
|
5669
|
-
|
|
5670
|
-
functionName: "mint",
|
|
5671
|
-
args: [params.amount]
|
|
5672
|
-
});
|
|
5817
|
+
const vtoken = await this.vtokenFor(params.asset);
|
|
5818
|
+
const data = encodeFunctionData16({ abi: CTOKEN_ABI, functionName: "mint", args: [params.amount] });
|
|
5673
5819
|
return {
|
|
5674
|
-
description: `[${this.protocolName}] Supply ${params.amount} to Venus`,
|
|
5675
|
-
to:
|
|
5820
|
+
description: `[${this.protocolName}] Supply ${params.amount} of ${params.asset} to Venus`,
|
|
5821
|
+
to: vtoken,
|
|
5676
5822
|
data,
|
|
5677
5823
|
value: 0n,
|
|
5678
|
-
gas_estimate: 3e5
|
|
5824
|
+
gas_estimate: 3e5,
|
|
5825
|
+
approvals: [{ token: params.asset, spender: vtoken, amount: params.amount }]
|
|
5679
5826
|
};
|
|
5680
5827
|
}
|
|
5681
5828
|
async buildBorrow(params) {
|
|
5682
|
-
const
|
|
5683
|
-
|
|
5684
|
-
functionName: "borrow",
|
|
5685
|
-
args: [params.amount]
|
|
5686
|
-
});
|
|
5829
|
+
const vtoken = await this.vtokenFor(params.asset);
|
|
5830
|
+
const data = encodeFunctionData16({ abi: CTOKEN_ABI, functionName: "borrow", args: [params.amount] });
|
|
5687
5831
|
return {
|
|
5688
|
-
description: `[${this.protocolName}] Borrow ${params.amount} from Venus`,
|
|
5689
|
-
to:
|
|
5832
|
+
description: `[${this.protocolName}] Borrow ${params.amount} of ${params.asset} from Venus`,
|
|
5833
|
+
to: vtoken,
|
|
5690
5834
|
data,
|
|
5691
5835
|
value: 0n,
|
|
5692
5836
|
gas_estimate: 35e4
|
|
5693
5837
|
};
|
|
5694
5838
|
}
|
|
5695
5839
|
async buildRepay(params) {
|
|
5696
|
-
const
|
|
5697
|
-
|
|
5698
|
-
functionName: "repayBorrow",
|
|
5699
|
-
args: [params.amount]
|
|
5700
|
-
});
|
|
5840
|
+
const vtoken = await this.vtokenFor(params.asset);
|
|
5841
|
+
const data = encodeFunctionData16({ abi: CTOKEN_ABI, functionName: "repayBorrow", args: [params.amount] });
|
|
5701
5842
|
return {
|
|
5702
|
-
description: `[${this.protocolName}] Repay ${params.amount} to Venus`,
|
|
5703
|
-
to:
|
|
5843
|
+
description: `[${this.protocolName}] Repay ${params.amount} of ${params.asset} to Venus`,
|
|
5844
|
+
to: vtoken,
|
|
5704
5845
|
data,
|
|
5705
5846
|
value: 0n,
|
|
5706
|
-
gas_estimate: 3e5
|
|
5847
|
+
gas_estimate: 3e5,
|
|
5848
|
+
approvals: [{ token: params.asset, spender: vtoken, amount: params.amount }]
|
|
5707
5849
|
};
|
|
5708
5850
|
}
|
|
5709
5851
|
async buildWithdraw(params) {
|
|
5710
|
-
const
|
|
5711
|
-
|
|
5712
|
-
functionName: "redeem",
|
|
5713
|
-
args: [params.amount]
|
|
5714
|
-
});
|
|
5852
|
+
const vtoken = await this.vtokenFor(params.asset);
|
|
5853
|
+
const data = encodeFunctionData16({ abi: CTOKEN_ABI, functionName: "redeemUnderlying", args: [params.amount] });
|
|
5715
5854
|
return {
|
|
5716
|
-
description: `[${this.protocolName}] Withdraw from Venus`,
|
|
5717
|
-
to:
|
|
5855
|
+
description: `[${this.protocolName}] Withdraw ${params.amount} of ${params.asset} from Venus`,
|
|
5856
|
+
to: vtoken,
|
|
5718
5857
|
data,
|
|
5719
5858
|
value: 0n,
|
|
5720
5859
|
gas_estimate: 25e4
|
|
@@ -7244,24 +7383,69 @@ var Executor = class _Executor {
|
|
|
7244
7383
|
`);
|
|
7245
7384
|
if (approveTxUrl) process.stderr.write(` Explorer: ${approveTxUrl}
|
|
7246
7385
|
`);
|
|
7247
|
-
await
|
|
7386
|
+
const approveReceipt = await _Executor.waitForReceiptWithRetry(publicClient, approveTxHash);
|
|
7387
|
+
if (approveReceipt.status !== "success") {
|
|
7388
|
+
throw new Error(`Approve tx ${approveTxHash} reverted on-chain (status=${approveReceipt.status}). Aborting downstream tx.`);
|
|
7389
|
+
}
|
|
7248
7390
|
process.stderr.write(
|
|
7249
7391
|
` Approved ${amount} of ${token} for ${spender}
|
|
7250
7392
|
`
|
|
7251
7393
|
);
|
|
7252
7394
|
}
|
|
7253
|
-
/**
|
|
7395
|
+
/**
|
|
7396
|
+
* Wait for a tx receipt with bounded retries. Some L2 RPCs (notably Mantle)
|
|
7397
|
+
* occasionally fail to surface a receipt even after the tx is mined; viem's
|
|
7398
|
+
* default `waitForTransactionReceipt` errors out instead of polling longer.
|
|
7399
|
+
* We retry up to `attempts` times with exponential backoff before giving up.
|
|
7400
|
+
*/
|
|
7401
|
+
static async waitForReceiptWithRetry(client, hash, attempts = 6) {
|
|
7402
|
+
let lastErr;
|
|
7403
|
+
for (let i = 0; i < attempts; i++) {
|
|
7404
|
+
try {
|
|
7405
|
+
return await client.waitForTransactionReceipt({
|
|
7406
|
+
hash,
|
|
7407
|
+
timeout: 6e4,
|
|
7408
|
+
retryCount: 8
|
|
7409
|
+
});
|
|
7410
|
+
} catch (e) {
|
|
7411
|
+
lastErr = e;
|
|
7412
|
+
const backoffMs = Math.min(2e3 * Math.pow(2, i), 6e4);
|
|
7413
|
+
await new Promise((resolve5) => setTimeout(resolve5, backoffMs));
|
|
7414
|
+
}
|
|
7415
|
+
}
|
|
7416
|
+
throw new Error(`waitForReceiptWithRetry: gave up after ${attempts} attempts. Last error: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}`);
|
|
7417
|
+
}
|
|
7418
|
+
/**
|
|
7419
|
+
* Fetch EIP-1559 fee params. Returns [maxFeePerGas, maxPriorityFeePerGas].
|
|
7420
|
+
*
|
|
7421
|
+
* Strategy: read the latest block's `baseFeePerGas` and use the canonical
|
|
7422
|
+
* EIP-1559 formula `maxFee = baseFee * 2 + priorityFee` (1 block of head-room
|
|
7423
|
+
* after a 12.5% bump). Falls back to `getGasPrice() + priorityFee` only when
|
|
7424
|
+
* the chain doesn't expose `baseFeePerGas` (pre-1559).
|
|
7425
|
+
*
|
|
7426
|
+
* Why not gasPrice * 2: `getGasPrice()` returns `baseFee + priorityFee`, so
|
|
7427
|
+
* doubling double-counts the priority component and produces nonsense on
|
|
7428
|
+
* chains where baseFee is already high (e.g., Mantle 50 gwei → 100 gwei,
|
|
7429
|
+
* which can drain MNT before the actual tx settles).
|
|
7430
|
+
*/
|
|
7254
7431
|
async fetchEip1559Fees(rpcUrl) {
|
|
7255
7432
|
try {
|
|
7256
7433
|
const client = createPublicClient2({ transport: http2(rpcUrl) });
|
|
7257
|
-
const gasPrice = await client.getGasPrice();
|
|
7258
7434
|
let priorityFee = DEFAULT_PRIORITY_FEE_WEI;
|
|
7259
7435
|
try {
|
|
7260
7436
|
priorityFee = await client.estimateMaxPriorityFeePerGas();
|
|
7261
7437
|
} catch {
|
|
7262
7438
|
}
|
|
7263
|
-
|
|
7264
|
-
|
|
7439
|
+
try {
|
|
7440
|
+
const block = await client.getBlock({ blockTag: "latest" });
|
|
7441
|
+
if (block.baseFeePerGas !== null && block.baseFeePerGas !== void 0) {
|
|
7442
|
+
const maxFee = block.baseFeePerGas * 2n + priorityFee;
|
|
7443
|
+
return [maxFee, priorityFee];
|
|
7444
|
+
}
|
|
7445
|
+
} catch {
|
|
7446
|
+
}
|
|
7447
|
+
const gasPrice = await client.getGasPrice();
|
|
7448
|
+
return [gasPrice + priorityFee, priorityFee];
|
|
7265
7449
|
} catch {
|
|
7266
7450
|
return [0n, 0n];
|
|
7267
7451
|
}
|
|
@@ -7425,8 +7609,8 @@ var Executor = class _Executor {
|
|
|
7425
7609
|
`);
|
|
7426
7610
|
if (preTxUrl) process.stderr.write(` Explorer: ${preTxUrl}
|
|
7427
7611
|
`);
|
|
7428
|
-
const
|
|
7429
|
-
if (
|
|
7612
|
+
const preReceiptResult = await _Executor.waitForReceiptWithRetry(publicClient, preTxHash);
|
|
7613
|
+
if (preReceiptResult.status !== "success") {
|
|
7430
7614
|
throw new DefiError("TX_FAILED", `Pre-transaction failed: ${preTx.description}`);
|
|
7431
7615
|
}
|
|
7432
7616
|
process.stderr.write(` Pre-tx confirmed
|
|
@@ -7468,7 +7652,7 @@ var Executor = class _Executor {
|
|
|
7468
7652
|
if (txUrl) process.stderr.write(`Explorer: ${txUrl}
|
|
7469
7653
|
`);
|
|
7470
7654
|
process.stderr.write("Waiting for confirmation...\n");
|
|
7471
|
-
const receipt = await
|
|
7655
|
+
const receipt = await _Executor.waitForReceiptWithRetry(publicClient, txHash);
|
|
7472
7656
|
const status = receipt.status === "success" ? TxStatus.Confirmed : TxStatus.Failed;
|
|
7473
7657
|
let mintedTokenId;
|
|
7474
7658
|
if (receipt.status === "success" && receipt.logs) {
|
|
@@ -8534,8 +8718,9 @@ function registerLP(parent, getOpts, makeExecutor2) {
|
|
|
8534
8718
|
}
|
|
8535
8719
|
if (protocol.interface === "uniswap_v2" && protocol.contracts?.["lb_factory"]) {
|
|
8536
8720
|
const adapter = createMerchantMoeLB(protocol, rpcUrl);
|
|
8537
|
-
const
|
|
8538
|
-
|
|
8721
|
+
const rewardedPools = await adapter.discoverRewardedPools();
|
|
8722
|
+
const rewardedSet = new Set(rewardedPools.map((p) => p.pool.toLowerCase()));
|
|
8723
|
+
for (const p of rewardedPools) {
|
|
8539
8724
|
if (!opts.emissionOnly || !p.stopped) {
|
|
8540
8725
|
results.push({
|
|
8541
8726
|
protocol: protocol.slug,
|
|
@@ -8557,6 +8742,19 @@ function registerLP(parent, getOpts, makeExecutor2) {
|
|
|
8557
8742
|
});
|
|
8558
8743
|
}
|
|
8559
8744
|
}
|
|
8745
|
+
if (!opts.emissionOnly) {
|
|
8746
|
+
const allPools = await adapter.discoverAllPools().catch(() => []);
|
|
8747
|
+
for (const p of allPools) {
|
|
8748
|
+
if (rewardedSet.has(p.pool.toLowerCase())) continue;
|
|
8749
|
+
results.push({
|
|
8750
|
+
protocol: protocol.slug,
|
|
8751
|
+
pool: p.pool,
|
|
8752
|
+
pair: `${p.symbolX}/${p.symbolY}`,
|
|
8753
|
+
type: "FEE",
|
|
8754
|
+
source: "lb_hooks"
|
|
8755
|
+
});
|
|
8756
|
+
}
|
|
8757
|
+
}
|
|
8560
8758
|
}
|
|
8561
8759
|
if (protocol.interface === "uniswap_v3" && protocol.contracts?.["masterchef"]) {
|
|
8562
8760
|
const mcAddr = protocol.contracts["masterchef"];
|
|
@@ -8688,7 +8886,7 @@ function registerLP(parent, getOpts, makeExecutor2) {
|
|
|
8688
8886
|
const recipient = opts.recipient ?? process.env["DEFI_WALLET_ADDRESS"] ?? "0x0000000000000000000000000000000000000001";
|
|
8689
8887
|
const poolAddr = opts.pool ? resolvePoolAddress(registry, opts.protocol, opts.pool) : void 0;
|
|
8690
8888
|
if (protocol.interface === "uniswap_v2" && protocol.contracts?.["lb_factory"]) {
|
|
8691
|
-
if (!poolAddr) throw new Error(
|
|
8889
|
+
if (!poolAddr) throw new Error(`--pool is required for ${protocol.name} (Liquidity Book \u2014 pass --pool <addr>; use \`lp discover --protocol ${protocol.slug}\` to list active pools)`);
|
|
8692
8890
|
const lbAdapter = createMerchantMoeLB(protocol, chain.effectiveRpcUrl());
|
|
8693
8891
|
const [tokenX, tokenY, amountX, amountY] = tokenA.toLowerCase() < tokenB.toLowerCase() ? [tokenA, tokenB, BigInt(opts.amountA), BigInt(opts.amountB)] : [tokenB, tokenA, BigInt(opts.amountB), BigInt(opts.amountA)];
|
|
8694
8892
|
const client = createPublicClient23({ transport: http23(chain.effectiveRpcUrl()) });
|
|
@@ -8931,7 +9129,7 @@ function registerLP(parent, getOpts, makeExecutor2) {
|
|
|
8931
9129
|
return;
|
|
8932
9130
|
}
|
|
8933
9131
|
if (iface === "uniswap_v2" && protocol.contracts?.["lb_factory"]) {
|
|
8934
|
-
if (!opts.pool) throw new Error(
|
|
9132
|
+
if (!opts.pool) throw new Error(`--pool is required for ${protocol.name} (Liquidity Book \u2014 pass --pool <addr>)`);
|
|
8935
9133
|
const adapter = createMerchantMoeLB(protocol, rpcUrl);
|
|
8936
9134
|
const binIds = opts.bins ? opts.bins.split(",").map((s) => parseInt(s.trim())) : void 0;
|
|
8937
9135
|
const tx = await adapter.buildClaimRewards(account, opts.pool, binIds);
|
|
@@ -9007,7 +9205,7 @@ function registerLP(parent, getOpts, makeExecutor2) {
|
|
|
9007
9205
|
const iface = protocol.interface;
|
|
9008
9206
|
const recipient = opts.recipient ?? process.env["DEFI_WALLET_ADDRESS"] ?? "0x0000000000000000000000000000000000000001";
|
|
9009
9207
|
if (iface === "uniswap_v2" && protocol.contracts?.["lb_factory"]) {
|
|
9010
|
-
if (!opts.pool) throw new Error(
|
|
9208
|
+
if (!opts.pool) throw new Error(`--pool is required for ${protocol.name} (Liquidity Book \u2014 pass --pool <addr>)`);
|
|
9011
9209
|
if (!opts.bins) throw new Error("--bins <id1,id2,...> is required for Merchant Moe LB remove");
|
|
9012
9210
|
const lbAdapter = createMerchantMoeLB(protocol, rpcUrl);
|
|
9013
9211
|
const tokenA2 = opts.tokenA.startsWith("0x") ? opts.tokenA : registry.resolveToken(chainName, opts.tokenA).address;
|