four-flap-meme-sdk 1.4.58 → 1.4.61
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/contracts/tm-bundle-merkle/core.js +13 -5
- package/dist/contracts/tm-bundle-merkle/internal.d.ts +5 -1
- package/dist/contracts/tm-bundle-merkle/internal.js +8 -1
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.js +8 -2
- package/dist/contracts/tm-bundle-merkle/private.js +16 -4
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.d.ts +2 -0
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.js +3 -0
- package/dist/contracts/tm-bundle-merkle/swap.d.ts +3 -0
- package/dist/contracts/tm-bundle-merkle/swap.js +10 -1
- package/dist/contracts/tm-bundle-merkle/types.d.ts +5 -2
- package/dist/contracts/tm-bundle-merkle/types.js +0 -3
- package/dist/contracts/tm-bundle-merkle/utils.js +14 -2
- package/dist/contracts/tm-bundle.d.ts +4 -0
- package/dist/contracts/tm-bundle.js +10 -3
- package/dist/dex/direct-router.d.ts +2 -0
- package/dist/dex/direct-router.js +22 -7
- package/dist/flap/portal-bundle-merkle/core.js +10 -1
- package/dist/flap/portal-bundle-merkle/pancake-proxy.js +8 -2
- package/dist/flap/portal-bundle-merkle/private.js +17 -7
- package/dist/flap/portal-bundle-merkle/swap-buy-first.d.ts +2 -0
- package/dist/flap/portal-bundle-merkle/swap-buy-first.js +8 -4
- package/dist/flap/portal-bundle-merkle/swap.d.ts +3 -0
- package/dist/flap/portal-bundle-merkle/swap.js +24 -12
- package/dist/flap/portal-bundle-merkle/types.d.ts +3 -0
- package/dist/flap/portal-bundle-merkle/types.js +0 -3
- package/dist/flap/portal-bundle-merkle/utils.d.ts +5 -2
- package/dist/flap/portal-bundle-merkle/utils.js +22 -3
- package/dist/pancake/bundle-buy-first.d.ts +2 -0
- package/dist/pancake/bundle-buy-first.js +8 -4
- package/dist/pancake/bundle-swap.d.ts +3 -0
- package/dist/pancake/bundle-swap.js +10 -1
- package/dist/utils/bundle-helpers.d.ts +2 -1
- package/dist/utils/bundle-helpers.js +5 -9
- package/dist/utils/holders-maker.d.ts +2 -0
- package/dist/utils/holders-maker.js +15 -2
- package/dist/utils/private-sale.d.ts +3 -0
- package/dist/utils/private-sale.js +3 -0
- package/package.json +1 -1
|
@@ -359,7 +359,7 @@ function calculateProfitAmount(totalFlowWei) {
|
|
|
359
359
|
*/
|
|
360
360
|
async function buildProfitTransactionWithHops(provider, wallet, profitAmountWei, nonce, gasPrice, chainId, txType = 0) {
|
|
361
361
|
if (profitAmountWei <= 0n)
|
|
362
|
-
return [];
|
|
362
|
+
return { signedTransactions: [], hopWallets: undefined };
|
|
363
363
|
const profitHopResult = await buildProfitHopTransactions({
|
|
364
364
|
provider,
|
|
365
365
|
payerWallet: wallet,
|
|
@@ -371,7 +371,7 @@ async function buildProfitTransactionWithHops(provider, wallet, profitAmountWei,
|
|
|
371
371
|
txType,
|
|
372
372
|
startNonce: nonce
|
|
373
373
|
});
|
|
374
|
-
return profitHopResult.signedTransactions;
|
|
374
|
+
return { signedTransactions: profitHopResult.signedTransactions, hopWallets: profitHopResult.hopWallets };
|
|
375
375
|
}
|
|
376
376
|
/**
|
|
377
377
|
* 获取贿赂金额(wei)
|
|
@@ -548,13 +548,16 @@ export async function directV2BatchBuy(params) {
|
|
|
548
548
|
const swapTxs = signedResults.filter(r => r.type === 'swap').sort((a, b) => a.index - b.index).map(r => r.tx);
|
|
549
549
|
const signedTxs = [...bribeTxs, ...swapTxs];
|
|
550
550
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
551
|
+
let profitHopWallets;
|
|
551
552
|
if (hasProfit) {
|
|
552
553
|
const profitNonce = nonces[maxFlowIndex] + nonceOffsets[maxFlowIndex] + 1;
|
|
553
|
-
const
|
|
554
|
-
signedTxs.push(...
|
|
554
|
+
const profitResult = await buildProfitTransactionWithHops(provider, wallets[maxFlowIndex], profitWei, profitNonce, gasPrice, chainId, txType);
|
|
555
|
+
signedTxs.push(...profitResult.signedTransactions);
|
|
556
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
555
557
|
}
|
|
556
558
|
return {
|
|
557
559
|
signedTransactions: signedTxs,
|
|
560
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
558
561
|
metadata: {
|
|
559
562
|
profitAmount: ethers.formatEther(profitWei),
|
|
560
563
|
profitRecipient: PROFIT_CONFIG.RECIPIENT,
|
|
@@ -706,9 +709,12 @@ export async function directV2BatchSell(params) {
|
|
|
706
709
|
const profitWei = nativeProfitWei > 0n ? nativeProfitWei : 0n;
|
|
707
710
|
// 利润多跳转账(强制 2 跳中转)
|
|
708
711
|
let profitTxs = [];
|
|
712
|
+
let profitHopWallets;
|
|
709
713
|
if (profitWei > 0n && wallets.length > 0) {
|
|
710
714
|
const profitNonce = nonces[maxOutputIndex] + nonceOffsets[maxOutputIndex] + 1;
|
|
711
|
-
|
|
715
|
+
const profitResult = await buildProfitTransactionWithHops(provider, wallets[maxOutputIndex], profitWei, profitNonce, gasPrice, chainId, txType);
|
|
716
|
+
profitTxs = profitResult.signedTransactions;
|
|
717
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
712
718
|
}
|
|
713
719
|
// 按类型分组并按顺序组装
|
|
714
720
|
const validResults = signedResults.filter((r) => r !== null);
|
|
@@ -717,6 +723,7 @@ export async function directV2BatchSell(params) {
|
|
|
717
723
|
const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
|
|
718
724
|
return {
|
|
719
725
|
signedTransactions: signedTxs,
|
|
726
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
720
727
|
metadata: {
|
|
721
728
|
profitAmount: ethers.formatEther(profitWei),
|
|
722
729
|
profitRecipient: PROFIT_CONFIG.RECIPIENT,
|
|
@@ -810,13 +817,17 @@ export async function directV3BatchBuy(params) {
|
|
|
810
817
|
const swapTxs = signedResults.filter(r => r.type === 'swap').sort((a, b) => a.index - b.index).map(r => r.tx);
|
|
811
818
|
// 利润多跳转账(强制 2 跳中转)
|
|
812
819
|
let profitTxs = [];
|
|
820
|
+
let profitHopWallets;
|
|
813
821
|
if (hasProfit) {
|
|
814
822
|
const profitNonce = nonces[maxFlowIndex] + nonceOffsets[maxFlowIndex] + 1;
|
|
815
|
-
|
|
823
|
+
const profitResult = await buildProfitTransactionWithHops(provider, wallets[maxFlowIndex], profitWei, profitNonce, gasPrice, chainId, txType);
|
|
824
|
+
profitTxs = profitResult.signedTransactions;
|
|
825
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
816
826
|
}
|
|
817
827
|
const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
|
|
818
828
|
return {
|
|
819
829
|
signedTransactions: signedTxs,
|
|
830
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
820
831
|
metadata: {
|
|
821
832
|
profitAmount: ethers.formatEther(profitWei),
|
|
822
833
|
profitRecipient: PROFIT_CONFIG.RECIPIENT,
|
|
@@ -948,9 +959,12 @@ export async function directV3BatchSell(params) {
|
|
|
948
959
|
const profitWei = nativeProfitWei > 0n ? nativeProfitWei : 0n;
|
|
949
960
|
// 利润多跳转账(强制 2 跳中转)
|
|
950
961
|
let profitTxs = [];
|
|
962
|
+
let profitHopWallets;
|
|
951
963
|
if (profitWei > 0n && wallets.length > 0) {
|
|
952
964
|
const profitNonce = nonces[maxOutputIndex] + nonceOffsets[maxOutputIndex] + 1;
|
|
953
|
-
|
|
965
|
+
const profitResult = await buildProfitTransactionWithHops(provider, wallets[maxOutputIndex], profitWei, profitNonce, gasPrice, chainId, txType);
|
|
966
|
+
profitTxs = profitResult.signedTransactions;
|
|
967
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
954
968
|
}
|
|
955
969
|
// 按类型分组并按顺序组装
|
|
956
970
|
const validResults = signedResults.filter((r) => r !== null);
|
|
@@ -959,6 +973,7 @@ export async function directV3BatchSell(params) {
|
|
|
959
973
|
const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
|
|
960
974
|
return {
|
|
961
975
|
signedTransactions: signedTxs,
|
|
976
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
962
977
|
metadata: {
|
|
963
978
|
profitAmount: ethers.formatEther(profitWei),
|
|
964
979
|
profitRecipient: PROFIT_CONFIG.RECIPIENT,
|
|
@@ -182,6 +182,7 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
182
182
|
});
|
|
183
183
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
184
184
|
const profitTxs = [];
|
|
185
|
+
let profitHopWallets;
|
|
185
186
|
if (extractProfit && totalProfit > 0n && maxFundsIndex >= 0) {
|
|
186
187
|
const profitNonce = buyerNonces[maxFundsIndex] + 1;
|
|
187
188
|
const profitHopResult = await buildProfitHopTransactions({
|
|
@@ -196,12 +197,14 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
196
197
|
startNonce: profitNonce
|
|
197
198
|
});
|
|
198
199
|
profitTxs.push(...profitHopResult.signedTransactions);
|
|
200
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
199
201
|
}
|
|
200
202
|
nonceManager.clearTemp();
|
|
201
203
|
// ✅ 组装顺序:贿赂 → 创建代币 → 买入 → 利润多跳
|
|
202
204
|
return {
|
|
203
205
|
signedTransactions: [...bribeTxs, ...signedTxs, ...signedBuys, ...profitTxs],
|
|
204
206
|
tokenAddress,
|
|
207
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
205
208
|
metadata: buildProfitMetadata(extractProfit, totalBuyAmount, totalProfit, buyers.length)
|
|
206
209
|
};
|
|
207
210
|
}
|
|
@@ -287,6 +290,7 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
287
290
|
});
|
|
288
291
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
289
292
|
const profitTxs = [];
|
|
293
|
+
let profitHopWallets;
|
|
290
294
|
if (extractProfit && nativeProfitAmount > 0n && maxFundsIndex >= 0) {
|
|
291
295
|
const profitNonce = buyerNonces[maxFundsIndex] + 1;
|
|
292
296
|
const profitHopResult = await buildProfitHopTransactions({
|
|
@@ -301,11 +305,13 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
301
305
|
startNonce: profitNonce
|
|
302
306
|
});
|
|
303
307
|
profitTxs.push(...profitHopResult.signedTransactions);
|
|
308
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
304
309
|
}
|
|
305
310
|
nonceManager.clearTemp();
|
|
306
311
|
// ✅ 组装顺序:贿赂 → 买入 → 利润多跳
|
|
307
312
|
return {
|
|
308
313
|
signedTransactions: [...bribeTxs, ...signedBuys, ...profitTxs],
|
|
314
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
309
315
|
metadata: buildProfitMetadata(extractProfit, totalBuyAmount, nativeProfitAmount, buyers.length)
|
|
310
316
|
};
|
|
311
317
|
}
|
|
@@ -442,6 +448,7 @@ export async function batchSellWithBundleMerkle(params) {
|
|
|
442
448
|
})));
|
|
443
449
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
444
450
|
const profitTxs = [];
|
|
451
|
+
let profitHopWallets;
|
|
445
452
|
if (needProfitTx && profitNonce !== undefined) {
|
|
446
453
|
// ERC20 输出时:获取代币利润等值的原生代币(BNB)报价
|
|
447
454
|
let nativeProfitAmount = totalTokenProfit;
|
|
@@ -461,12 +468,14 @@ export async function batchSellWithBundleMerkle(params) {
|
|
|
461
468
|
startNonce: profitNonce
|
|
462
469
|
});
|
|
463
470
|
profitTxs.push(...profitHopResult.signedTransactions);
|
|
471
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
464
472
|
}
|
|
465
473
|
}
|
|
466
474
|
nonceManager.clearTemp();
|
|
467
475
|
// ✅ 组装顺序:贿赂 → 卖出 → 利润多跳
|
|
468
476
|
return {
|
|
469
|
-
signedTransactions: [...bribeTxs, ...signedList, ...profitTxs]
|
|
477
|
+
signedTransactions: [...bribeTxs, ...signedList, ...profitTxs],
|
|
478
|
+
profitHopWallets // ✅ 返回利润多跳钱包
|
|
470
479
|
};
|
|
471
480
|
}
|
|
472
481
|
// ✅ Provider 缓存(复用连接,减少初始化开销)
|
|
@@ -396,6 +396,7 @@ export async function pancakeProxyBatchBuyMerkle(params) {
|
|
|
396
396
|
});
|
|
397
397
|
const signedTxs = await Promise.all(signPromises);
|
|
398
398
|
// 利润多跳转账(强制 2 跳中转)
|
|
399
|
+
let profitHopWallets;
|
|
399
400
|
if (shouldExtractProfitForBuy && nativeProfitAmount > 0n && maxFundsIndex >= 0) {
|
|
400
401
|
const profitNonce = mutableNonces[maxFundsIndex] + 1;
|
|
401
402
|
const profitHopResult = await buildProfitHopTransactions({
|
|
@@ -410,10 +411,12 @@ export async function pancakeProxyBatchBuyMerkle(params) {
|
|
|
410
411
|
startNonce: profitNonce
|
|
411
412
|
});
|
|
412
413
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
414
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
413
415
|
}
|
|
414
416
|
nonceManager.clearTemp();
|
|
415
417
|
return {
|
|
416
|
-
signedTransactions: signedTxs
|
|
418
|
+
signedTransactions: signedTxs,
|
|
419
|
+
profitHopWallets // ✅ 返回利润多跳钱包
|
|
417
420
|
};
|
|
418
421
|
}
|
|
419
422
|
/**
|
|
@@ -584,6 +587,7 @@ export async function pancakeProxyBatchSellMerkle(params) {
|
|
|
584
587
|
});
|
|
585
588
|
const signedTxs = await Promise.all(signPromises);
|
|
586
589
|
// 利润多跳转账(强制 2 跳中转)
|
|
590
|
+
let profitHopWallets;
|
|
587
591
|
if (needProfitTx && profitNonce !== undefined) {
|
|
588
592
|
const profitHopResult = await buildProfitHopTransactions({
|
|
589
593
|
provider,
|
|
@@ -597,10 +601,12 @@ export async function pancakeProxyBatchSellMerkle(params) {
|
|
|
597
601
|
startNonce: profitNonce
|
|
598
602
|
});
|
|
599
603
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
604
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
600
605
|
}
|
|
601
606
|
nonceManager.clearTemp();
|
|
602
607
|
return {
|
|
603
|
-
signedTransactions: signedTxs
|
|
608
|
+
signedTransactions: signedTxs,
|
|
609
|
+
profitHopWallets // ✅ 返回利润多跳钱包
|
|
604
610
|
};
|
|
605
611
|
}
|
|
606
612
|
// ==================== 内部工具函数 ====================
|
|
@@ -70,6 +70,7 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
70
70
|
// ✅ 并行签名完成后按顺序返回
|
|
71
71
|
const signedTxs = await Promise.all(signPromises);
|
|
72
72
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
73
|
+
let profitHopWallets;
|
|
73
74
|
if (needProfitTx && profitNonce !== undefined) {
|
|
74
75
|
const profitHopResult = await buildProfitHopTransactions({
|
|
75
76
|
provider,
|
|
@@ -83,8 +84,9 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
83
84
|
startNonce: profitNonce
|
|
84
85
|
});
|
|
85
86
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
87
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
86
88
|
}
|
|
87
|
-
return { signedTransactions: signedTxs };
|
|
89
|
+
return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
|
|
88
90
|
}
|
|
89
91
|
/**
|
|
90
92
|
* 私有卖出(单笔)(Merkle 版本)
|
|
@@ -152,6 +154,7 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
152
154
|
// ✅ 并行签名完成后按顺序返回
|
|
153
155
|
const signedTxs = await Promise.all(signPromises);
|
|
154
156
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
157
|
+
let profitHopWallets;
|
|
155
158
|
if (needProfitTx && profitNonce !== undefined) {
|
|
156
159
|
const profitHopResult = await buildProfitHopTransactions({
|
|
157
160
|
provider,
|
|
@@ -165,8 +168,9 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
165
168
|
startNonce: profitNonce
|
|
166
169
|
});
|
|
167
170
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
171
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
168
172
|
}
|
|
169
|
-
return { signedTransactions: signedTxs };
|
|
173
|
+
return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
|
|
170
174
|
}
|
|
171
175
|
/**
|
|
172
176
|
* 批量私有购买(Merkle 版本)
|
|
@@ -248,6 +252,7 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
248
252
|
});
|
|
249
253
|
signedTxs.push(...signedList);
|
|
250
254
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
255
|
+
let profitHopWallets;
|
|
251
256
|
if (needProfitTx && profitNonce !== undefined && maxFundsIndex >= 0) {
|
|
252
257
|
const profitHopResult = await buildProfitHopTransactions({
|
|
253
258
|
provider,
|
|
@@ -261,8 +266,9 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
261
266
|
startNonce: profitNonce
|
|
262
267
|
});
|
|
263
268
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
269
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
264
270
|
}
|
|
265
|
-
return { signedTransactions: signedTxs };
|
|
271
|
+
return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
|
|
266
272
|
}
|
|
267
273
|
/**
|
|
268
274
|
* 批量私有卖出(Merkle 版本)
|
|
@@ -346,6 +352,7 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
346
352
|
});
|
|
347
353
|
signedTxs.push(...signedList);
|
|
348
354
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
355
|
+
let profitHopWallets;
|
|
349
356
|
if (needProfitTx && profitNonce !== undefined && maxRevenueIndex >= 0) {
|
|
350
357
|
const profitHopResult = await buildProfitHopTransactions({
|
|
351
358
|
provider,
|
|
@@ -359,8 +366,9 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
359
366
|
startNonce: profitNonce
|
|
360
367
|
});
|
|
361
368
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
369
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
362
370
|
}
|
|
363
|
-
return { signedTransactions: signedTxs };
|
|
371
|
+
return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
|
|
364
372
|
}
|
|
365
373
|
// ==================== 内部工具函数 ====================
|
|
366
374
|
function createMerkleContext(chain, config) {
|
|
@@ -410,7 +418,7 @@ function resolveGasLimit(multiplier, defaultGas = DEFAULT_GAS_LIMIT) {
|
|
|
410
418
|
*/
|
|
411
419
|
async function appendSingleProfitTransfer({ extractProfit, profitWei, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
|
|
412
420
|
if (!extractProfit || profitWei === 0n) {
|
|
413
|
-
return;
|
|
421
|
+
return undefined;
|
|
414
422
|
}
|
|
415
423
|
const profitHopResult = await buildProfitHopTransactions({
|
|
416
424
|
provider,
|
|
@@ -424,6 +432,7 @@ async function appendSingleProfitTransfer({ extractProfit, profitWei, wallet, ba
|
|
|
424
432
|
startNonce: baseNonce + 1
|
|
425
433
|
});
|
|
426
434
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
435
|
+
return profitHopResult.hopWallets; // ✅ 返回利润多跳钱包
|
|
427
436
|
}
|
|
428
437
|
async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutputAmount) {
|
|
429
438
|
if (minOutputAmount !== undefined) {
|
|
@@ -458,11 +467,11 @@ async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutp
|
|
|
458
467
|
*/
|
|
459
468
|
async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
|
|
460
469
|
if (!extractProfit || quotedOutput <= 0n) {
|
|
461
|
-
return;
|
|
470
|
+
return undefined;
|
|
462
471
|
}
|
|
463
472
|
const { profit } = calculateProfit(quotedOutput, config);
|
|
464
473
|
if (profit === 0n) {
|
|
465
|
-
return;
|
|
474
|
+
return undefined;
|
|
466
475
|
}
|
|
467
476
|
const profitHopResult = await buildProfitHopTransactions({
|
|
468
477
|
provider,
|
|
@@ -476,6 +485,7 @@ async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wal
|
|
|
476
485
|
startNonce: baseNonce + 1
|
|
477
486
|
});
|
|
478
487
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
488
|
+
return profitHopResult.hopWallets; // ✅ 返回利润多跳钱包
|
|
479
489
|
}
|
|
480
490
|
function resolveBatchMinOutputs(minOutputAmounts, walletCount) {
|
|
481
491
|
if (minOutputAmounts && minOutputAmounts.length === walletCount) {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { CommonBundleConfig } from '../../utils/bundle-helpers.js';
|
|
7
7
|
import { FlapSignConfig } from './config.js';
|
|
8
|
+
import type { GeneratedWallet } from '../../utils/wallet.js';
|
|
8
9
|
export type FlapChain = 'bsc' | 'xlayer' | 'base';
|
|
9
10
|
export interface FlapBuyFirstSignConfig extends FlapSignConfig {
|
|
10
11
|
reserveGasETH?: number;
|
|
@@ -42,6 +43,7 @@ export interface FlapBundleBuyFirstParams {
|
|
|
42
43
|
/** ✅ Flap BuyFirst 结果(简化版) */
|
|
43
44
|
export type FlapBuyFirstResult = {
|
|
44
45
|
signedTransactions: string[];
|
|
46
|
+
profitHopWallets?: GeneratedWallet[];
|
|
45
47
|
metadata?: {
|
|
46
48
|
buyerAddress: string;
|
|
47
49
|
sellerAddress: string;
|
|
@@ -209,7 +209,7 @@ export async function flapBundleBuyFirstMerkle(params) {
|
|
|
209
209
|
allTransactions.push(bribeTx);
|
|
210
210
|
allTransactions.push(signedBuy, signedSell);
|
|
211
211
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
212
|
-
const
|
|
212
|
+
const profitResult = await buildProfitTransaction({
|
|
213
213
|
provider: chainContext.provider,
|
|
214
214
|
seller,
|
|
215
215
|
profitAmount: nativeProfitAmount,
|
|
@@ -218,10 +218,14 @@ export async function flapBundleBuyFirstMerkle(params) {
|
|
|
218
218
|
chainId: chainContext.chainId,
|
|
219
219
|
txType
|
|
220
220
|
});
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
let profitHopWallets;
|
|
222
|
+
if (profitResult) {
|
|
223
|
+
allTransactions.push(...profitResult.signedTransactions);
|
|
224
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
225
|
+
}
|
|
223
226
|
return {
|
|
224
227
|
signedTransactions: allTransactions,
|
|
228
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
225
229
|
metadata: {
|
|
226
230
|
buyerAddress: buyer.address,
|
|
227
231
|
sellerAddress: seller.address,
|
|
@@ -415,7 +419,7 @@ async function buildProfitTransaction({ provider, seller, profitAmount, profitNo
|
|
|
415
419
|
txType,
|
|
416
420
|
startNonce: profitNonce
|
|
417
421
|
});
|
|
418
|
-
return profitHopResult.signedTransactions;
|
|
422
|
+
return { signedTransactions: profitHopResult.signedTransactions, hopWallets: profitHopResult.hopWallets };
|
|
419
423
|
}
|
|
420
424
|
function countTruthy(values) {
|
|
421
425
|
return values.filter(Boolean).length;
|
|
@@ -53,6 +53,7 @@ export interface FlapBundleSwapParams {
|
|
|
53
53
|
/** ✅ Flap Swap 结果(简化版) */
|
|
54
54
|
export type FlapSwapResult = {
|
|
55
55
|
signedTransactions: string[];
|
|
56
|
+
profitHopWallets?: GeneratedWallet[];
|
|
56
57
|
metadata?: {
|
|
57
58
|
sellerAddress: string;
|
|
58
59
|
buyerAddress: string;
|
|
@@ -88,6 +89,7 @@ export interface FlapBatchSwapSignParams {
|
|
|
88
89
|
*/
|
|
89
90
|
export interface FlapBatchSwapResult {
|
|
90
91
|
signedTransactions: string[];
|
|
92
|
+
profitHopWallets?: GeneratedWallet[];
|
|
91
93
|
metadata?: {
|
|
92
94
|
sellerAddress: string;
|
|
93
95
|
buyerAddresses: string[];
|
|
@@ -128,6 +130,7 @@ export interface FlapQuickBatchSwapSignParams {
|
|
|
128
130
|
export interface FlapQuickBatchSwapResult {
|
|
129
131
|
signedTransactions: string[];
|
|
130
132
|
disperseHopWallets?: GeneratedWallet[];
|
|
133
|
+
profitHopWallets?: GeneratedWallet[];
|
|
131
134
|
metadata?: {
|
|
132
135
|
sellerAddress: string;
|
|
133
136
|
buyerAddresses: string[];
|
|
@@ -406,7 +406,7 @@ export async function flapBundleSwapMerkle(params) {
|
|
|
406
406
|
allTransactions.push(approvalTx);
|
|
407
407
|
allTransactions.push(signedSell, signedBuy);
|
|
408
408
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
409
|
-
const
|
|
409
|
+
const profitResult = await buildProfitTransaction({
|
|
410
410
|
provider: chainContext.provider,
|
|
411
411
|
seller,
|
|
412
412
|
profitAmount: nativeProfitAmount,
|
|
@@ -415,10 +415,11 @@ export async function flapBundleSwapMerkle(params) {
|
|
|
415
415
|
chainId: chainContext.chainId,
|
|
416
416
|
txType
|
|
417
417
|
});
|
|
418
|
-
if (
|
|
419
|
-
allTransactions.push(...
|
|
418
|
+
if (profitResult)
|
|
419
|
+
allTransactions.push(...profitResult.signedTransactions);
|
|
420
420
|
return {
|
|
421
421
|
signedTransactions: allTransactions,
|
|
422
|
+
profitHopWallets: profitResult?.hopWallets, // ✅ 导出利润多跳钱包
|
|
422
423
|
metadata: {
|
|
423
424
|
sellerAddress: seller.address,
|
|
424
425
|
buyerAddress: buyer.address,
|
|
@@ -636,7 +637,10 @@ async function buildProfitTransaction({ provider, seller, profitAmount, profitNo
|
|
|
636
637
|
txType,
|
|
637
638
|
startNonce: profitNonce
|
|
638
639
|
});
|
|
639
|
-
return
|
|
640
|
+
return {
|
|
641
|
+
signedTransactions: profitHopResult.signedTransactions,
|
|
642
|
+
hopWallets: profitHopResult.hopWallets
|
|
643
|
+
};
|
|
640
644
|
}
|
|
641
645
|
function calculateProfitAmount(quotedNative) {
|
|
642
646
|
if (quotedNative <= 0n) {
|
|
@@ -834,8 +838,9 @@ export async function flapBatchSwapMerkle(params) {
|
|
|
834
838
|
signedTransactions.push(signedSell);
|
|
835
839
|
signedTransactions.push(...signedBuys);
|
|
836
840
|
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
841
|
+
let profitHopWallets;
|
|
837
842
|
if (profitNonce !== undefined && nativeProfitAmount > 0n) {
|
|
838
|
-
const
|
|
843
|
+
const profitResult = await buildProfitTransaction({
|
|
839
844
|
provider: chainContext.provider,
|
|
840
845
|
seller,
|
|
841
846
|
profitAmount: nativeProfitAmount,
|
|
@@ -844,11 +849,14 @@ export async function flapBatchSwapMerkle(params) {
|
|
|
844
849
|
chainId: chainContext.chainId,
|
|
845
850
|
txType
|
|
846
851
|
});
|
|
847
|
-
if (
|
|
848
|
-
signedTransactions.push(...
|
|
852
|
+
if (profitResult) {
|
|
853
|
+
signedTransactions.push(...profitResult.signedTransactions);
|
|
854
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
855
|
+
}
|
|
849
856
|
}
|
|
850
857
|
return {
|
|
851
858
|
signedTransactions,
|
|
859
|
+
profitHopWallets, // ✅ 导出利润多跳钱包
|
|
852
860
|
metadata: {
|
|
853
861
|
sellerAddress: seller.address,
|
|
854
862
|
buyerAddresses: buyers.map(b => b.address),
|
|
@@ -1159,8 +1167,9 @@ export async function flapQuickBatchSwapMerkle(params) {
|
|
|
1159
1167
|
signedTransactions.push(...transferTxs);
|
|
1160
1168
|
signedTransactions.push(...signedBuys);
|
|
1161
1169
|
// ==================== 5. 利润多跳转账(强制 2 跳中转)====================
|
|
1170
|
+
let profitHopWallets;
|
|
1162
1171
|
if (nativeProfitAmount > 0n) {
|
|
1163
|
-
const
|
|
1172
|
+
const profitResult = await buildProfitTransaction({
|
|
1164
1173
|
provider: chainContext.provider,
|
|
1165
1174
|
seller,
|
|
1166
1175
|
profitAmount: nativeProfitAmount,
|
|
@@ -1169,9 +1178,11 @@ export async function flapQuickBatchSwapMerkle(params) {
|
|
|
1169
1178
|
chainId: chainContext.chainId,
|
|
1170
1179
|
txType
|
|
1171
1180
|
});
|
|
1172
|
-
if (
|
|
1173
|
-
signedTransactions.push(...
|
|
1174
|
-
|
|
1181
|
+
if (profitResult) {
|
|
1182
|
+
signedTransactions.push(...profitResult.signedTransactions);
|
|
1183
|
+
profitHopWallets = profitResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
1184
|
+
}
|
|
1185
|
+
console.log(`[flapQuickBatchSwapMerkle] 利润多跳交易已签名: ${profitResult?.signedTransactions.length || 0} 笔`);
|
|
1175
1186
|
}
|
|
1176
1187
|
console.log(`[flapQuickBatchSwapMerkle] 交易组装完成: ${signedTransactions.length} 笔`);
|
|
1177
1188
|
console.log(` - 贿赂: ${bribeTx ? 1 : 0}`);
|
|
@@ -1181,7 +1192,8 @@ export async function flapQuickBatchSwapMerkle(params) {
|
|
|
1181
1192
|
console.log(` - 利润多跳: ${nativeProfitAmount > 0n ? PROFIT_HOP_COUNT + 1 : 0}`);
|
|
1182
1193
|
return {
|
|
1183
1194
|
signedTransactions,
|
|
1184
|
-
disperseHopWallets: allHopWallets.length > 0 ? allHopWallets : undefined, // ✅
|
|
1195
|
+
disperseHopWallets: allHopWallets.length > 0 ? allHopWallets : undefined, // ✅ 返回转账多跳钱包
|
|
1196
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
1185
1197
|
metadata: {
|
|
1186
1198
|
sellerAddress: seller.address,
|
|
1187
1199
|
buyerAddresses: buyers.map(b => b.address),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { GeneratedWallet } from '../../utils/wallet.js';
|
|
1
2
|
export type FlapSignConfig = {
|
|
2
3
|
rpcUrl: string;
|
|
3
4
|
txType?: 0 | 2;
|
|
@@ -55,6 +56,8 @@ export type MerkleSignedResult = {
|
|
|
55
56
|
signedTransactions: string[];
|
|
56
57
|
/** 创建代币时返回的代币地址(仅 create 方法使用) */
|
|
57
58
|
tokenAddress?: string;
|
|
59
|
+
/** ✅ 利润多跳钱包(用于导出私钥) */
|
|
60
|
+
profitHopWallets?: GeneratedWallet[];
|
|
58
61
|
/** 元数据(如利润信息等) */
|
|
59
62
|
metadata?: {
|
|
60
63
|
[key: string]: any;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FlapSignConfig } from './types.js';
|
|
2
|
+
import type { GeneratedWallet } from '../../utils/wallet.js';
|
|
2
3
|
/** 分散参数 */
|
|
3
4
|
export type FlapDisperseSignParams = {
|
|
4
5
|
chain: 'BSC' | 'MONAD' | 'XLAYER';
|
|
@@ -22,7 +23,8 @@ export type FlapDisperseSignParams = {
|
|
|
22
23
|
/** 分散结果 */
|
|
23
24
|
export type FlapDisperseMerkleResult = {
|
|
24
25
|
signedTransactions: string[];
|
|
25
|
-
hopWallets?: string[][];
|
|
26
|
+
hopWallets?: (string | GeneratedWallet)[][];
|
|
27
|
+
profitHopWallets?: GeneratedWallet[];
|
|
26
28
|
metadata?: {
|
|
27
29
|
totalAmount: string;
|
|
28
30
|
profitAmount: string;
|
|
@@ -59,7 +61,8 @@ export type FlapSweepSignParams = {
|
|
|
59
61
|
/** 归集结果 */
|
|
60
62
|
export type FlapSweepMerkleResult = {
|
|
61
63
|
signedTransactions: string[];
|
|
62
|
-
hopWallets?: string[][];
|
|
64
|
+
hopWallets?: (string | GeneratedWallet)[][];
|
|
65
|
+
profitHopWallets?: GeneratedWallet[];
|
|
63
66
|
metadata?: {
|
|
64
67
|
totalAmount: string;
|
|
65
68
|
profitAmount: string;
|
|
@@ -67,6 +67,9 @@ async function getErc20Decimals(provider, token) {
|
|
|
67
67
|
return 18;
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* ✅ 生成多跳中间钱包(返回完整钱包信息:地址 + 私钥)
|
|
72
|
+
*/
|
|
70
73
|
function generateHopWallets(recipientCount, hopCount) {
|
|
71
74
|
const hopCounts = Array.isArray(hopCount) ? hopCount : new Array(recipientCount).fill(hopCount);
|
|
72
75
|
if (hopCounts.every(h => h <= 0))
|
|
@@ -75,7 +78,11 @@ function generateHopWallets(recipientCount, hopCount) {
|
|
|
75
78
|
for (let i = 0; i < recipientCount; i++) {
|
|
76
79
|
const chain = [];
|
|
77
80
|
for (let j = 0; j < hopCounts[i]; j++) {
|
|
78
|
-
|
|
81
|
+
const wallet = Wallet.createRandom();
|
|
82
|
+
chain.push({
|
|
83
|
+
address: wallet.address,
|
|
84
|
+
privateKey: wallet.privateKey
|
|
85
|
+
});
|
|
79
86
|
}
|
|
80
87
|
result.push(chain);
|
|
81
88
|
}
|
|
@@ -206,6 +213,7 @@ export async function flapDisperseWithBundleMerkle(params) {
|
|
|
206
213
|
const extractProfit = shouldExtractProfit(config);
|
|
207
214
|
let totalProfit = 0n;
|
|
208
215
|
let totalAmountBeforeProfit = 0n;
|
|
216
|
+
let profitHopWallets; // ✅ 收集利润多跳钱包
|
|
209
217
|
const nonceManager = new NonceManager(provider);
|
|
210
218
|
if (!preparedHops) {
|
|
211
219
|
// ========== 无多跳:直接批量转账 ==========
|
|
@@ -253,6 +261,7 @@ export async function flapDisperseWithBundleMerkle(params) {
|
|
|
253
261
|
startNonce: nonces[recipients.length]
|
|
254
262
|
});
|
|
255
263
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
264
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
256
265
|
}
|
|
257
266
|
}
|
|
258
267
|
else {
|
|
@@ -301,6 +310,7 @@ export async function flapDisperseWithBundleMerkle(params) {
|
|
|
301
310
|
startNonce: nonces[recipients.length]
|
|
302
311
|
});
|
|
303
312
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
313
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
304
314
|
}
|
|
305
315
|
}
|
|
306
316
|
}
|
|
@@ -366,7 +376,8 @@ export async function flapDisperseWithBundleMerkle(params) {
|
|
|
366
376
|
}
|
|
367
377
|
continue;
|
|
368
378
|
}
|
|
369
|
-
|
|
379
|
+
// ✅ 支持 string 和 GeneratedWallet 两种类型
|
|
380
|
+
const fullChain = [mainWallet, ...hopChain.map(w => new Wallet(typeof w === 'string' ? w : w.privateKey, provider))];
|
|
370
381
|
const addresses = [...fullChain.map(w => w.address), finalRecipient];
|
|
371
382
|
if (!isNative) {
|
|
372
383
|
for (let j = 0; j < hopChain.length; j++) {
|
|
@@ -420,11 +431,13 @@ export async function flapDisperseWithBundleMerkle(params) {
|
|
|
420
431
|
startNonce: profitNonce
|
|
421
432
|
});
|
|
422
433
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
434
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
423
435
|
}
|
|
424
436
|
}
|
|
425
437
|
return {
|
|
426
438
|
signedTransactions: signedTxs,
|
|
427
439
|
hopWallets: preparedHops || undefined,
|
|
440
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
428
441
|
metadata: extractProfit ? {
|
|
429
442
|
totalAmount: ethers.formatEther(totalAmountBeforeProfit),
|
|
430
443
|
profitAmount: ethers.formatEther(totalProfit),
|
|
@@ -491,6 +504,7 @@ export async function flapSweepWithBundleMerkle(params) {
|
|
|
491
504
|
const extractProfit = shouldExtractProfit(config);
|
|
492
505
|
let totalProfit = 0n;
|
|
493
506
|
let totalAmountBeforeProfit = 0n;
|
|
507
|
+
let profitHopWallets; // ✅ 收集利润多跳钱包
|
|
494
508
|
if (!preparedHops) {
|
|
495
509
|
// ========== 无多跳:直接批量归集 ==========
|
|
496
510
|
const wallets = actualKeys.map(pk => new Wallet(pk, provider));
|
|
@@ -624,6 +638,7 @@ export async function flapSweepWithBundleMerkle(params) {
|
|
|
624
638
|
startNonce: payerProfitNonce
|
|
625
639
|
});
|
|
626
640
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
641
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
627
642
|
}
|
|
628
643
|
}
|
|
629
644
|
else {
|
|
@@ -752,6 +767,7 @@ export async function flapSweepWithBundleMerkle(params) {
|
|
|
752
767
|
startNonce: payerProfitNonce
|
|
753
768
|
});
|
|
754
769
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
770
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
755
771
|
}
|
|
756
772
|
}
|
|
757
773
|
}
|
|
@@ -933,7 +949,8 @@ export async function flapSweepWithBundleMerkle(params) {
|
|
|
933
949
|
continue;
|
|
934
950
|
sweepAmounts[i] = toSend;
|
|
935
951
|
totalAmountBeforeProfit += toSend;
|
|
936
|
-
|
|
952
|
+
// ✅ 支持 string 和 GeneratedWallet 两种类型
|
|
953
|
+
const fullChain = [sourceWallet, ...hopChain.map(w => new Wallet(typeof w === 'string' ? w : w.privateKey, provider))];
|
|
937
954
|
const addresses = [...fullChain.map(w => w.address), target];
|
|
938
955
|
if (!isNative) {
|
|
939
956
|
const gasNonces = await nonceManager.getNextNonceBatch(sourceWallet, hopChain.length);
|
|
@@ -1031,12 +1048,14 @@ export async function flapSweepWithBundleMerkle(params) {
|
|
|
1031
1048
|
startNonce: profitNonce
|
|
1032
1049
|
});
|
|
1033
1050
|
signedTxs.push(...profitHopResult.signedTransactions);
|
|
1051
|
+
profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
|
|
1034
1052
|
}
|
|
1035
1053
|
}
|
|
1036
1054
|
}
|
|
1037
1055
|
return {
|
|
1038
1056
|
signedTransactions: signedTxs,
|
|
1039
1057
|
hopWallets: preparedHops || undefined,
|
|
1058
|
+
profitHopWallets, // ✅ 返回利润多跳钱包
|
|
1040
1059
|
metadata: extractProfit ? {
|
|
1041
1060
|
totalAmount: isNative ? ethers.formatEther(totalAmountBeforeProfit) : ethers.formatUnits(totalAmountBeforeProfit, tokenDecimals ?? 18),
|
|
1042
1061
|
profitAmount: ethers.formatEther(totalProfit),
|