four-flap-meme-sdk 1.5.15 → 1.5.17
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.
|
@@ -333,6 +333,64 @@ async function getGasPrice(provider, config) {
|
|
|
333
333
|
function isNativeToken(quoteToken) {
|
|
334
334
|
return !quoteToken || quoteToken === ZERO_ADDRESS;
|
|
335
335
|
}
|
|
336
|
+
// ============================================================================
|
|
337
|
+
// XLAYER V3 报价(slot0 现货价,纯 V3,不串 V2)
|
|
338
|
+
// - 只用于“利润换算”为原生币,避免 XLAYER 没有 v3Quoter 导致 profit=0
|
|
339
|
+
// - 不改 BSC 的任何配置/逻辑
|
|
340
|
+
// ============================================================================
|
|
341
|
+
const XLAYER_V3_FACTORY_ABI = [
|
|
342
|
+
'function getPool(address tokenA, address tokenB, uint24 fee) view returns (address pool)',
|
|
343
|
+
];
|
|
344
|
+
const XLAYER_V3_POOL_ABI = [
|
|
345
|
+
'function slot0() view returns (uint160 sqrtPriceX96,int24 tick,uint16 observationIndex,uint16 observationCardinality,uint16 observationCardinalityNext,uint8 feeProtocol,bool unlocked)',
|
|
346
|
+
'function token0() view returns (address)',
|
|
347
|
+
'function token1() view returns (address)',
|
|
348
|
+
];
|
|
349
|
+
const V3_FEE_DENOMINATOR = 1000000n; // UniswapV3 fee: X / 1e6
|
|
350
|
+
async function quoteXLayerV3TokenToNativeBySlot0(params) {
|
|
351
|
+
try {
|
|
352
|
+
const { provider, tokenIn, amountIn, fee } = params;
|
|
353
|
+
if (!tokenIn || amountIn <= 0n)
|
|
354
|
+
return 0n;
|
|
355
|
+
const chainFactory = DIRECT_ROUTERS.XLAYER.V3_FACTORY;
|
|
356
|
+
const wrappedNative = DIRECT_ROUTERS.XLAYER.WOKB;
|
|
357
|
+
if (!chainFactory || !wrappedNative)
|
|
358
|
+
return 0n;
|
|
359
|
+
const tokenInLower = tokenIn.toLowerCase();
|
|
360
|
+
const wrappedLower = wrappedNative.toLowerCase();
|
|
361
|
+
if (tokenInLower === wrappedLower)
|
|
362
|
+
return amountIn;
|
|
363
|
+
const factory = new Contract(chainFactory, XLAYER_V3_FACTORY_ABI, provider);
|
|
364
|
+
const poolAddr = await factory.getPool?.(tokenIn, wrappedNative, fee);
|
|
365
|
+
if (!poolAddr || poolAddr.toLowerCase() === ZERO_ADDRESS.toLowerCase())
|
|
366
|
+
return 0n;
|
|
367
|
+
const pool = new Contract(poolAddr, XLAYER_V3_POOL_ABI, provider);
|
|
368
|
+
const [t0, t1, slot0] = await Promise.all([pool.token0?.(), pool.token1?.(), pool.slot0?.()]);
|
|
369
|
+
if (!t0 || !t1 || !slot0)
|
|
370
|
+
return 0n;
|
|
371
|
+
const sqrtPriceX96 = BigInt(slot0[0]);
|
|
372
|
+
if (sqrtPriceX96 <= 0n)
|
|
373
|
+
return 0n;
|
|
374
|
+
const amountInLessFee = (amountIn * (V3_FEE_DENOMINATOR - BigInt(fee))) / V3_FEE_DENOMINATOR;
|
|
375
|
+
if (amountInLessFee <= 0n)
|
|
376
|
+
return 0n;
|
|
377
|
+
const Q192 = 2n ** 192n;
|
|
378
|
+
const num = sqrtPriceX96 * sqrtPriceX96;
|
|
379
|
+
const t0Lower = String(t0).toLowerCase();
|
|
380
|
+
const t1Lower = String(t1).toLowerCase();
|
|
381
|
+
// sqrtPriceX96 表示 token1/token0 的现货价(raw)
|
|
382
|
+
if (tokenInLower === t0Lower && wrappedLower === t1Lower) {
|
|
383
|
+
return (amountInLessFee * num) / Q192;
|
|
384
|
+
}
|
|
385
|
+
if (tokenInLower === t1Lower && wrappedLower === t0Lower) {
|
|
386
|
+
return (amountInLessFee * Q192) / num;
|
|
387
|
+
}
|
|
388
|
+
return 0n;
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
return 0n;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
336
394
|
// ✅ getTokenToNativeQuote 函数已移至 ../utils/quote-helpers.ts
|
|
337
395
|
/**
|
|
338
396
|
* ✅ 找到金额最大的钱包索引(和 core.ts 逻辑一致)
|
|
@@ -766,7 +824,9 @@ export async function directV3BatchBuy(params) {
|
|
|
766
824
|
getGasPrice(provider, config),
|
|
767
825
|
// ERC20 报价(V3 买入用 V3 报价)
|
|
768
826
|
(!useNative && baseProfitWei > 0n && quoteToken)
|
|
769
|
-
?
|
|
827
|
+
? (chain.toUpperCase() === 'XLAYER'
|
|
828
|
+
? quoteXLayerV3TokenToNativeBySlot0({ provider, tokenIn: quoteToken, amountIn: baseProfitWei, fee })
|
|
829
|
+
: getTokenToNativeQuote(provider, quoteToken, baseProfitWei, chain, 'v3', fee))
|
|
770
830
|
: Promise.resolve(baseProfitWei)
|
|
771
831
|
]);
|
|
772
832
|
const profitWei = nativeProfitWei > 0n ? nativeProfitWei : 0n;
|
|
@@ -884,7 +944,9 @@ export async function directV3BatchSell(params) {
|
|
|
884
944
|
try {
|
|
885
945
|
if (useNativeOutput) {
|
|
886
946
|
// 卖出代币 → 得到 BNB:先获取 V3 报价,再计算利润
|
|
887
|
-
const estimatedBNBOut =
|
|
947
|
+
const estimatedBNBOut = chain.toUpperCase() === 'XLAYER'
|
|
948
|
+
? await quoteXLayerV3TokenToNativeBySlot0({ provider, tokenIn: tokenAddress, amountIn: totalSellAmount, fee })
|
|
949
|
+
: await getTokenToNativeQuote(provider, tokenAddress, totalSellAmount, chain, 'v3', fee);
|
|
888
950
|
console.log(`[V3 Sell Profit] totalSellAmount: ${totalSellAmount}, estimatedBNBOut: ${estimatedBNBOut}, estimatedBNB: ${ethers.formatEther(estimatedBNBOut)}`);
|
|
889
951
|
if (estimatedBNBOut <= 0n)
|
|
890
952
|
return 0n;
|
|
@@ -894,7 +956,9 @@ export async function directV3BatchSell(params) {
|
|
|
894
956
|
}
|
|
895
957
|
else if (quoteToken) {
|
|
896
958
|
// 卖出代币 → 得到 ERC20:先获取 V3 报价,再计算利润
|
|
897
|
-
const estimatedBNBOut =
|
|
959
|
+
const estimatedBNBOut = chain.toUpperCase() === 'XLAYER'
|
|
960
|
+
? await quoteXLayerV3TokenToNativeBySlot0({ provider, tokenIn: tokenAddress, amountIn: totalSellAmount, fee })
|
|
961
|
+
: await getTokenToNativeQuote(provider, tokenAddress, totalSellAmount, chain, 'v3', fee);
|
|
898
962
|
if (estimatedBNBOut <= 0n)
|
|
899
963
|
return 0n;
|
|
900
964
|
const profit = calculateProfitAmount(estimatedBNBOut);
|
package/dist/utils/lp-inspect.js
CHANGED
|
@@ -57,6 +57,8 @@ const CHAIN_DEX_CONFIGS = {
|
|
|
57
57
|
stableCoins: [
|
|
58
58
|
{ address: '0x1e4a5963abfd975d8c9021ce480b42188849d41d', symbol: 'USDT', decimals: 6 },
|
|
59
59
|
{ address: '0x74b7f16337b8972027f6196a17a631ac6de26d22', symbol: 'USDC', decimals: 6 },
|
|
60
|
+
// ✅ XLayer: USD₮0 / USDT0(常见外盘配对)
|
|
61
|
+
{ address: '0x779ded0c9e1022225f8e0630b35a9b54be713736', symbol: 'USDT0', decimals: 6 },
|
|
60
62
|
],
|
|
61
63
|
dexes: {
|
|
62
64
|
POTATOSWAP: {
|