four-flap-meme-sdk 1.4.28 → 1.4.29
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.
|
@@ -748,23 +748,16 @@ export async function directV3BatchBuy(params) {
|
|
|
748
748
|
const totalFlowWei = flowAmounts.reduce((sum, amt) => sum + amt, 0n);
|
|
749
749
|
const baseProfitWei = calculateProfitAmount(totalFlowWei);
|
|
750
750
|
// ✅ 方案 B:并行获取 nonces、gasPrice 和 ERC20 报价
|
|
751
|
-
// ✅ 修复:ERC20 报价不传 fee 参数,让报价函数自动选择最佳费率
|
|
752
|
-
// 因为 quoteToken/WBNB 池的费率可能与交易池(tokenAddress)的费率不同
|
|
753
751
|
const [nonces, gasPrice, nativeProfitWei] = await Promise.all([
|
|
754
752
|
startNonces && startNonces.length === wallets.length
|
|
755
753
|
? Promise.resolve(startNonces)
|
|
756
754
|
: new NonceManager(provider).getNextNoncesForWallets(wallets),
|
|
757
755
|
getGasPrice(provider, config),
|
|
758
|
-
// ERC20
|
|
756
|
+
// ERC20 报价(V3 买入用 V3 报价)
|
|
759
757
|
(!useNative && baseProfitWei > 0n && quoteToken)
|
|
760
|
-
? getTokenToNativeQuote(provider, quoteToken, baseProfitWei, chain, 'v3')
|
|
758
|
+
? getTokenToNativeQuote(provider, quoteToken, baseProfitWei, chain, 'v3', fee)
|
|
761
759
|
: Promise.resolve(baseProfitWei)
|
|
762
760
|
]);
|
|
763
|
-
// ✅ 添加详细日志
|
|
764
|
-
if (!useNative) {
|
|
765
|
-
console.log(`[V3 Buy Profit] quoteToken=${quoteToken}, baseProfitWei=${baseProfitWei} (${ethers.formatEther(baseProfitWei)} quoteToken)`);
|
|
766
|
-
console.log(`[V3 Buy Profit] nativeProfitWei=${nativeProfitWei} (${ethers.formatEther(nativeProfitWei)} BNB)`);
|
|
767
|
-
}
|
|
768
761
|
const profitWei = nativeProfitWei > 0n ? nativeProfitWei : 0n;
|
|
769
762
|
const gasLimit = getGasLimit(config, 300000);
|
|
770
763
|
const txType = config.txType ?? 0;
|
|
@@ -47,7 +47,8 @@ const WBNB_ADDRESS = ADDRESSES.BSC.WBNB;
|
|
|
47
47
|
// ✅ getDeadline 从 bundle-helpers.js 导入
|
|
48
48
|
const APPROVE_INTERFACE = new ethers.Interface(['function approve(address,uint256) returns (bool)']);
|
|
49
49
|
export async function pancakeBundleBuyFirstMerkle(params) {
|
|
50
|
-
const { buyerPrivateKey, sellerPrivateKey, tokenAddress, routeParams, buyerFunds, buyerFundsPercentage, config, quoteToken, quoteTokenDecimals = 18
|
|
50
|
+
const { buyerPrivateKey, sellerPrivateKey, tokenAddress, routeParams, buyerFunds, buyerFundsPercentage, config, quoteToken, quoteTokenDecimals = 18, startNonces // ✅ 可选:前端预获取的 nonces
|
|
51
|
+
} = params;
|
|
51
52
|
// ✅ 判断是否使用原生代币(BNB)或 ERC20 代币(如 USDT)
|
|
52
53
|
const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
|
|
53
54
|
const context = createPancakeContext(config);
|
|
@@ -121,15 +122,18 @@ export async function pancakeBundleBuyFirstMerkle(params) {
|
|
|
121
122
|
? ethers.parseEther(String(config.bribeAmount))
|
|
122
123
|
: 0n;
|
|
123
124
|
const needBribeTx = bribeAmount > 0n;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
// ✅ 如果前端传入了 startNonces,直接使用(性能优化,避免 nonce 冲突)
|
|
126
|
+
const noncePlan = startNonces && startNonces.length >= (sameAddress ? 1 : 2)
|
|
127
|
+
? buildNoncePlanFromStartNonces(startNonces, sameAddress, !!approvalTx, profitAmount > 0n, needBribeTx)
|
|
128
|
+
: await planNonces({
|
|
129
|
+
buyer,
|
|
130
|
+
seller,
|
|
131
|
+
sameAddress,
|
|
132
|
+
approvalExists: !!approvalTx,
|
|
133
|
+
extractProfit: profitAmount > 0n,
|
|
134
|
+
needBribeTx,
|
|
135
|
+
nonceManager
|
|
136
|
+
});
|
|
133
137
|
// ✅ 贿赂交易放在首位(由卖方发送,与利润交易同一钱包)
|
|
134
138
|
let bribeTx = null;
|
|
135
139
|
if (needBribeTx && noncePlan.bribeNonce !== undefined) {
|
|
@@ -512,3 +516,31 @@ async function validateFinalBalances({ sameAddress, buyerFundsWei, buyerBalance,
|
|
|
512
516
|
function countTruthy(values) {
|
|
513
517
|
return values.filter(Boolean).length;
|
|
514
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* ✅ 从前端传入的 startNonces 构建 NoncePlan(用于性能优化,避免 nonce 冲突)
|
|
521
|
+
* 顺序:同地址时 [baseNonce],不同地址时 [sellerNonce, buyerNonce]
|
|
522
|
+
*/
|
|
523
|
+
function buildNoncePlanFromStartNonces(startNonces, sameAddress, approvalExists, profitNeeded, needBribeTx) {
|
|
524
|
+
if (sameAddress) {
|
|
525
|
+
// 同一地址:所有交易使用递增 nonce
|
|
526
|
+
let idx = 0;
|
|
527
|
+
const baseNonce = startNonces[0];
|
|
528
|
+
const bribeNonce = needBribeTx ? baseNonce + idx++ : undefined;
|
|
529
|
+
if (approvalExists)
|
|
530
|
+
idx++;
|
|
531
|
+
const buyerNonce = baseNonce + idx++;
|
|
532
|
+
const sellerNonce = baseNonce + idx++;
|
|
533
|
+
const profitNonce = profitNeeded ? baseNonce + idx : undefined;
|
|
534
|
+
return { buyerNonce, sellerNonce, bribeNonce, profitNonce };
|
|
535
|
+
}
|
|
536
|
+
// 不同地址
|
|
537
|
+
let sellerIdx = 0;
|
|
538
|
+
const sellerBaseNonce = startNonces[0];
|
|
539
|
+
const bribeNonce = needBribeTx ? sellerBaseNonce + sellerIdx++ : undefined;
|
|
540
|
+
if (approvalExists)
|
|
541
|
+
sellerIdx++;
|
|
542
|
+
const sellerNonce = sellerBaseNonce + sellerIdx++;
|
|
543
|
+
const profitNonce = profitNeeded ? sellerBaseNonce + sellerIdx : undefined;
|
|
544
|
+
const buyerNonce = startNonces[1];
|
|
545
|
+
return { buyerNonce, sellerNonce, bribeNonce, profitNonce };
|
|
546
|
+
}
|