four-flap-meme-sdk 1.3.79 → 1.3.80

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.
@@ -178,7 +178,6 @@ export class BlockRazorClient {
178
178
  bundleParams.noMerge = params.noMerge;
179
179
  }
180
180
  try {
181
- console.log(`📦 [BlockRazor] 发送 Bundle: ${params.txs.length} 笔交易`);
182
181
  // ✅ 使用 fetch 发送请求,支持 Authorization 头
183
182
  const requestBody = {
184
183
  jsonrpc: '2.0',
@@ -210,16 +209,13 @@ export class BlockRazorClient {
210
209
  // 提取 bundle hash
211
210
  const bundleHash = result.result;
212
211
  if (typeof bundleHash === 'string') {
213
- console.log(`✅ [BlockRazor] Bundle 发送成功: ${bundleHash}`);
214
212
  return bundleHash;
215
213
  }
216
214
  if (bundleHash && typeof bundleHash === 'object') {
217
215
  if ('bundleHash' in bundleHash) {
218
- console.log(`✅ [BlockRazor] Bundle 发送成功: ${bundleHash.bundleHash}`);
219
216
  return String(bundleHash.bundleHash);
220
217
  }
221
218
  }
222
- console.log(`✅ [BlockRazor] Bundle 发送成功:`, result);
223
219
  return JSON.stringify(result.result || result);
224
220
  }
225
221
  catch (error) {
@@ -251,7 +247,6 @@ export class BlockRazorClient {
251
247
  // 计算最大有效区块号
252
248
  const actualOffset = Math.min(blockOffset, maxBlockOffset);
253
249
  const maxBlockNumber = currentBlock + actualOffset;
254
- console.log(`📊 [BlockRazor] 当前区块: ${currentBlock}, 最大有效区块: ${maxBlockNumber}`);
255
250
  // 发送 Bundle
256
251
  const bundleHash = await this.sendBundleRaw({
257
252
  txs: options.transactions,
@@ -281,7 +276,6 @@ export class BlockRazorClient {
281
276
  lastError = error;
282
277
  if (autoRetry && attempt < maxRetries) {
283
278
  attempt++;
284
- console.log(`🔄 [BlockRazor] 重试 ${attempt}/${maxRetries}...`);
285
279
  await new Promise(resolve => setTimeout(resolve, 3000)); // 等待一个区块
286
280
  continue;
287
281
  }
@@ -308,7 +302,6 @@ export class BlockRazorClient {
308
302
  });
309
303
  // 将激励交易添加到 Bundle 末尾
310
304
  const allTransactions = [...options.transactions, incentiveTx];
311
- console.log(`💰 [BlockRazor] 添加激励交易: ${incentive.amount} BNB -> ${BLOCKRAZOR_BUILDER_EOA}`);
312
305
  return await this.sendBundle({
313
306
  ...options,
314
307
  transactions: allTransactions,
@@ -82,7 +82,6 @@ export async function createTokenWithBundleBuyMerkle(params) {
82
82
  funGroup: false,
83
83
  clickFun: false,
84
84
  });
85
- console.log('🔍 Four.meme createToken 响应:', JSON.stringify(createResp, null, 2));
86
85
  const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
87
86
  const nonceManager = new NonceManager(provider);
88
87
  const txType = getTxType(config);
@@ -99,7 +98,6 @@ export async function createTokenWithBundleBuyMerkle(params) {
99
98
  const { remaining, profit } = calculateProfit(originalBuyAmount, config);
100
99
  actualBuyFunds = remaining;
101
100
  profitAmount = profit;
102
- console.log(`💰 利润刮取: 原始 ${ethers.formatEther(originalBuyAmount)} BNB → 实际买入 ${ethers.formatEther(actualBuyFunds)} BNB + 利润 ${ethers.formatEther(profitAmount)} BNB`);
103
101
  }
104
102
  else {
105
103
  actualBuyFunds = originalBuyAmount;
@@ -124,7 +122,6 @@ export async function createTokenWithBundleBuyMerkle(params) {
124
122
  value: valueWei
125
123
  };
126
124
  signedTxs.push(await devWallet.signTransaction(createTxRequest));
127
- console.log(`✅ 生成创建+买入交易: value = ${ethers.formatEther(valueWei)} BNB (0.01创建 + ${ethers.formatEther(actualBuyFunds)}买入)`);
128
125
  // ✅ 添加利润转账交易
129
126
  if (extractProfit && profitAmount > 0n) {
130
127
  const profitNonce = await nonceManager.getNextNonce(devWallet);
@@ -138,13 +135,9 @@ export async function createTokenWithBundleBuyMerkle(params) {
138
135
  type: txType
139
136
  });
140
137
  signedTxs.push(profitTx);
141
- console.log(`💸 利润转账交易已生成: ${ethers.formatEther(profitAmount)} BNB → ${getProfitRecipient()}`);
142
138
  }
143
139
  nonceManager.clearTemp();
144
- console.log(`✅ 总共生成了 ${signedTxs.length} 个交易签名 (1创建+买入${extractProfit && profitAmount > 0n ? ' + 1利润' : ''})`);
145
140
  // ⚠️ 只返回签名交易,不提交
146
- console.log('📦 交易已签名完成');
147
- console.log('💡 提示: 可以通过 Merkle Bundle 提交,或直接 broadcastTransaction');
148
141
  // 构建元数据
149
142
  const metadata = extractProfit && profitAmount > 0n ? {
150
143
  totalBuyAmount: ethers.formatEther(originalBuyAmount),
@@ -63,8 +63,6 @@ export interface SubmitBundleResult {
63
63
  * });
64
64
  *
65
65
  * if (result.code) {
66
- * console.log('✅ Bundle提交成功:', result.bundleHash);
67
- * console.log('交易哈希:', result.txHashes);
68
66
  * } else {
69
67
  * console.error('❌ Bundle提交失败:', result.error);
70
68
  * }
@@ -156,9 +154,6 @@ export interface BlockRazorSubmitResult {
156
154
  * });
157
155
  *
158
156
  * if (result.code) {
159
- * console.log('✅ Bundle 提交成功:', result.bundleHash);
160
- * console.log('交易哈希:', result.txHashes);
161
- * console.log('最大有效区块:', result.maxBlockNumber);
162
157
  * } else {
163
158
  * console.error('❌ Bundle 提交失败:', result.error);
164
159
  * }
@@ -249,8 +244,6 @@ export interface DirectSubmitResult {
249
244
  * });
250
245
  *
251
246
  * if (result.code) {
252
- * console.log('✅ 广播成功:', result.successCount, '/', result.totalTransactions);
253
- * console.log('交易哈希:', result.txHashes);
254
247
  * } else {
255
248
  * console.error('❌ 全部广播失败:', result.errorSummary);
256
249
  * }
@@ -50,8 +50,6 @@ function getMerkleClient(config) {
50
50
  * });
51
51
  *
52
52
  * if (result.code) {
53
- * console.log('✅ Bundle提交成功:', result.bundleHash);
54
- * console.log('交易哈希:', result.txHashes);
55
53
  * } else {
56
54
  * console.error('❌ Bundle提交失败:', result.error);
57
55
  * }
@@ -179,9 +177,6 @@ function getBlockRazorClient(config) {
179
177
  * });
180
178
  *
181
179
  * if (result.code) {
182
- * console.log('✅ Bundle 提交成功:', result.bundleHash);
183
- * console.log('交易哈希:', result.txHashes);
184
- * console.log('最大有效区块:', result.maxBlockNumber);
185
180
  * } else {
186
181
  * console.error('❌ Bundle 提交失败:', result.error);
187
182
  * }
@@ -200,7 +195,6 @@ export async function submitBundleToBlockRazor(signedTransactions, config) {
200
195
  }
201
196
  // ✅ 使用缓存的 BlockRazorClient
202
197
  const client = getBlockRazorClient(config);
203
- console.log(`📦 [BlockRazor] 提交 ${totalTransactions} 笔交易...`);
204
198
  // 提交 Bundle
205
199
  const bundleResult = await client.sendBundle({
206
200
  transactions: signedTransactions,
@@ -211,7 +205,6 @@ export async function submitBundleToBlockRazor(signedTransactions, config) {
211
205
  autoRetry: config.autoRetry ?? false,
212
206
  maxRetries: config.maxRetries ?? 3
213
207
  });
214
- console.log(`✅ [BlockRazor] 提交成功: ${bundleResult.bundleHash}`);
215
208
  // ✅ 提交成功
216
209
  return {
217
210
  code: true,
@@ -223,7 +216,6 @@ export async function submitBundleToBlockRazor(signedTransactions, config) {
223
216
  };
224
217
  }
225
218
  catch (error) {
226
- console.error(`❌ [BlockRazor] 提交失败:`, error?.message || error);
227
219
  // ❌ 提交失败
228
220
  return {
229
221
  code: false,
@@ -279,8 +271,6 @@ export async function submitMultipleBundlesToBlockRazorParallel(bundles, config)
279
271
  * });
280
272
  *
281
273
  * if (result.code) {
282
- * console.log('✅ 广播成功:', result.successCount, '/', result.totalTransactions);
283
- * console.log('交易哈希:', result.txHashes);
284
274
  * } else {
285
275
  * console.error('❌ 全部广播失败:', result.errorSummary);
286
276
  * }
@@ -333,7 +323,6 @@ export async function submitDirectToRpc(signedTransactions, config) {
333
323
  txHash: txResponse.hash
334
324
  });
335
325
  txHashes.push(txResponse.hash);
336
- console.log(`✅ [${chainName}] 交易 ${i + 1}/${totalTransactions} 广播成功: ${txResponse.hash}`);
337
326
  // 如果需要等待确认
338
327
  if (config.waitForConfirmation) {
339
328
  try {
@@ -417,12 +406,9 @@ export async function submitDirectToRpcSequential(signedTransactions, config) {
417
406
  for (let i = 0; i < signedTransactions.length; i++) {
418
407
  const signedTx = signedTransactions[i];
419
408
  try {
420
- console.log(`📤 [${chainName}] 广播交易 ${i + 1}/${totalTransactions}...`);
421
409
  // 广播交易
422
410
  const txResponse = await provider.broadcastTransaction(signedTx);
423
- console.log(`✅ [${chainName}] 交易 ${i + 1} 已广播: ${txResponse.hash}`);
424
411
  // ✅ 等待交易确认
425
- console.log(`⏳ [${chainName}] 等待交易 ${i + 1} 确认...`);
426
412
  const receipt = await provider.waitForTransaction(txResponse.hash, 1, // 等待1个确认
427
413
  confirmationTimeout);
428
414
  if (receipt && receipt.status === 1) {
@@ -432,7 +418,6 @@ export async function submitDirectToRpcSequential(signedTransactions, config) {
432
418
  txHash: txResponse.hash
433
419
  });
434
420
  txHashes.push(txResponse.hash);
435
- console.log(`✅ [${chainName}] 交易 ${i + 1} 已确认: ${txResponse.hash}`);
436
421
  }
437
422
  else {
438
423
  const errorMsg = `交易执行失败(status=${receipt?.status})`;
@@ -443,9 +428,7 @@ export async function submitDirectToRpcSequential(signedTransactions, config) {
443
428
  error: errorMsg
444
429
  });
445
430
  errors.push(`交易 ${i + 1}: ${errorMsg}`);
446
- console.error(`❌ [${chainName}] 交易 ${i + 1} 失败: ${errorMsg}`);
447
431
  // ✅ 多跳场景:如果某笔失败,后续交易可能也会失败,继续尝试但标记
448
- console.warn(`⚠️ [${chainName}] 交易 ${i + 1} 失败,继续尝试后续交易...`);
449
432
  }
450
433
  }
451
434
  catch (error) {
@@ -456,14 +439,11 @@ export async function submitDirectToRpcSequential(signedTransactions, config) {
456
439
  error: errorMessage
457
440
  });
458
441
  errors.push(`交易 ${i + 1}: ${errorMessage}`);
459
- console.error(`❌ [${chainName}] 交易 ${i + 1}/${totalTransactions} 失败:`, errorMessage);
460
442
  // ✅ 多跳场景:如果某笔失败,后续交易可能也会失败,继续尝试
461
- console.warn(`⚠️ [${chainName}] 继续尝试后续交易...`);
462
443
  }
463
444
  }
464
445
  const successCount = txHashes.length;
465
446
  const failedCount = totalTransactions - successCount;
466
- console.log(`📊 [${chainName}] 顺序广播完成: ${successCount}/${totalTransactions} 成功`);
467
447
  return {
468
448
  code: successCount > 0,
469
449
  totalTransactions,
@@ -536,7 +516,6 @@ export async function submitDirectToRpcParallel(signedTransactions, config) {
536
516
  const errors = results.filter(r => !r.success).map(r => `交易 ${r.index + 1}: ${r.error}`);
537
517
  const successCount = txHashes.length;
538
518
  const failedCount = totalTransactions - successCount;
539
- console.log(`📤 [${chainName}] 并行广播完成: ${successCount}/${totalTransactions} 成功`);
540
519
  return {
541
520
  code: successCount > 0,
542
521
  totalTransactions,
@@ -202,7 +202,6 @@ export async function fourBatchSwapMerkle(params) {
202
202
  const seller = new Wallet(sellerPrivateKey, provider);
203
203
  const buyers = buyerPrivateKeys.map(pk => new Wallet(pk, provider));
204
204
  const nonceManager = new NonceManager(provider);
205
- console.log('🔍 Four BatchSwap - 买方数量:', buyerPrivateKeys.length);
206
205
  // 创建适配的配置对象
207
206
  const bundleConfig = {
208
207
  minGasPriceGwei: config.minGasPriceGwei,
@@ -233,10 +232,8 @@ export async function fourBatchSwapMerkle(params) {
233
232
  let buyAmountsWei;
234
233
  if (params.buyerRatios && params.buyerRatios.length === buyers.length) {
235
234
  // 按比例分配
236
- console.log('📊 使用比例分配,卖出所得:', ethers.formatEther(totalBuyerFunds), 'BNB');
237
235
  buyAmountsWei = params.buyerRatios.map((ratio, index) => {
238
236
  const amount = (totalBuyerFunds * BigInt(Math.round(ratio * 10000))) / 10000n;
239
- console.log(` 买方 ${index + 1}: ${(ratio * 100).toFixed(1)}% = ${ethers.formatEther(amount)} BNB`);
240
237
  return amount;
241
238
  });
242
239
  }
@@ -363,7 +360,6 @@ export async function fourBatchSwapMerkle(params) {
363
360
  signedTransactions.push(...signedBuys);
364
361
  if (profitTx)
365
362
  signedTransactions.push(profitTx);
366
- console.log(`✅ Four 批量换手签名完成: ${signedTransactions.length} 笔交易`);
367
363
  return {
368
364
  signedTransactions,
369
365
  metadata: {
@@ -305,8 +305,6 @@ export async function createTokenWithBundleBuy(params) {
305
305
  bundleUuid = await config.customSubmitFn(signedTxs);
306
306
  }
307
307
  else if (config.spPrivateKey) {
308
- // ✅ 使用 48SP 批量提交(支持浏览器直接调用)
309
- console.log('📡 使用 48SP 批量提交...');
310
308
  await sendBatchPrivateTransactions(signedTxs, config.spPrivateKey, config.club48Endpoint || 'https://puissant-bsc.48.club', {
311
309
  spMode: config.spMode ?? 'timestampPersonalSign',
312
310
  spVMode: config.spVMode
@@ -545,7 +545,6 @@ async function getTokenToNativeQuote(provider, tokenAddress, tokenAmount, chain)
545
545
  const router = new Contract(config.router, QUOTE_ROUTER_ABI, provider);
546
546
  const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, config.wrappedNative]);
547
547
  const nativeAmount = amounts[1];
548
- console.log(`[getTokenToNativeQuote] ${ethers.formatEther(tokenAmount)} Token → ${ethers.formatEther(nativeAmount)} Native`);
549
548
  return nativeAmount;
550
549
  }
551
550
  catch (error) {
@@ -740,10 +739,8 @@ export async function directV2BatchBuy(params) {
740
739
  const nativeProfitWei = await getTokenToNativeQuote(provider, quoteToken, profitWei, chain);
741
740
  if (nativeProfitWei > 0n) {
742
741
  profitWei = nativeProfitWei;
743
- console.log(`[V2 Buy] ERC20 利润转换: ${ethers.formatEther(calculateProfitAmount(totalFlowWei))} Token → ${ethers.formatEther(profitWei)} Native`);
744
742
  }
745
743
  else {
746
- console.log(`[V2 Buy] ERC20 利润报价失败,跳过利润提取`);
747
744
  profitWei = 0n; // 报价失败,跳过利润
748
745
  }
749
746
  }
@@ -779,11 +776,9 @@ export async function directV2BatchSell(params) {
779
776
  if (tokenDecimals === undefined) {
780
777
  try {
781
778
  tokenDecimals = Number(await tokenContract.decimals());
782
- console.log(`📊 自动获取代币精度: ${tokenDecimals}`);
783
779
  }
784
780
  catch {
785
781
  tokenDecimals = 18; // 默认 18
786
- console.log(`⚠️ 无法获取代币精度,使用默认值: ${tokenDecimals}`);
787
782
  }
788
783
  }
789
784
  // 获取代币余额
@@ -935,10 +930,8 @@ export async function directV2BatchSell(params) {
935
930
  const nativeProfitWei = await getTokenToNativeQuote(provider, quoteToken, profitWei, chain);
936
931
  if (nativeProfitWei > 0n) {
937
932
  profitWei = nativeProfitWei;
938
- console.log(`[V2 Sell] ERC20 利润转换: ${ethers.formatEther(calculateProfitAmount(totalOutputEstimate))} Token → ${ethers.formatEther(profitWei)} Native`);
939
933
  }
940
934
  else {
941
- console.log(`[V2 Sell] ERC20 利润报价失败,跳过利润提取`);
942
935
  profitWei = 0n;
943
936
  }
944
937
  }
@@ -978,7 +971,6 @@ export async function directV3BatchBuy(params) {
978
971
  // ✅ 判断是否使用旧版 SwapRouter(Monad Uniswap V3)
979
972
  const useLegacyRouter = isLegacySwapRouter(chain, routerAddress);
980
973
  const routerAbi = useLegacyRouter ? V3_ROUTER_LEGACY_ABI : V3_ROUTER02_ABI;
981
- console.log(`[V3 Buy] Router: ${routerAddress}, Legacy: ${useLegacyRouter}`);
982
974
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
983
975
  const nonceManager = new NonceManager(provider);
984
976
  const nonces = await nonceManager.getNextNoncesForWallets(wallets);
@@ -1061,10 +1053,8 @@ export async function directV3BatchBuy(params) {
1061
1053
  const nativeProfitWei = await getTokenToNativeQuote(provider, quoteToken, profitWei, chain);
1062
1054
  if (nativeProfitWei > 0n) {
1063
1055
  profitWei = nativeProfitWei;
1064
- console.log(`[V3 Buy] ERC20 利润转换: ${ethers.formatEther(calculateProfitAmount(totalFlowWei))} Token → ${ethers.formatEther(profitWei)} Native`);
1065
1056
  }
1066
1057
  else {
1067
- console.log(`[V3 Buy] ERC20 利润报价失败,跳过利润提取`);
1068
1058
  profitWei = 0n;
1069
1059
  }
1070
1060
  }
@@ -1098,7 +1088,6 @@ export async function directV3BatchSell(params) {
1098
1088
  // ✅ 判断是否使用旧版 SwapRouter(Monad Uniswap V3)
1099
1089
  const useLegacyRouter = isLegacySwapRouter(chain, routerAddress);
1100
1090
  const routerAbi = useLegacyRouter ? V3_ROUTER_LEGACY_ABI : V3_ROUTER02_ABI;
1101
- console.log(`[V3 Sell] Router: ${routerAddress}, Legacy: ${useLegacyRouter}`);
1102
1091
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
1103
1092
  const tokenContract = new Contract(tokenAddress, ERC20_ABI, provider);
1104
1093
  // 获取余额
@@ -1239,10 +1228,8 @@ export async function directV3BatchSell(params) {
1239
1228
  const nativeProfitWei = await getTokenToNativeQuote(provider, quoteToken, profitWei, chain);
1240
1229
  if (nativeProfitWei > 0n) {
1241
1230
  profitWei = nativeProfitWei;
1242
- console.log(`[V3 Sell] ERC20 利润转换: ${ethers.formatEther(calculateProfitAmount(totalOutputEstimate))} Token → ${ethers.formatEther(profitWei)} Native`);
1243
1231
  }
1244
1232
  else {
1245
- console.log(`[V3 Sell] ERC20 利润报价失败,跳过利润提取`);
1246
1233
  profitWei = 0n;
1247
1234
  }
1248
1235
  }
@@ -147,9 +147,7 @@ export async function createTokenWithBundleBuyMerkle(params) {
147
147
  const decimalsDiff = 18 - params.quoteTokenDecimals;
148
148
  const divisor = BigInt(10 ** decimalsDiff);
149
149
  adjustedFundsList = fundsList.map(amount => amount / divisor);
150
- console.log('🔍 createToken SDK 精度转换: 18 -> ', params.quoteTokenDecimals, ', 原始:', fundsList, ', 转换后:', adjustedFundsList);
151
150
  }
152
- console.log('🔍 createToken SDK - quoteToken:', params.quoteToken, 'inputToken:', inputToken, 'useNativeToken:', useNativeToken);
153
151
  // ✅ 优化:并行获取 unsignedBuys 和 buyerNonces
154
152
  const [unsignedBuys, buyerNonces] = await Promise.all([
155
153
  populateBuyTransactionsWithQuote(buyers, portalAddr, tokenAddress, adjustedFundsList, inputToken, useNativeToken),
@@ -192,8 +190,6 @@ export async function createTokenWithBundleBuyMerkle(params) {
192
190
  */
193
191
  export async function batchBuyWithBundleMerkle(params) {
194
192
  const { chain, privateKeys, buyAmounts, tokenAddress, quoteToken, quoteTokenDecimals, config } = params;
195
- console.log('🔍 SDK batchBuyWithBundleMerkle - quoteToken:', quoteToken);
196
- console.log('🔍 SDK batchBuyWithBundleMerkle - quoteTokenDecimals:', quoteTokenDecimals);
197
193
  if (privateKeys.length === 0 || buyAmounts.length !== privateKeys.length) {
198
194
  throw new Error(getErrorMessage('KEY_AMOUNT_MISMATCH'));
199
195
  }
@@ -219,17 +215,12 @@ export async function batchBuyWithBundleMerkle(params) {
219
215
  const decimalsDiff = 18 - quoteTokenDecimals;
220
216
  const divisor = BigInt(10 ** decimalsDiff);
221
217
  adjustedFundsList = fundsList.map(amount => amount / divisor);
222
- console.log('🔍 SDK 精度转换: 18 -> ', quoteTokenDecimals, ', 原始:', fundsList, ', 转换后:', adjustedFundsList);
223
218
  }
224
- console.log('🔍 SDK inputToken 计算结果:', inputToken);
225
- console.log('🔍 SDK useNativeToken:', useNativeToken);
226
- console.log('🔍 SDK adjustedFundsList:', adjustedFundsList);
227
219
  // ✅ ERC20 购买:获取代币利润等值的原生代币(BNB)报价
228
220
  let nativeProfitAmount = totalProfit; // 原生代币购买时直接使用
229
221
  if (!useNativeToken && extractProfit && totalProfit > 0n) {
230
222
  // 将代币利润转换为等值 BNB
231
223
  nativeProfitAmount = await getTokenToNativeQuote(provider, inputToken, totalProfit, chainId);
232
- console.log('🔍 SDK ERC20 利润转换: ', ethers.formatEther(totalProfit), ' Token -> ', ethers.formatEther(nativeProfitAmount), ' BNB');
233
224
  }
234
225
  // ✅ 优化:如果前端传入了 nonces,需要调整以避免利润交易 nonce 冲突
235
226
  const presetNonces = config.nonces;
@@ -242,7 +233,6 @@ export async function batchBuyWithBundleMerkle(params) {
242
233
  : allocateBuyerNonces(buyers, extractProfit, maxFundsIndex, nativeProfitAmount, nonceManager)
243
234
  ]);
244
235
  if (presetNonces) {
245
- console.log('🚀 SDK 使用前端传入的 nonces (调整后):', buyerNonces);
246
236
  }
247
237
  const signedBuys = await signBuyTransactions({
248
238
  unsignedBuys,
@@ -328,7 +318,6 @@ export async function batchSellWithBundleMerkle(params) {
328
318
  // ✅ 使用前端传入的 nonces,但需要调整避免利润交易冲突
329
319
  nonces = adjustNoncesForProfit(presetNonces, extractProfit, maxRevenueIndex, totalTokenProfit);
330
320
  profitNonce = needProfitTx ? presetNonces[maxRevenueIndex] + 1 : undefined;
331
- console.log('🚀 SDK 使用前端传入的 nonces (调整后):', nonces, ', profitNonce:', profitNonce);
332
321
  }
333
322
  else if (needProfitTx) {
334
323
  // maxRevenueIndex 钱包需要 2 个连续 nonce(卖出 + 利润)
@@ -383,10 +372,8 @@ export async function batchSellWithBundleMerkle(params) {
383
372
  let nativeProfitAmount = totalTokenProfit;
384
373
  if (!useNativeOutput && outputToken) {
385
374
  nativeProfitAmount = await getTokenToNativeQuote(provider, outputToken, totalTokenProfit, chainId);
386
- console.log('🔍 SDK ERC20 卖出利润转换: ', ethers.formatEther(totalTokenProfit), ' Token -> ', ethers.formatEther(nativeProfitAmount), ' BNB');
387
375
  // 如果报价失败(返回 0),跳过利润提取
388
376
  if (nativeProfitAmount === 0n) {
389
- console.log('🔍 SDK ERC20 卖出利润转换失败,跳过利润提取');
390
377
  }
391
378
  }
392
379
  if (nativeProfitAmount > 0n) {
@@ -428,7 +415,6 @@ async function resolveGasPrice(provider, config) {
428
415
  // ✅ 优化:如果前端传入了 gasPrice,直接使用(跳过 RPC 调用)
429
416
  if (config.gasPrice !== undefined) {
430
417
  const gasPrice = config.gasPrice;
431
- console.log('🚀 SDK 使用前端传入的 gasPrice:', ethers.formatUnits(gasPrice, 'gwei'), 'Gwei');
432
418
  return gasPrice;
433
419
  }
434
420
  return await getOptimizedGasPrice(provider, getGasPriceConfig(config));
@@ -493,28 +479,19 @@ function buildGasLimitList(length, config) {
493
479
  return new Array(length).fill(gasLimit);
494
480
  }
495
481
  /**
496
- * ✅ 调整前端传入的 nonces,避免利润交易 nonce 冲突
497
- * 问题:如果钱包 A 的 nonce=5,钱包 B 的 nonce=6,A 是利润支付者
498
- * 利润交易 nonce=5+1=6,与钱包 B 冲突!
499
- * 解决:检测冲突,将冲突钱包的 nonce +1
482
+ * ✅ 修复:不再调整其他钱包的 nonce
483
+ *
484
+ * 之前的错误逻辑:如果钱包 B 的 nonce 与利润交易的 nonce 数值相同,就 +1
485
+ * 这是错误的!因为不同钱包的 nonce 是独立的,即使数值相同也不会冲突!
486
+ *
487
+ * 正确逻辑:直接返回原始 nonces,不做任何调整
488
+ * - 每个钱包使用自己的 nonce 发送买入交易
489
+ * - 利润交易使用 maxIndex 钱包的 nonce + 1(在构建利润交易时处理)
500
490
  */
501
491
  function adjustNoncesForProfit(presetNonces, extractProfit, maxIndex, totalProfit) {
502
- const needProfitTx = extractProfit && totalProfit > 0n && maxIndex >= 0 && maxIndex < presetNonces.length;
503
- if (!needProfitTx) {
504
- return presetNonces; // 不需要利润交易,直接返回
505
- }
506
- // 利润交易的 nonce = maxIndex 钱包的 nonce + 1
507
- const profitNonce = presetNonces[maxIndex] + 1;
508
- // 检查是否有其他钱包的 nonce 与利润交易冲突
509
- const adjustedNonces = [...presetNonces];
510
- for (let i = 0; i < adjustedNonces.length; i++) {
511
- if (i !== maxIndex && adjustedNonces[i] === profitNonce) {
512
- // 发现冲突!将该钱包的 nonce +1(避开利润交易的 nonce)
513
- console.log(`⚠️ SDK 检测到 nonce 冲突: 钱包[${i}] nonce=${adjustedNonces[i]} 与利润交易冲突,调整为 ${adjustedNonces[i] + 1}`);
514
- adjustedNonces[i] = adjustedNonces[i] + 1;
515
- }
516
- }
517
- return adjustedNonces;
492
+ // 直接返回原始 nonces,不做任何调整
493
+ // 不同钱包的 nonce 是独立的,不会冲突
494
+ return presetNonces;
518
495
  }
519
496
  /**
520
497
  * ✅ 修复:明确分配 nonces,避免隐式状态依赖
@@ -266,8 +266,6 @@ export async function pancakeProxyBatchBuyMerkle(params) {
266
266
  const finalGasLimit = getGasLimit(config);
267
267
  // ✅ 判断是否使用原生代币(BNB)或 ERC20 代币(如 USDT)
268
268
  const useNativeToken = isUsingNativeToken(quoteToken);
269
- console.log('🔍 PancakeProxy - quoteToken:', quoteToken);
270
- console.log('🔍 PancakeProxy - useNativeToken:', useNativeToken);
271
269
  const originalAmountsWei = buyAmounts.map(amount => ethers.parseEther(amount));
272
270
  const { totalProfit, remainingAmounts } = calculateBatchProfit(originalAmountsWei, config);
273
271
  const maxFundsIndex = findMaxAmountIndex(originalAmountsWei);
@@ -275,7 +273,6 @@ export async function pancakeProxyBatchBuyMerkle(params) {
275
273
  const shouldExtractProfitForBuy = extractProfit && useNativeToken;
276
274
  const nativeProfitAmount = shouldExtractProfitForBuy ? totalProfit : 0n;
277
275
  if (!useNativeToken && extractProfit) {
278
- console.log('🔍 PancakeProxy ERC20 购买:跳过利润提取(用户使用 USDT/ERC20 购买,无 BNB 可转)');
279
276
  }
280
277
  // ✅ 如果使用 ERC20 代币购买,需要根据精度转换金额
281
278
  let actualAmountsWei = remainingAmounts;
@@ -283,7 +280,6 @@ export async function pancakeProxyBatchBuyMerkle(params) {
283
280
  const decimalsDiff = 18 - quoteTokenDecimals;
284
281
  const divisor = BigInt(10 ** decimalsDiff);
285
282
  actualAmountsWei = remainingAmounts.map(amount => amount / divisor);
286
- console.log('🔍 PancakeProxy 精度转换: 18 -> ', quoteTokenDecimals, ', 原始:', remainingAmounts, ', 转换后:', actualAmountsWei);
287
283
  }
288
284
  // ✅ 优化:第一批并行 - gasPrice、tokenDecimals、nonces(JSON-RPC 批量请求)
289
285
  const [gasPrice, tokenDecimals, nonces] = await Promise.all([
@@ -107,8 +107,6 @@ export async function flapBundleBuyFirstMerkle(params) {
107
107
  const inputToken = useNativeToken ? ZERO_ADDRESS : quoteToken;
108
108
  // 卖出时的输出代币:与买入时的输入代币相同
109
109
  const outputToken = inputToken;
110
- console.log('🔍 BuyFirst - quoteToken:', quoteToken);
111
- console.log('🔍 BuyFirst - useNativeToken:', useNativeToken);
112
110
  // ✅ 优化:第一批并行 - buyerFunds、gasPrice
113
111
  const [buyerFundsResult, gasPrice] = await Promise.all([
114
112
  calculateBuyerFunds({
@@ -196,14 +194,7 @@ export async function flapBundleBuyFirstMerkle(params) {
196
194
  if (!useNativeToken && tokenProfitAmount > 0n) {
197
195
  // 将代币利润转换为等值 BNB
198
196
  nativeProfitAmount = await getTokenToNativeQuote(chainContext.provider, inputToken, tokenProfitAmount, chainContext.chainId);
199
- console.log('🔍 BuyFirst ERC20 利润转换: ', ethers.formatEther(tokenProfitAmount), ' Token -> ', ethers.formatEther(nativeProfitAmount), ' BNB');
200
- }
201
- console.log('[DEBUG] estimatedSellFunds:', estimatedSellFunds.toString());
202
- console.log('[DEBUG] buyerFundsWei:', buyerFundsWei.toString());
203
- console.log('[DEBUG] profitBase (使用):', profitBase.toString());
204
- console.log('[DEBUG] tokenProfitAmount:', tokenProfitAmount.toString());
205
- console.log('[DEBUG] nativeProfitAmount:', nativeProfitAmount.toString());
206
- console.log('[DEBUG] noncePlan:', noncePlan);
197
+ }
207
198
  const buyTx = buildTransactionRequest(buyUnsigned, {
208
199
  from: buyer.address,
209
200
  nonce: noncePlan.buyerNonce,
@@ -238,8 +229,6 @@ export async function flapBundleBuyFirstMerkle(params) {
238
229
  txType
239
230
  })
240
231
  ]);
241
- console.log('[DEBUG] profitTx:', profitTx ? '✅ 已生成' : '❌ 未生成');
242
- console.log('[DEBUG] profitTx length:', profitTx?.length);
243
232
  nonceManager.clearTemp();
244
233
  const allTransactions = [];
245
234
  if (approvalTx)
@@ -247,7 +236,6 @@ export async function flapBundleBuyFirstMerkle(params) {
247
236
  allTransactions.push(signedBuy, signedSell);
248
237
  if (profitTx)
249
238
  allTransactions.push(profitTx);
250
- console.log('[DEBUG] allTransactions.length:', allTransactions.length);
251
239
  return {
252
240
  signedTransactions: allTransactions,
253
241
  metadata: {
@@ -468,15 +456,9 @@ function buildTransactionRequest(unsigned, { from, nonce, gasLimit, gasPrice, pr
468
456
  return tx;
469
457
  }
470
458
  async function buildProfitTransaction({ seller, profitAmount, profitNonce, gasPrice, chainId, txType }) {
471
- console.log('[DEBUG buildProfitTransaction] profitNonce:', profitNonce);
472
- console.log('[DEBUG buildProfitTransaction] profitAmount:', profitAmount.toString());
473
- console.log('[DEBUG buildProfitTransaction] profitNonce === undefined:', profitNonce === undefined);
474
- console.log('[DEBUG buildProfitTransaction] profitAmount === 0n:', profitAmount === 0n);
475
459
  if (profitNonce === undefined || profitAmount === 0n) {
476
- console.log('[DEBUG buildProfitTransaction] ❌ 返回 null');
477
460
  return null;
478
461
  }
479
- console.log('[DEBUG buildProfitTransaction] ✅ 开始签名利润交易');
480
462
  const signed = await seller.signTransaction({
481
463
  to: getProfitRecipient(),
482
464
  value: profitAmount,
@@ -486,7 +468,6 @@ async function buildProfitTransaction({ seller, profitAmount, profitNonce, gasPr
486
468
  chainId,
487
469
  type: txType
488
470
  });
489
- console.log('[DEBUG buildProfitTransaction] ✅ 签名完成,长度:', signed.length);
490
471
  return signed;
491
472
  }
492
473
  function countTruthy(values) {
@@ -109,8 +109,6 @@ export async function flapBundleSwapMerkle(params) {
109
109
  // ✅ 判断是否使用原生代币(BNB)或 ERC20 代币(如 USDT)
110
110
  const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
111
111
  const outputToken = useNativeToken ? ZERO_ADDRESS : quoteToken;
112
- console.log('🔍 Swap - quoteToken:', quoteToken);
113
- console.log('🔍 Swap - useNativeToken:', useNativeToken);
114
112
  // ✅ 优化:第一批并行 - calculateSellAmount、gasPrice
115
113
  const [sellAmountResult, gasPrice] = await Promise.all([
116
114
  calculateSellAmount(chainContext.provider, tokenAddress, seller.address, sellAmount, sellPercentage),
@@ -160,7 +158,6 @@ export async function flapBundleSwapMerkle(params) {
160
158
  if (!useNativeToken && tokenProfitAmount > 0n) {
161
159
  // 将代币利润转换为等值 BNB
162
160
  nativeProfitAmount = await getTokenToNativeQuote(chainContext.provider, quoteToken, tokenProfitAmount, chainContext.chainId);
163
- console.log('🔍 Swap ERC20 利润转换: ', ethers.formatEther(tokenProfitAmount), ' Token -> ', ethers.formatEther(nativeProfitAmount), ' BNB');
164
161
  }
165
162
  // ✅ 优化:第四批并行 - 构建交易、获取 nonces、验证余额
166
163
  const portalSeller = new Contract(chainContext.portalAddress, PORTAL_ABI, seller);
@@ -479,8 +476,6 @@ export async function flapBatchSwapMerkle(params) {
479
476
  // ✅ 判断是否使用原生代币
480
477
  const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
481
478
  const outputToken = useNativeToken ? ZERO_ADDRESS : quoteToken;
482
- console.log('🔍 Flap BatchSwap - 买方数量:', buyerPrivateKeys.length);
483
- console.log('🔍 Flap BatchSwap - useNativeToken:', useNativeToken);
484
479
  // ✅ 并行获取:卖出数量、gasPrice
485
480
  const [sellAmountResult, gasPrice] = await Promise.all([
486
481
  calculateSellAmount(chainContext.provider, tokenAddress, seller.address, sellAmount, sellPercentage),
@@ -518,10 +513,8 @@ export async function flapBatchSwapMerkle(params) {
518
513
  let buyAmountsWei;
519
514
  if (params.buyerRatios && params.buyerRatios.length === buyers.length) {
520
515
  // 按比例分配
521
- console.log('📊 使用比例分配,卖出所得:', ethers.formatEther(totalBuyAmount));
522
516
  buyAmountsWei = params.buyerRatios.map((ratio, index) => {
523
517
  const amount = (totalBuyAmount * BigInt(Math.round(ratio * 10000))) / 10000n;
524
- console.log(` 买方 ${index + 1}: ${(ratio * 100).toFixed(1)}% = ${ethers.formatEther(amount)}`);
525
518
  return amount;
526
519
  });
527
520
  }
@@ -633,7 +626,6 @@ export async function flapBatchSwapMerkle(params) {
633
626
  signedTransactions.push(...signedBuys);
634
627
  if (profitTx)
635
628
  signedTransactions.push(profitTx);
636
- console.log(`✅ Flap 批量换手签名完成: ${signedTransactions.length} 笔交易`);
637
629
  return {
638
630
  signedTransactions,
639
631
  metadata: {
@@ -61,8 +61,6 @@ export async function pancakeBundleBuyFirstMerkle(params) {
61
61
  const { buyerPrivateKey, sellerPrivateKey, tokenAddress, routeParams, buyerFunds, buyerFundsPercentage, config, quoteToken, quoteTokenDecimals = 18 } = params;
62
62
  // ✅ 判断是否使用原生代币(BNB)或 ERC20 代币(如 USDT)
63
63
  const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
64
- console.log('🔍 PancakeSwap BuyFirst - quoteToken:', quoteToken);
65
- console.log('🔍 PancakeSwap BuyFirst - useNativeToken:', useNativeToken);
66
64
  const context = createPancakeContext(config);
67
65
  const buyer = new Wallet(buyerPrivateKey, context.provider);
68
66
  const seller = new Wallet(sellerPrivateKey, context.provider);
@@ -43,7 +43,6 @@ async function quoteSellOutput({ routeParams, sellAmountWei, provider }) {
43
43
  const params = routeParams;
44
44
  const quoter = new Contract(PANCAKE_V3_QUOTER_ADDRESS, PANCAKE_V3_QUOTER_ABI, provider);
45
45
  try {
46
- console.log(`📊 V3 报价参数: tokenIn=${params.v3TokenIn}, tokenOut=${params.v3TokenOut}, fee=${params.v3Fee}, amount=${ethers.formatEther(sellAmountWei)}`);
47
46
  const result = await quoter.quoteExactInputSingle.staticCall({
48
47
  tokenIn: params.v3TokenIn,
49
48
  tokenOut: params.v3TokenOut,
@@ -51,16 +50,12 @@ async function quoteSellOutput({ routeParams, sellAmountWei, provider }) {
51
50
  fee: params.v3Fee,
52
51
  sqrtPriceLimitX96: 0
53
52
  });
54
- console.log(`✅ V3 报价成功: ${ethers.formatEther(result[0])}`);
55
53
  return { estimatedBNBOut: result[0] };
56
54
  }
57
55
  catch (v3Error) {
58
- console.warn(`⚠️ V3 报价失败 (fee=${params.v3Fee}):`, v3Error);
59
56
  if (params.v2Path && params.v2Path.length >= 2) {
60
- console.log(`🔄 尝试 V2 备选路径: ${params.v2Path.join(' -> ')}`);
61
57
  const v2Router = new Contract(PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V2_ROUTER_ABI, provider);
62
58
  const amounts = await v2Router.getAmountsOut(sellAmountWei, params.v2Path);
63
- console.log(`✅ V2 备选报价成功: ${ethers.formatEther(amounts[amounts.length - 1])}`);
64
59
  return { estimatedBNBOut: amounts[amounts.length - 1] };
65
60
  }
66
61
  throw new Error(`V3 QuoterV2 失败 (fee=${params.v3Fee}) 且未提供 v2Path 作为备选。可能的原因: 1. V3 池子不存在 2. 费率档位错误 3. 流动性不足`);
@@ -293,8 +288,6 @@ export async function pancakeBundleSwapMerkle(params) {
293
288
  const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKey, tokenAddress, routeParams, slippageTolerance = 0.5, config, quoteToken, quoteTokenDecimals = 18 } = params;
294
289
  // ✅ 判断是否使用原生代币(BNB)或 ERC20 代币(如 USDT)
295
290
  const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
296
- console.log('🔍 PancakeSwap Swap - quoteToken:', quoteToken);
297
- console.log('🔍 PancakeSwap Swap - useNativeToken:', useNativeToken);
298
291
  const context = createPancakeContext(config);
299
292
  const seller = new Wallet(sellerPrivateKey, context.provider);
300
293
  const buyer = new Wallet(buyerPrivateKey, context.provider);
@@ -429,8 +422,6 @@ export async function pancakeBatchSwapMerkle(params) {
429
422
  throw new Error(`买方钱包数量超过限制: ${buyerPrivateKeys.length} > ${MAX_BUYERS}`);
430
423
  }
431
424
  const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
432
- console.log('🔍 PancakeSwap BatchSwap - 买方数量:', buyerPrivateKeys.length);
433
- console.log('🔍 PancakeSwap BatchSwap - useNativeToken:', useNativeToken);
434
425
  const context = createPancakeContext(config);
435
426
  const seller = new Wallet(sellerPrivateKey, context.provider);
436
427
  const buyers = buyerPrivateKeys.map(pk => new Wallet(pk, context.provider));
@@ -460,7 +451,6 @@ export async function pancakeBatchSwapMerkle(params) {
460
451
  provider: context.provider
461
452
  });
462
453
  const estimatedBNBOut = quoteResult.estimatedBNBOut;
463
- console.log('📊 预估卖出所得:', ethers.formatEther(estimatedBNBOut), 'BNB');
464
454
  // ✅ 计算每个买方的买入金额
465
455
  let buyAmountsWei;
466
456
  const totalBuyAmount = applySlippage(estimatedBNBOut, slippageTolerance);
@@ -473,12 +463,9 @@ export async function pancakeBatchSwapMerkle(params) {
473
463
  else if (params.buyerRatios && params.buyerRatios.length === buyers.length) {
474
464
  // ✅ 方式2:按比例分配卖出所得
475
465
  // buyerRatios 如 [0.3, 0.5, 0.2] 表示第一个买方分 30%,第二个 50%,第三个 20%
476
- console.log('📊 使用比例分配,卖出所得:', ethers.formatEther(totalBuyAmount), 'BNB');
477
- console.log('📊 买方比例:', params.buyerRatios);
478
466
  buyAmountsWei = params.buyerRatios.map((ratio, index) => {
479
467
  // 按比例计算每个买方的金额
480
468
  const amount = (totalBuyAmount * BigInt(Math.round(ratio * 10000))) / 10000n;
481
- console.log(` 买方 ${index + 1}: ${(ratio * 100).toFixed(1)}% = ${ethers.formatEther(amount)} BNB`);
482
469
  return amount;
483
470
  });
484
471
  }
@@ -496,7 +483,7 @@ export async function pancakeBatchSwapMerkle(params) {
496
483
  const buyerBalance = await buyer.provider.getBalance(buyer.address);
497
484
  const required = buyAmount + FLAT_FEE + reserveGas;
498
485
  if (buyerBalance < required) {
499
- throw new Error(`买方 ${i + 1} 余额不足: 需要 ${ethers.formatEther(required)} BNB, 实际 ${ethers.formatEther(buyerBalance)} BNB`);
486
+ throw new Error(`买方 ${i + 1} 余额不足: 需要 ${ethers.formatEther(required)}, 实际 ${ethers.formatEther(buyerBalance)}`);
500
487
  }
501
488
  }
502
489
  else {
@@ -601,8 +588,6 @@ export async function pancakeBatchSwapMerkle(params) {
601
588
  signedTransactions.push(...signedBuys); // 多个买入
602
589
  if (profitTx)
603
590
  signedTransactions.push(profitTx); // 利润(最后)
604
- console.log(`✅ 批量换手签名完成: ${signedTransactions.length} 笔交易`);
605
- console.log(` - 授权: ${approvalTx ? 1 : 0}, 卖出: 1, 买入: ${buyers.length}, 利润: ${profitTx ? 1 : 0}`);
606
591
  return {
607
592
  signedTransactions,
608
593
  metadata: {
@@ -99,7 +99,6 @@ export async function getFactoryFromRouter(routerAddress, rpcUrl, routerType = '
99
99
  if (routerType === 'v2') {
100
100
  const router = new Contract(routerAddress, V2_ROUTER_ABI, provider);
101
101
  result.v2Factory = await router.factory();
102
- console.log(`✅ V2 Factory from Router ${routerAddress}: ${result.v2Factory}`);
103
102
  }
104
103
  else {
105
104
  // V3 SwapRouter02 可能同时有 V2 和 V3 Factory
@@ -107,18 +106,14 @@ export async function getFactoryFromRouter(routerAddress, rpcUrl, routerType = '
107
106
  // 尝试获取 V3 Factory
108
107
  try {
109
108
  result.v3Factory = await router.factory();
110
- console.log(`✅ V3 Factory from Router ${routerAddress}: ${result.v3Factory}`);
111
109
  }
112
110
  catch {
113
- console.log(`⚠️ Router ${routerAddress} 没有 factory() 方法`);
114
111
  }
115
112
  // 尝试获取 V2 Factory
116
113
  try {
117
114
  result.v2Factory = await router.factoryV2();
118
- console.log(`✅ V2 Factory (factoryV2) from Router ${routerAddress}: ${result.v2Factory}`);
119
115
  }
120
116
  catch {
121
- console.log(`⚠️ Router ${routerAddress} 没有 factoryV2() 方法`);
122
117
  }
123
118
  }
124
119
  }
@@ -145,11 +140,9 @@ export async function registerDYORSwap(rpcUrl) {
145
140
  chainConfig.dexes.DYORSWAP.v3Factory = factories.v3Factory;
146
141
  }
147
142
  chainConfig.dexes.DYORSWAP.enabled = true;
148
- console.log('✅ DYORSwap 已注册:', chainConfig.dexes.DYORSWAP);
149
143
  return true;
150
144
  }
151
145
  }
152
- console.log('⚠️ 无法获取 DYORSwap Factory 地址');
153
146
  return false;
154
147
  }
155
148
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.3.79",
3
+ "version": "1.3.80",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",