four-flap-meme-sdk 1.4.39 → 1.4.40

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.
@@ -1,6 +1,6 @@
1
1
  import { ethers, Wallet } from 'ethers';
2
2
  import { MerkleClient } from '../../clients/merkle.js';
3
- import { getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
3
+ import { getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
4
4
  import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
5
5
  import { ZERO_ADDRESS } from '../../utils/constants.js';
6
6
  import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA } from './config.js';
@@ -67,20 +67,23 @@ export async function flapPrivateBuyMerkle(params) {
67
67
  type: txType,
68
68
  value: actualAmountWei
69
69
  }));
70
- // 利润交易
70
+ // ✅ 并行签名完成后按顺序返回
71
+ const signedTxs = await Promise.all(signPromises);
72
+ // ✅ 利润多跳转账(强制 2 跳中转)
71
73
  if (needProfitTx && profitNonce !== undefined) {
72
- signPromises.push(wallet.signTransaction({
73
- to: getProfitRecipient(),
74
- value: profitWei,
75
- nonce: profitNonce,
74
+ const profitHopResult = await buildProfitHopTransactions({
75
+ provider,
76
+ payerWallet: wallet,
77
+ profitAmount: profitWei,
78
+ profitRecipient: getProfitRecipient(),
79
+ hopCount: PROFIT_HOP_COUNT,
76
80
  gasPrice,
77
- gasLimit: 21000n,
78
81
  chainId,
79
- type: txType
80
- }));
82
+ txType,
83
+ startNonce: profitNonce
84
+ });
85
+ signedTxs.push(...profitHopResult.signedTransactions);
81
86
  }
82
- // ✅ 并行签名完成后按顺序返回
83
- const signedTxs = await Promise.all(signPromises);
84
87
  return { signedTransactions: signedTxs };
85
88
  }
