four-flap-meme-sdk 1.4.7 → 1.4.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/dex/direct-router.js +69 -13
- package/package.json +1 -1
|
@@ -48,9 +48,31 @@ const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
|
|
|
48
48
|
const QUOTE_ROUTER_ABI = [
|
|
49
49
|
'function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)'
|
|
50
50
|
];
|
|
51
|
-
// ✅ V3
|
|
51
|
+
// ✅ V3 QuoterV2 ABI(用于 V3 报价)
|
|
52
|
+
// PancakeSwap V3 使用结构体参数版本
|
|
52
53
|
const V3_QUOTER_ABI = [
|
|
53
|
-
|
|
54
|
+
{
|
|
55
|
+
"inputs": [{
|
|
56
|
+
"components": [
|
|
57
|
+
{ "name": "tokenIn", "type": "address" },
|
|
58
|
+
{ "name": "tokenOut", "type": "address" },
|
|
59
|
+
{ "name": "amountIn", "type": "uint256" },
|
|
60
|
+
{ "name": "fee", "type": "uint24" },
|
|
61
|
+
{ "name": "sqrtPriceLimitX96", "type": "uint160" }
|
|
62
|
+
],
|
|
63
|
+
"name": "params",
|
|
64
|
+
"type": "tuple"
|
|
65
|
+
}],
|
|
66
|
+
"name": "quoteExactInputSingle",
|
|
67
|
+
"outputs": [
|
|
68
|
+
{ "name": "amountOut", "type": "uint256" },
|
|
69
|
+
{ "name": "sqrtPriceX96After", "type": "uint160" },
|
|
70
|
+
{ "name": "initializedTicksCrossed", "type": "uint32" },
|
|
71
|
+
{ "name": "gasEstimate", "type": "uint256" }
|
|
72
|
+
],
|
|
73
|
+
"stateMutability": "nonpayable",
|
|
74
|
+
"type": "function"
|
|
75
|
+
}
|
|
54
76
|
];
|
|
55
77
|
// ✅ 各链的报价配置(V2 Router + V3 Quoter)
|
|
56
78
|
const QUOTE_CONFIG = {
|
|
@@ -657,15 +679,26 @@ async function getTokenToNativeQuote(provider, tokenAddress, tokenAmount, chain,
|
|
|
657
679
|
// V3 策略 1:直接路径 代币 → WBNB
|
|
658
680
|
// 如果指定了 fee,只用指定的 fee;否则尝试所有费率
|
|
659
681
|
const feesToTry = fee ? [fee] : V3_FEE_TIERS;
|
|
682
|
+
console.log(`[getTokenToNativeQuote] 开始 V3 报价: token=${tokenAddress.slice(0, 10)}..., amount=${tokenAmount}, feesToTry=${feesToTry}`);
|
|
660
683
|
for (const tryFee of feesToTry) {
|
|
661
684
|
try {
|
|
662
|
-
|
|
685
|
+
// ✅ 使用结构体参数调用 QuoterV2
|
|
686
|
+
const result = await quoter.quoteExactInputSingle.staticCall({
|
|
687
|
+
tokenIn: tokenAddress,
|
|
688
|
+
tokenOut: config.wrappedNative,
|
|
689
|
+
amountIn: tokenAmount,
|
|
690
|
+
fee: tryFee,
|
|
691
|
+
sqrtPriceLimitX96: 0n
|
|
692
|
+
});
|
|
693
|
+
// QuoterV2 返回多个值,第一个是 amountOut
|
|
694
|
+
const amountOut = result[0];
|
|
663
695
|
if (amountOut > 0n) {
|
|
664
696
|
console.log(`[getTokenToNativeQuote] V3 直接路径成功 (fee=${tryFee}): ${ethers.formatEther(amountOut)} BNB`);
|
|
665
697
|
return amountOut;
|
|
666
698
|
}
|
|
667
699
|
}
|
|
668
|
-
catch {
|
|
700
|
+
catch (err) {
|
|
701
|
+
console.log(`[getTokenToNativeQuote] V3 直接路径失败 (fee=${tryFee}): ${String(err).slice(0, 100)}`);
|
|
669
702
|
continue;
|
|
670
703
|
}
|
|
671
704
|
}
|
|
@@ -675,19 +708,42 @@ async function getTokenToNativeQuote(provider, tokenAddress, tokenAmount, chain,
|
|
|
675
708
|
continue;
|
|
676
709
|
for (const fee1 of feesToTry) {
|
|
677
710
|
try {
|
|
678
|
-
// 第一跳:代币 →
|
|
679
|
-
const
|
|
711
|
+
// 第一跳:代币 → 稳定币(使用结构体参数)
|
|
712
|
+
const midResult = await quoter.quoteExactInputSingle.staticCall({
|
|
713
|
+
tokenIn: tokenAddress,
|
|
714
|
+
tokenOut: stableCoin,
|
|
715
|
+
amountIn: tokenAmount,
|
|
716
|
+
fee: fee1,
|
|
717
|
+
sqrtPriceLimitX96: 0n
|
|
718
|
+
});
|
|
719
|
+
const midAmount = midResult[0];
|
|
680
720
|
if (midAmount <= 0n)
|
|
681
721
|
continue;
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
722
|
+
console.log(`[getTokenToNativeQuote] V3 第一跳成功: 代币 → ${stableCoin.slice(0, 10)}... = ${midAmount}`);
|
|
723
|
+
// 第二跳:稳定币 → WBNB(尝试多个费率)
|
|
724
|
+
const stableFees = [100, 500, 2500]; // 0.01%, 0.05%, 0.25%
|
|
725
|
+
for (const fee2 of stableFees) {
|
|
726
|
+
try {
|
|
727
|
+
const finalResult = await quoter.quoteExactInputSingle.staticCall({
|
|
728
|
+
tokenIn: stableCoin,
|
|
729
|
+
tokenOut: config.wrappedNative,
|
|
730
|
+
amountIn: midAmount,
|
|
731
|
+
fee: fee2,
|
|
732
|
+
sqrtPriceLimitX96: 0n
|
|
733
|
+
});
|
|
734
|
+
const amountOut = finalResult[0];
|
|
735
|
+
if (amountOut > 0n) {
|
|
736
|
+
console.log(`[getTokenToNativeQuote] V3 多跳路径成功 (${fee1}→${fee2}): ${ethers.formatEther(amountOut)} BNB`);
|
|
737
|
+
return amountOut;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
catch {
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
688
743
|
}
|
|
689
744
|
}
|
|
690
|
-
catch {
|
|
745
|
+
catch (err) {
|
|
746
|
+
console.log(`[getTokenToNativeQuote] V3 第一跳失败 (fee=${fee1}): ${err}`);
|
|
691
747
|
continue;
|
|
692
748
|
}
|
|
693
749
|
}
|