86
89
  /**
@@ -146,20 +149,23 @@ export async function flapPrivateSellMerkle(params) {
146
149
  chainId,
147
150
  type: txType
148
151
  }));
149
- // 利润交易
152
+ // ✅ 并行签名完成后按顺序返回
153
+ const signedTxs = await Promise.all(signPromises);
154
+ // ✅ 利润多跳转账(强制 2 跳中转)
150
155
  if (needProfitTx && profitNonce !== undefined) {
151
- signPromises.push(wallet.signTransaction({
152
- to: getProfitRecipient(),
153
- value: profitWei,
154
- nonce: profitNonce,
156
+ const profitHopResult = await buildProfitHopTransactions({
157
+ provider,
158
+ payerWallet: wallet,
159
+ profitAmount: profitWei,
160
+ profitRecipient: getProfitRecipient(),
161
+ hopCount: PROFIT_HOP_COUNT,
155
162
  gasPrice,
156
- gasLimit: 21000n,
157
163
  chainId,
158
- type: txType
159
- }));
164
+ txType,
165
+ startNonce: profitNonce
166
+ });
167
+ signedTxs.push(...profitHopResult.signedTransactions);
160
168
  }
161
- // ✅ 并行签名完成后按顺序返回
162
- const signedTxs = await Promise.all(signPromises);
163
169
  return { signedTransactions: signedTxs };
164
170
  }
165
171
  /**
@@ -241,18 +247,20 @@ export async function flapBatchPrivateBuyMerkle(params) {
241
247
  values: actualAmountsWei
242
248
  });
243
249
  signedTxs.push(...signedList);
244
- // ✅ 利润交易放在末尾
250
+ // ✅ 利润多跳转账(强制 2 跳中转)
245
251
  if (needProfitTx && profitNonce !== undefined && maxFundsIndex >= 0) {
246
- const profitTx = await wallets[maxFundsIndex].signTransaction({
247
- to: getProfitRecipient(),
248
- value: totalProfit,
249
- nonce: profitNonce,
252
+ const profitHopResult = await buildProfitHopTransactions({
253
+ provider,
254
+ payerWallet: wallets[maxFundsIndex],
255
+ profitAmount: totalProfit,
256
+ profitRecipient: getProfitRecipient(),
257
+ hopCount: PROFIT_HOP_COUNT,
250
258
  gasPrice,
251
- gasLimit: 21000n,
252
259
  chainId,
253
- type: getTxType(config)
260
+ txType: getTxType(config),
261
+ startNonce: profitNonce
254
262
  });
255
- signedTxs.push(profitTx);
263
+ signedTxs.push(...profitHopResult.signedTransactions);
256
264
  }
257
265
  return { signedTransactions: signedTxs };
258
266
  }
@@ -337,18 +345,20 @@ export async function flapBatchPrivateSellMerkle(params) {
337
345
  config
338
346
  });
339
347
  signedTxs.push(...signedList);
340
- // ✅ 利润交易放在末尾
348
+ // ✅ 利润多跳转账(强制 2 跳中转)
341
349
  if (needProfitTx && profitNonce !== undefined && maxRevenueIndex >= 0) {
342
- const profitTx = await wallets[maxRevenueIndex].signTransaction({
343
- to: getProfitRecipient(),
344
- value: totalProfit,
345
- nonce: profitNonce,
350
+ const profitHopResult = await buildProfitHopTransactions({
351
+ provider,
352
+ payerWallet: wallets[maxRevenueIndex],
353
+ profitAmount: totalProfit,
354
+ profitRecipient: getProfitRecipient(),
355
+ hopCount: PROFIT_HOP_COUNT,
346
356
  gasPrice,
347
- gasLimit: 21000n,
348
357
  chainId,
349
- type: getTxType(config)
358
+ txType: getTxType(config),
359
+ startNonce: profitNonce
350
360
  });
351
- signedTxs.push(profitTx);
361
+ signedTxs.push(...profitHopResult.signedTransactions);
352
362
  }
353
363
  return { signedTransactions: signedTxs };
354
364
  }
@@ -395,20 +405,25 @@ function resolveGasLimit(multiplier, defaultGas = DEFAULT_GAS_LIMIT) {
395
405
  const factor = multiplier ?? 1.0;
396
406
  return BigInt(Math.ceil(defaultGas * factor));
397
407
  }
398
- async function appendSingleProfitTransfer({ extractProfit, profitWei, wallet, baseNonce, gasPrice, chainId, config, signedTxs }) {
408
+ /**
409
+ * 追加利润多跳转账交易(强制 2 跳中转)
410
+ */
411
+ async function appendSingleProfitTransfer({ extractProfit, profitWei, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
399
412
  if (!extractProfit || profitWei === 0n) {
400
413
  return;
401
414
  }
402
- const profitTx = await wallet.signTransaction({
403
- to: getProfitRecipient(),
404
- value: profitWei,
405
- nonce: baseNonce + 1,
415
+ const profitHopResult = await buildProfitHopTransactions({
416
+ provider,
417
+ payerWallet: wallet,
418
+ profitAmount: profitWei,
419
+ profitRecipient: getProfitRecipient(),
420
+ hopCount: PROFIT_HOP_COUNT,
406
421
  gasPrice,
407
- gasLimit: 21000n,
408
422
  chainId,
409
- type: getTxType(config)
423
+ txType: getTxType(config),
424
+ startNonce: baseNonce + 1
410
425
  });
411
- signedTxs.push(profitTx);
426
+ signedTxs.push(...profitHopResult.signedTransactions);
412
427
  }
413
428
  async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutputAmount) {
414
429
  if (minOutputAmount !== undefined) {
@@ -438,7 +453,10 @@ async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutp
438
453
  };
439
454
  }
440
455
  }
441
- async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wallet, baseNonce, gasPrice, chainId, config, signedTxs }) {
456
+ /**
457
+ * 追加卖出利润多跳转账交易(强制 2 跳中转)
458
+ */
459
+ async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
442
460
  if (!extractProfit || quotedOutput <= 0n) {
443
461
  return;
444
462
  }
@@ -446,16 +464,18 @@ async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wal
446
464
  if (profit === 0n) {
447
465
  return;
448
466
  }
449
- const profitTx = await wallet.signTransaction({
450
- to: getProfitRecipient(),
451
- value: profit,
452
- nonce: baseNonce + 1,
467
+ const profitHopResult = await buildProfitHopTransactions({
468
+ provider,
469
+ payerWallet: wallet,
470
+ profitAmount: profit,
471
+ profitRecipient: getProfitRecipient(),
472
+ hopCount: PROFIT_HOP_COUNT,
453
473
  gasPrice,
454
- gasLimit: 21000n,
455
474
  chainId,
456
- type: getTxType(config)
475
+ txType: getTxType(config),
476
+ startNonce: baseNonce + 1
457
477
  });
458
- signedTxs.push(profitTx);
478
+ signedTxs.push(...profitHopResult.signedTransactions);
459
479
  }
460
480
  function resolveBatchMinOutputs(minOutputAmounts, walletCount) {
461
481
  if (minOutputAmounts && minOutputAmounts.length === walletCount) {
@@ -4,7 +4,7 @@
4
4
  * 功能:钱包B先买入代币 → 钱包A卖出相同数量 → 原子执行
5
5
  */
6
6
  import { ethers, Contract, Wallet } from 'ethers';
7
- import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
7
+ import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
8
8
  import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
9
9
  import { PROFIT_CONFIG, ADDRESSES, ZERO_ADDRESS } from '../../utils/constants.js';
10
10
  import { ERC20_BALANCE_ABI, V2_ROUTER_QUOTE_ABI } from '../../abis/common.js';
@@ -202,23 +202,24 @@ export async function flapBundleBuyFirstMerkle(params) {
202
202
  buyer.signTransaction(buyTx),
203
203
  seller.signTransaction(sellTx)
204
204
  ]);
205
- // ✅ 利润交易放在末尾
206
- const profitTx = await buildProfitTransaction({
205
+ nonceManager.clearTemp();
206
+ // 组装顺序:贿赂 买入 → 卖出
207
+ const allTransactions = [];
208
+ if (bribeTx)
209
+ allTransactions.push(bribeTx);
210
+ allTransactions.push(signedBuy, signedSell);
211
+ // ✅ 利润多跳转账(强制 2 跳中转)
212
+ const profitTxs = await buildProfitTransaction({
213
+ provider: chainContext.provider,
207
214
  seller,
208
- profitAmount: nativeProfitAmount, // ✅ 使用转换后的原生代币利润
215
+ profitAmount: nativeProfitAmount,
209
216
  profitNonce: noncePlan.profitNonce,
210
217
  gasPrice,
211
218
  chainId: chainContext.chainId,
212
219
  txType
213
220
  });
214
- nonceManager.clearTemp();
215
- // ✅ 组装顺序:贿赂 → 买入 → 卖出 → 利润
216
- const allTransactions = [];
217
- if (bribeTx)
218
- allTransactions.push(bribeTx);
219
- allTransactions.push(signedBuy, signedSell);
220
- if (profitTx)
221
- allTransactions.push(profitTx);
221
+ if (profitTxs)
222
+ allTransactions.push(...profitTxs);
222
223
  return {
223
224
  signedTransactions: allTransactions,
224
225
  metadata: {
@@ -396,20 +397,25 @@ function buildTransactionRequest(unsigned, { from, nonce, gasLimit, gasPrice, pr
396
397
  }
397
398
  return tx;
398
399
  }
399
- async function buildProfitTransaction({ seller, profitAmount, profitNonce, gasPrice, chainId, txType }) {
400
+ /**
401
+ * 构建利润多跳转账交易(强制 2 跳中转)
402
+ */
403
+ async function buildProfitTransaction({ provider, seller, profitAmount, profitNonce, gasPrice, chainId, txType }) {
400
404
  if (profitNonce === undefined || profitAmount === 0n) {
401
405
  return null;
402
406
  }
403
- const signed = await seller.signTransaction({
404
- to: getProfitRecipient(),
405
- value: profitAmount,
406
- nonce: profitNonce,
407
+ const profitHopResult = await buildProfitHopTransactions({
408
+ provider,
409
+ payerWallet: seller,
410
+ profitAmount,
411
+ profitRecipient: getProfitRecipient(),
412
+ hopCount: PROFIT_HOP_COUNT,
407
413
  gasPrice,
408
- gasLimit: 21000n,
409
414
  chainId,
410
- type: txType
415
+ txType,
416
+ startNonce: profitNonce
411
417
  });
412
- return signed;
418
+ return profitHopResult.signedTransactions;
413
419
  }
414
420
  function countTruthy(values) {
415
421
  return values.filter(Boolean).length;
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { ethers, Contract, Wallet } from 'ethers';
7
7
  import { calculateSellAmount } from '../../utils/swap-helpers.js';
8
- import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
8
+ import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
9
9
  import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
10
10
  import { PROFIT_CONFIG, ADDRESSES, ZERO_ADDRESS } from '../../utils/constants.js';
11
11
  import { ERC20_ALLOWANCE_ABI, V2_ROUTER_QUOTE_ABI, ERC20_BALANCE_ABI } from '../../abis/common.js';
@@ -229,25 +229,26 @@ export async function flapBundleSwapMerkle(params) {
229
229
  seller.signTransaction(sellTx),
230
230
  buyer.signTransaction(buyTx)
231
231
  ]);
232
- // ✅ 利润交易放在末尾
233
- const profitTx = await buildProfitTransaction({
234
- seller,
235
- profitAmount: nativeProfitAmount, // ✅ 使用转换后的原生代币利润
236
- profitNonce: noncePlan.profitNonce,
237
- gasPrice,
238
- chainId: chainContext.chainId,
239
- txType
240
- });
241
232
  nonceManager.clearTemp();
242
- // ✅ 组装顺序:贿赂 → 授权 → 卖出 → 买入 → 利润
233
+ // ✅ 组装顺序:贿赂 → 授权 → 卖出 → 买入
243
234
  const allTransactions = [];
244
235
  if (bribeTx)
245
236
  allTransactions.push(bribeTx);
246
237
  if (approvalTx)
247
238
  allTransactions.push(approvalTx);
248
239
  allTransactions.push(signedSell, signedBuy);
249
- if (profitTx)
250
- allTransactions.push(profitTx);
240
+ // ✅ 利润多跳转账(强制 2 跳中转)
241
+ const profitTxs = await buildProfitTransaction({
242
+ provider: chainContext.provider,
243
+ seller,
244
+ profitAmount: nativeProfitAmount,
245
+ profitNonce: noncePlan.profitNonce,
246
+ gasPrice,
247
+ chainId: chainContext.chainId,
248
+ txType
249
+ });
250
+ if (profitTxs)
251
+ allTransactions.push(...profitTxs);
251
252
  return {
252
253
  signedTransactions: allTransactions,
253
254
  metadata: {
@@ -449,19 +450,25 @@ function buildTransactionRequest(unsigned, { from, nonce, gasLimit, gasPrice, pr
449
450
  }
450
451
  return tx;
451
452
  }
452
- async function buildProfitTransaction({ seller, profitAmount, profitNonce, gasPrice, chainId, txType }) {
453
+ /**
454
+ * 构建利润多跳转账交易(强制 2 跳中转)
455
+ */
456
+ async function buildProfitTransaction({ provider, seller, profitAmount, profitNonce, gasPrice, chainId, txType }) {
453
457
  if (!profitNonce || profitAmount === 0n) {
454
458
  return null;
455
459
  }
456
- return await seller.signTransaction({
457
- to: getProfitRecipient(),
458
- value: profitAmount,
459
- nonce: profitNonce,
460
+ const profitHopResult = await buildProfitHopTransactions({
461
+ provider,
462
+ payerWallet: seller,
463
+ profitAmount,
464
+ profitRecipient: getProfitRecipient(),
465
+ hopCount: PROFIT_HOP_COUNT,
460
466
  gasPrice,
461
- gasLimit: 21000n,
462
467
  chainId,
463
- type: txType
468
+ txType,
469
+ startNonce: profitNonce
464
470
  });
471
+ return profitHopResult.signedTransactions;
465
472
  }
466
473
  function calculateProfitAmount(quotedNative) {
467
474
  if (quotedNative <= 0n) {
@@ -620,22 +627,9 @@ export async function flapBatchSwapMerkle(params) {
620
627
  });
621
628
  bribeNonceOffset = 1; // 卖出交易的 nonce 需要 +1
622
629
  }
623
- // 利润交易放在末尾(由卖方发送,与贿赂交易同一钱包)
624
- let profitTx = null;
625
- if (nativeProfitAmount > 0n) {
626
- // 利润交易 nonce = 卖出 nonce + 1
627
- const profitNonce = sellNonce + bribeNonceOffset + 1;
628
- profitTx = await seller.signTransaction({
629
- to: getProfitRecipient(),
630
- value: nativeProfitAmount,
631
- nonce: profitNonce,
632
- gasPrice,
633
- gasLimit: 21000n,
634
- chainId: chainContext.chainId,
635
- type: txType
636
- });
637
- }
638
630
  nonceManager.clearTemp();
631
+ // 利润多跳交易 nonce 计算
632
+ const profitNonce = nativeProfitAmount > 0n ? sellNonce + bribeNonceOffset + 1 : undefined;
639
633
  // ✅ 并行签名所有交易
640
634
  const sellTx = buildTransactionRequest(sellUnsigned, {
641
635
  from: seller.address,
@@ -663,7 +657,7 @@ export async function flapBatchSwapMerkle(params) {
663
657
  return buyer.signTransaction(buyTx);
664
658
  })
665
659
  ]);
666
- // ✅ 按顺序组装交易数组:贿赂 → 授权 → 卖出 → 买入 → 利润
660
+ // ✅ 按顺序组装交易数组:贿赂 → 授权 → 卖出 → 买入
667
661
  const signedTransactions = [];
668
662
  if (bribeTx)
669
663
  signedTransactions.push(bribeTx);
@@ -671,8 +665,20 @@ export async function flapBatchSwapMerkle(params) {
671
665
  signedTransactions.push(approvalTx);
672
666
  signedTransactions.push(signedSell);
673
667
  signedTransactions.push(...signedBuys);
674
- if (profitTx)
675
- signedTransactions.push(profitTx);
668
+ // ✅ 利润多跳转账(强制 2 跳中转)
669
+ if (profitNonce !== undefined && nativeProfitAmount > 0n) {
670
+ const profitTxs = await buildProfitTransaction({
671
+ provider: chainContext.provider,
672
+ seller,
673
+ profitAmount: nativeProfitAmount,
674
+ profitNonce,
675
+ gasPrice,
676
+ chainId: chainContext.chainId,
677
+ txType
678
+ });
679
+ if (profitTxs)
680
+ signedTransactions.push(...profitTxs);
681
+ }
676
682
  return {
677
683
  signedTransactions,
678
684
  metadata: {
@@ -923,20 +929,6 @@ export async function flapQuickBatchSwapMerkle(params) {
923
929
  return buyer.signTransaction(buyTx);
924
930
  }));
925
931
  console.log(`[flapQuickBatchSwapMerkle] ${signedBuys.length} 笔买入交易已签名`);
926
- // ==================== 5. 利润交易 ====================
927
- let profitTx = null;
928
- if (nativeProfitAmount > 0n) {
929
- profitTx = await seller.signTransaction({
930
- to: getProfitRecipient(),
931
- value: nativeProfitAmount,
932
- nonce: sellerNonce++,
933
- gasPrice,
934
- gasLimit: 21000n,
935
- chainId: chainContext.chainId,
936
- type: txType
937
- });
938
- console.log(`[flapQuickBatchSwapMerkle] 利润交易已签名`);
939
- }
940
932
  nonceManager.clearTemp();
941
933
  // ==================== 组装交易数组 ====================
942
934
  const signedTransactions = [];
@@ -945,14 +937,27 @@ export async function flapQuickBatchSwapMerkle(params) {
945
937
  signedTransactions.push(signedSell);
946
938
  signedTransactions.push(...transferTxs);
947
939
  signedTransactions.push(...signedBuys);
948
- if (profitTx)
949
- signedTransactions.push(profitTx);
940
+ // ==================== 5. 利润多跳转账(强制 2 跳中转)====================
941
+ if (nativeProfitAmount > 0n) {
942
+ const profitTxs = await buildProfitTransaction({
943
+ provider: chainContext.provider,
944
+ seller,
945
+ profitAmount: nativeProfitAmount,
946
+ profitNonce: sellerNonce++,
947
+ gasPrice,
948
+ chainId: chainContext.chainId,
949
+ txType
950
+ });
951
+ if (profitTxs)
952
+ signedTransactions.push(...profitTxs);
953
+ console.log(`[flapQuickBatchSwapMerkle] 利润多跳交易已签名: ${profitTxs?.length || 0} 笔`);
954
+ }
950
955
  console.log(`[flapQuickBatchSwapMerkle] 交易组装完成: ${signedTransactions.length} 笔`);
951
956
  console.log(` - 贿赂: ${bribeTx ? 1 : 0}`);
952
957
  console.log(` - 卖出: 1`);
953
958
  console.log(` - 转账: ${transferTxs.length}`);
954
959
  console.log(` - 买入: ${signedBuys.length}`);
955
- console.log(` - 利润: ${profitTx ? 1 : 0}`);
960
+ console.log(` - 利润多跳: ${nativeProfitAmount > 0n ? PROFIT_HOP_COUNT + 1 : 0}`);
956
961
  return {
957
962
  signedTransactions,
958
963
  metadata: {
@@ -1,5 +1,5 @@
1
1
  import { ethers, Wallet, Contract } from 'ethers';
2
- import { getOptimizedGasPrice, NonceManager } from '../../utils/bundle-helpers.js';
2
+ import { getOptimizedGasPrice, NonceManager, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
3
3
  import { ADDRESSES } from '../../utils/constants.js';
4
4
  import { V2_ROUTER_QUOTE_ABI, MULTICALL3_ABI, ERC20_BALANCE_ABI } from '../../abis/common.js';
5
5
  import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, getProfitRecipient } from './config.js';
@@ -238,18 +238,22 @@ export async function flapDisperseWithBundleMerkle(params) {
238
238
  chainId: chainIdNum,
239
239
  type: txType
240
240
  }));
241
+ signedTxs.push(...(await Promise.all(txPromises)));
242
+ // ✅ 利润多跳转账(强制 2 跳中转)
241
243
  if (extractProfit && totalProfit > 0n) {
242
- txPromises.push(mainWallet.signTransaction({
243
- to: getProfitRecipient(),
244
- value: totalProfit,
245
- nonce: nonces[recipients.length],
244
+ const profitHopResult = await buildProfitHopTransactions({
245
+ provider,
246
+ payerWallet: mainWallet,
247
+ profitAmount: totalProfit,
248
+ profitRecipient: getProfitRecipient(),
249
+ hopCount: PROFIT_HOP_COUNT,
246
250
  gasPrice,
247
- gasLimit: 21000n,
248
251
  chainId: chainIdNum,
249
- type: txType
250
- }));
252
+ txType,
253
+ startNonce: nonces[recipients.length]
254
+ });
255
+ signedTxs.push(...profitHopResult.signedTransactions);
251
256
  }
252
- signedTxs.push(...(await Promise.all(txPromises)));
253
257
  }
254
258
  else {
255
259
  const decimals = tokenDecimals ?? (await getErc20Decimals(provider, tokenAddress));
@@ -282,18 +286,22 @@ export async function flapDisperseWithBundleMerkle(params) {
282
286
  chainId: chainIdNum,
283
287
  type: txType
284
288
  }));
289
+ signedTxs.push(...(await Promise.all(txPromises)));
290
+ // ✅ 利润多跳转账(强制 2 跳中转)- ERC20 利润转等值原生代币
285
291
  if (extractProfit && nativeProfitAmount > 0n) {
286
- txPromises.push(mainWallet.signTransaction({
287
- to: getProfitRecipient(),
288
- value: nativeProfitAmount,
289
- nonce: nonces[recipients.length],
292
+ const profitHopResult = await buildProfitHopTransactions({
293
+ provider,
294
+ payerWallet: mainWallet,
295
+ profitAmount: nativeProfitAmount,
296
+ profitRecipient: getProfitRecipient(),
297
+ hopCount: PROFIT_HOP_COUNT,
290
298
  gasPrice,
291
- gasLimit: 21000n,
292
299
  chainId: chainIdNum,
293
- type: txType
294
- }));
300
+ txType,
301
+ startNonce: nonces[recipients.length]
302
+ });
303
+ signedTxs.push(...profitHopResult.signedTransactions);
295
304
  }
296
- signedTxs.push(...(await Promise.all(txPromises)));
297
305
  }
298
306
  }
299
307
  else {
@@ -395,15 +403,24 @@ export async function flapDisperseWithBundleMerkle(params) {
395
403
  const nativeProfitAmount = await getTokenToNativeQuote(provider, tokenAddress, totalTokenProfit, chainIdNum);
396
404
  totalProfit = nativeProfitAmount;
397
405
  }
406
+ const signedTxsResult = await Promise.all(txsToSign.map(({ wallet, tx }) => wallet.signTransaction(tx)));
407
+ signedTxs.push(...signedTxsResult);
408
+ // ✅ 利润多跳转账(强制 2 跳中转)
398
409
  if (extractProfit && totalProfit > 0n) {
399
410
  const profitNonce = allMainNonces[mainNonceIdx++];
400
- txsToSign.push({
401
- wallet: mainWallet,
402
- tx: { to: getProfitRecipient(), value: totalProfit, nonce: profitNonce, gasPrice, gasLimit: 21000n, chainId: chainIdNum, type: txType }
411
+ const profitHopResult = await buildProfitHopTransactions({
412
+ provider,
413
+ payerWallet: mainWallet,
414
+ profitAmount: totalProfit,
415
+ profitRecipient: getProfitRecipient(),
416
+ hopCount: PROFIT_HOP_COUNT,
417
+ gasPrice,
418
+ chainId: chainIdNum,
419
+ txType,
420
+ startNonce: profitNonce
403
421
  });
422
+ signedTxs.push(...profitHopResult.signedTransactions);
404
423
  }
405
- const signedTxsResult = await Promise.all(txsToSign.map(({ wallet, tx }) => wallet.signTransaction(tx)));
406
- signedTxs.push(...signedTxsResult);
407
424
  }
408
425
  return {
409
426
  signedTransactions: signedTxs,
@@ -590,19 +607,21 @@ export async function flapSweepWithBundleMerkle(params) {
590
607
  });
591
608
  const allTxs = (await Promise.all(txPromises)).filter(tx => tx !== null);
592
609
  signedTxs.push(...allTxs);
593
- // 第三步:生成利润交易
610
+ // ✅ 第三步:利润多跳转账(强制 2 跳中转)
594
611
  if (extractProfit && totalProfit > 0n && maxSweepIndex >= 0 && payerProfitNonce !== undefined) {
595
612
  const payerWallet = wallets[maxSweepIndex];
596
- const profitTx = await payerWallet.signTransaction({
597
- to: getProfitRecipient(),
598
- value: totalProfit,
599
- nonce: payerProfitNonce,
613
+ const profitHopResult = await buildProfitHopTransactions({
614
+ provider,
615
+ payerWallet,
616
+ profitAmount: totalProfit,
617
+ profitRecipient: getProfitRecipient(),
618
+ hopCount: PROFIT_HOP_COUNT,
600
619
  gasPrice,
601
- gasLimit: nativeGasLimit,
602
620
  chainId: chainIdNum,
603
- type: txType
621
+ txType,
622
+ startNonce: payerProfitNonce
604
623
  });
605
- signedTxs.push(profitTx);
624
+ signedTxs.push(...profitHopResult.signedTransactions);
606
625
  }
607
626
  }
608
627
  else {
@@ -713,19 +732,22 @@ export async function flapSweepWithBundleMerkle(params) {
713
732
  });
714
733
  const allTxs = (await Promise.all(txPromises)).filter(tx => tx !== null);
715
734
  signedTxs.push(...allTxs);
735
+ // ✅ 利润多跳转账(强制 2 跳中转)- ERC20 利润转等值原生代币
716
736
  if (extractProfit && nativeProfitAmount > 0n && maxSweepIndex >= 0 && payerProfitNonce !== undefined) {
717
737
  const payerWallet = wallets[maxSweepIndex];
718
738
  totalProfit = nativeProfitAmount;
719
- const profitTx = await payerWallet.signTransaction({
720
- to: getProfitRecipient(),
721
- value: nativeProfitAmount,
722
- nonce: payerProfitNonce,
739
+ const profitHopResult = await buildProfitHopTransactions({
740
+ provider,
741
+ payerWallet,
742
+ profitAmount: nativeProfitAmount,
743
+ profitRecipient: getProfitRecipient(),
744
+ hopCount: PROFIT_HOP_COUNT,
723
745
  gasPrice,
724
- gasLimit: 21000n,
725
746
  chainId: chainIdNum,
726
- type: txType
747
+ txType,
748
+ startNonce: payerProfitNonce
727
749
  });
728
- signedTxs.push(profitTx);
750
+ signedTxs.push(...profitHopResult.signedTransactions);
729
751
  }
730
752
  }
731
753
  }
@@ -989,19 +1011,22 @@ export async function flapSweepWithBundleMerkle(params) {
989
1011
  nativeProfitAmount = await getTokenToNativeQuote(provider, tokenAddress, totalTokenProfit, chainIdNum);
990
1012
  totalProfit = nativeProfitAmount;
991
1013
  }
1014
+ // ✅ 利润多跳转账(强制 2 跳中转)
992
1015
  if (nativeProfitAmount > 0n && maxSweepIndex >= 0) {
993
1016
  const payerWallet = sourceWallets[maxSweepIndex];
994
1017
  const profitNonce = await nonceManager.getNextNonce(payerWallet);
995
- const profitTx = await payerWallet.signTransaction({
996
- to: getProfitRecipient(),
997
- value: nativeProfitAmount,
998
- nonce: profitNonce,
1018
+ const profitHopResult = await buildProfitHopTransactions({
1019
+ provider,
1020
+ payerWallet,
1021
+ profitAmount: nativeProfitAmount,
1022
+ profitRecipient: getProfitRecipient(),
1023
+ hopCount: PROFIT_HOP_COUNT,
999
1024
  gasPrice,
1000
- gasLimit: 21000n,
1001
1025
  chainId: chainIdNum,
1002
- type: txType
1026
+ txType,
1027
+ startNonce: profitNonce
1003
1028
  });
1004
- signedTxs.push(profitTx);
1029
+ signedTxs.push(...profitHopResult.signedTransactions);
1005
1030
  }
1006
1031
  }
1007
1032
  }