four-flap-meme-sdk 1.4.55 → 1.4.57

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,3 +1,229 @@
1
+ // ==================== 多跳转账常量 ====================
2
+ const NATIVE_TRANSFER_GAS_LIMIT = 21055n;
3
+ const ERC20_TRANSFER_GAS_LIMIT_HOP = 65000n;
4
+ /**
5
+ * 生成分发多跳路径
6
+ */
7
+ function generateDisperseHopPaths(targetAddresses, hopCount, provider) {
8
+ if (hopCount <= 0) {
9
+ return targetAddresses.map(addr => ({
10
+ targetAddress: addr,
11
+ hopWallets: [],
12
+ hopWalletsInfo: []
13
+ }));
14
+ }
15
+ return targetAddresses.map(targetAddress => {
16
+ const hopWalletsInfo = generateWallets(hopCount);
17
+ const hopWallets = hopWalletsInfo.map(w => new Wallet(w.privateKey, provider));
18
+ return { targetAddress, hopWallets, hopWalletsInfo };
19
+ });
20
+ }
21
+ /**
22
+ * 构建原生代币多跳转账链
23
+ */
24
+ async function buildNativeHopChain(payer, path, finalAmount, gasPrice, chainId, txType, payerNonce) {
25
+ const signedTxs = [];
26
+ const hopCount = path.hopWallets.length;
27
+ if (hopCount === 0) {
28
+ const tx = {
29
+ to: path.targetAddress,
30
+ value: finalAmount,
31
+ nonce: payerNonce,
32
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
33
+ chainId,
34
+ type: txType
35
+ };
36
+ if (txType === 2) {
37
+ tx.maxFeePerGas = gasPrice;
38
+ tx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
39
+ }
40
+ else {
41
+ tx.gasPrice = gasPrice;
42
+ }
43
+ signedTxs.push(await payer.signTransaction(tx));
44
+ return signedTxs;
45
+ }
46
+ const hopGasCost = NATIVE_TRANSFER_GAS_LIMIT * gasPrice;
47
+ // 计算每跳需要的金额
48
+ const amountsPerHop = [];
49
+ for (let i = 0; i < hopCount; i++) {
50
+ const remainingHops = hopCount - i;
51
+ amountsPerHop.push(finalAmount + hopGasCost * BigInt(remainingHops));
52
+ }
53
+ // payer → hop1
54
+ const firstTx = {
55
+ to: path.hopWallets[0].address,
56
+ value: amountsPerHop[0],
57
+ nonce: payerNonce,
58
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
59
+ chainId,
60
+ type: txType
61
+ };
62
+ if (txType === 2) {
63
+ firstTx.maxFeePerGas = gasPrice;
64
+ firstTx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
65
+ }
66
+ else {
67
+ firstTx.gasPrice = gasPrice;
68
+ }
69
+ signedTxs.push(await payer.signTransaction(firstTx));
70
+ // hop1 → hop2 → ... → target
71
+ for (let i = 0; i < hopCount; i++) {
72
+ const fromWallet = path.hopWallets[i];
73
+ const toAddress = i === hopCount - 1 ? path.targetAddress : path.hopWallets[i + 1].address;
74
+ const amount = i === hopCount - 1 ? finalAmount : amountsPerHop[i + 1];
75
+ const tx = {
76
+ to: toAddress,
77
+ value: amount,
78
+ nonce: 0,
79
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
80
+ chainId,
81
+ type: txType
82
+ };
83
+ if (txType === 2) {
84
+ tx.maxFeePerGas = gasPrice;
85
+ tx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
86
+ }
87
+ else {
88
+ tx.gasPrice = gasPrice;
89
+ }
90
+ signedTxs.push(await fromWallet.signTransaction(tx));
91
+ }
92
+ return signedTxs;
93
+ }
94
+ /**
95
+ * 构建 ERC20 多跳转账链(需要配合 BNB 多跳使用)
96
+ */
97
+ async function buildERC20HopChain(payer, path, erc20Address, erc20Amount, gasPrice, chainId, txType, payerNonce) {
98
+ const signedTxs = [];
99
+ const hopCount = path.hopWallets.length;
100
+ const erc20Interface = new ethers.Interface(ERC20_ABI);
101
+ if (hopCount === 0) {
102
+ const data = erc20Interface.encodeFunctionData('transfer', [path.targetAddress, erc20Amount]);
103
+ const tx = {
104
+ to: erc20Address,
105
+ data,
106
+ value: 0n,
107
+ nonce: payerNonce,
108
+ gasLimit: ERC20_TRANSFER_GAS_LIMIT_HOP,
109
+ chainId,
110
+ type: txType
111
+ };
112
+ if (txType === 2) {
113
+ tx.maxFeePerGas = gasPrice;
114
+ tx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
115
+ }
116
+ else {
117
+ tx.gasPrice = gasPrice;
118
+ }
119
+ signedTxs.push(await payer.signTransaction(tx));
120
+ return signedTxs;
121
+ }
122
+ // payer → hop1
123
+ const firstData = erc20Interface.encodeFunctionData('transfer', [path.hopWallets[0].address, erc20Amount]);
124
+ const firstTx = {
125
+ to: erc20Address,
126
+ data: firstData,
127
+ value: 0n,
128
+ nonce: payerNonce,
129
+ gasLimit: ERC20_TRANSFER_GAS_LIMIT_HOP,
130
+ chainId,
131
+ type: txType
132
+ };
133
+ if (txType === 2) {
134
+ firstTx.maxFeePerGas = gasPrice;
135
+ firstTx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
136
+ }
137
+ else {
138
+ firstTx.gasPrice = gasPrice;
139
+ }
140
+ signedTxs.push(await payer.signTransaction(firstTx));
141
+ // hop1 → hop2 → ... → target (nonce=1,nonce=0 用于 BNB 转发)
142
+ for (let i = 0; i < hopCount; i++) {
143
+ const fromWallet = path.hopWallets[i];
144
+ const toAddress = i === hopCount - 1 ? path.targetAddress : path.hopWallets[i + 1].address;
145
+ const data = erc20Interface.encodeFunctionData('transfer', [toAddress, erc20Amount]);
146
+ const tx = {
147
+ to: erc20Address,
148
+ data,
149
+ value: 0n,
150
+ nonce: 1, // nonce=0 已用于 BNB 转发
151
+ gasLimit: ERC20_TRANSFER_GAS_LIMIT_HOP,
152
+ chainId,
153
+ type: txType
154
+ };
155
+ if (txType === 2) {
156
+ tx.maxFeePerGas = gasPrice;
157
+ tx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
158
+ }
159
+ else {
160
+ tx.gasPrice = gasPrice;
161
+ }
162
+ signedTxs.push(await fromWallet.signTransaction(tx));
163
+ }
164
+ return signedTxs;
165
+ }
166
+ /**
167
+ * 构建 BNB 多跳转账链(为 ERC20 中间钱包预留 gas)
168
+ */
169
+ async function buildBNBHopChainForERC20(payer, path, finalGasAmount, gasPrice, chainId, txType, payerNonce) {
170
+ const signedTxs = [];
171
+ const hopCount = path.hopWallets.length;
172
+ if (hopCount === 0) {
173
+ // 无多跳时不需要转 gas
174
+ return signedTxs;
175
+ }
176
+ const hopGasCost = NATIVE_TRANSFER_GAS_LIMIT * gasPrice;
177
+ const erc20GasCost = ERC20_TRANSFER_GAS_LIMIT_HOP * gasPrice;
178
+ // 每个中间钱包需要: BNB 转发 gas + ERC20 转发 gas
179
+ const gasPerHop = hopGasCost + erc20GasCost * 2n; // 2倍安全系数
180
+ // 计算每跳需要的金额
181
+ const amountsPerHop = [];
182
+ for (let i = 0; i < hopCount; i++) {
183
+ const remainingHops = hopCount - i;
184
+ amountsPerHop.push(finalGasAmount + gasPerHop * BigInt(remainingHops));
185
+ }
186
+ // payer → hop1
187
+ const firstTx = {
188
+ to: path.hopWallets[0].address,
189
+ value: amountsPerHop[0],
190
+ nonce: payerNonce,
191
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
192
+ chainId,
193
+ type: txType
194
+ };
195
+ if (txType === 2) {
196
+ firstTx.maxFeePerGas = gasPrice;
197
+ firstTx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
198
+ }
199
+ else {
200
+ firstTx.gasPrice = gasPrice;
201
+ }
202
+ signedTxs.push(await payer.signTransaction(firstTx));
203
+ // hop1 → hop2 → ... → target (nonce=0)
204
+ for (let i = 0; i < hopCount; i++) {
205
+ const fromWallet = path.hopWallets[i];
206
+ const toAddress = i === hopCount - 1 ? path.targetAddress : path.hopWallets[i + 1].address;
207
+ const amount = i === hopCount - 1 ? finalGasAmount : amountsPerHop[i + 1];
208
+ const tx = {
209
+ to: toAddress,
210
+ value: amount,
211
+ nonce: 0,
212
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
213
+ chainId,
214
+ type: txType
215
+ };
216
+ if (txType === 2) {
217
+ tx.maxFeePerGas = gasPrice;
218
+ tx.maxPriorityFeePerGas = gasPrice / 10n || 1n;
219
+ }
220
+ else {
221
+ tx.gasPrice = gasPrice;
222
+ }
223
+ signedTxs.push(await fromWallet.signTransaction(tx));
224
+ }
225
+ return signedTxs;
226
+ }
1
227
  // ==================== 工具函数 ====================
2
228
  function createPancakeContext(config) {
3
229
  const chainId = config.chainId ?? 56;
@@ -302,7 +528,8 @@ import { calculateSellAmount } from '../utils/swap-helpers.js';
302
528
  import { NonceManager, getDeadline, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../utils/bundle-helpers.js';
303
529
  import { ADDRESSES, PROFIT_CONFIG, BLOCKRAZOR_BUILDER_EOA } from '../utils/constants.js';
304
530
  import { quoteV2, quoteV3 } from '../utils/quote-helpers.js';
305
- import { V2_ROUTER_ABI, V3_ROUTER02_ABI, ERC20_BALANCE_ABI } from '../abis/common.js';
531
+ import { V2_ROUTER_ABI, V3_ROUTER02_ABI, ERC20_BALANCE_ABI, ERC20_ABI } from '../abis/common.js';
532
+ import { generateWallets } from '../utils/wallet.js';
306
533
  /**
307
534
  * 获取 Gas Limit
308
535
  */
@@ -788,32 +1015,49 @@ export async function pancakeBatchSwapMerkle(params) {
788
1015
  /**
789
1016
  * PancakeSwap 快捷批量换手(资金自动流转)
790
1017
  *
791
- * 流程:[贿赂] → [卖出] → [转账1, 转账2, ...] → [买入1, 买入2, ...] → [利润]
1018
+ * 流程:[贿赂] → [卖出] → [转账多跳...] → [买入1, 买入2, ...] → [利润]
792
1019
  *
793
1020
  * 特点:
794
1021
  * - 子钱包不需要预先有余额
795
1022
  * - 资金来自主钱包卖出代币所得
796
1023
  * - 提升资金利用率
797
1024
  * - 支持 BNB 和 ERC20(如 USDT)两种模式
1025
+ * - ✅ 支持转账多跳,隐藏资金流向
798
1026
  *
799
- * 限制:最多 23 个买方(转账 + 买入 = 46 笔,加上贿赂/卖出/利润 = 50 笔限制)
1027
+ * 限制:根据多跳数动态计算最大买方数量
800
1028
  */
801
1029
  export async function pancakeQuickBatchSwapMerkle(params) {
802
- const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKeys, buyerRatios, buyerAmounts, tokenAddress, routeParams, config, quoteToken, quoteTokenDecimals = 18, startNonces // ✅ 可选:前端预获取的 nonces
1030
+ const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKeys, buyerRatios, buyerAmounts, tokenAddress, routeParams, config, quoteToken, quoteTokenDecimals = 18, disperseHopCount = 0, // ✅ 转账多跳数(默认0=直接转账)
1031
+ startNonces // ✅ 可选:前端预获取的 nonces
803
1032
  } = params;
804
1033
  // ✅ 判断是否使用原生代币
805
1034
  const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
806
1035
  const WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'.toLowerCase();
807
- // ✅ 校验买方数量(子钱包已预留 BNB,不需要主钱包转 Gas)
808
- // BNB 模式:贿赂(1) + 卖出(1) + 转账(N) + 买入(N) + 利润(1) ≤ 50 → 2N + 3 ≤ 50 → N ≤ 23
809
- // ERC20 模式:贿赂(1) + 卖出(1) + ERC20转账(N) + 买入(N) + 利润(1) ≤ 50 → 2N + 3 ≤ 50 → N ≤ 23
810
- const MAX_BUYERS = 23;
1036
+ // ✅ 动态计算最大买方数量(根据多跳数)
1037
+ // 固定开销: 贿赂(1) + 卖出(1) + 利润多跳(PROFIT_HOP_COUNT + 1)
1038
+ // BNB 模式(无多跳): 转账(N) + 买入(N) = 2N
1039
+ // BNB 模式(有多跳H): 转账(N*(H+1)) + 买入(N) = N*(H+2)
1040
+ // ERC20 模式(无多跳): 转账(N) + 买入(N) = 2N
1041
+ // ERC20 模式(有多跳H): BNB转账(N*(H+1)) + ERC20转账(N*(H+1)) + 买入(N) = N*(2H+3)
1042
+ const fixedOverhead = 1 + 1 + PROFIT_HOP_COUNT + 1; // 贿赂 + 卖出 + 利润多跳
1043
+ const maxTxs = 50 - fixedOverhead;
1044
+ let MAX_BUYERS;
1045
+ if (useNativeToken) {
1046
+ // BNB 模式: N*(H+2) <= maxTxs => N <= maxTxs / (H+2)
1047
+ MAX_BUYERS = Math.floor(maxTxs / (disperseHopCount + 2));
1048
+ }
1049
+ else {
1050
+ // ERC20 模式: N*(2H+3) <= maxTxs => N <= maxTxs / (2H+3)
1051
+ MAX_BUYERS = Math.floor(maxTxs / (2 * disperseHopCount + 3));
1052
+ }
1053
+ MAX_BUYERS = Math.max(1, MAX_BUYERS); // 至少1个
1054
+ console.log(`[pancakeQuickBatchSwapMerkle] 多跳数: ${disperseHopCount}, 最大买方数: ${MAX_BUYERS}`);
811
1055
  if (buyerPrivateKeys.length === 0) {
812
1056
  throw new Error('至少需要一个买方钱包');
813
1057
  }
814
1058
  if (buyerPrivateKeys.length > MAX_BUYERS) {
815
1059
  const mode = useNativeToken ? 'BNB' : 'ERC20';
816
- throw new Error(`资金利用率模式(${mode})买方钱包数量超过限制: ${buyerPrivateKeys.length} > ${MAX_BUYERS}`);
1060
+ throw new Error(`资金利用率模式(${mode}, ${disperseHopCount}跳)买方钱包数量超过限制: ${buyerPrivateKeys.length} > ${MAX_BUYERS}`);
817
1061
  }
818
1062
  // ✅ 校验分配模式
819
1063
  if (!buyerRatios && !buyerAmounts) {
@@ -1020,50 +1264,89 @@ export async function pancakeQuickBatchSwapMerkle(params) {
1020
1264
  type: txType
1021
1265
  });
1022
1266
  console.log(`[pancakeQuickBatchSwapMerkle] 卖出交易已签名`);
1023
- // ==================== 3. 转账交易(并行签名)====================
1267
+ // ==================== 3. 转账交易(支持多跳)====================
1024
1268
  const buyerGasCost = gasPrice * finalGasLimit;
1025
- // ✅ 预分配 nonce,然后并行签名
1026
- const transferNonces = buyers.map((_, i) => sellerNonce + i);
1027
- sellerNonce += buyers.length; // 更新 sellerNonce
1028
- let transferTxs;
1029
- if (useNativeToken) {
1030
- // ✅ 原生代币模式:直接 BNB 转账(并行签名)
1031
- transferTxs = await Promise.all(buyers.map((buyer, i) => {
1032
- const transferValue = transferAmountsWei[i] + FLAT_FEE + buyerGasCost;
1033
- return seller.signTransaction({
1034
- to: buyer.address,
1035
- value: transferValue,
1036
- nonce: transferNonces[i],
1037
- gasPrice,
1038
- gasLimit: 21000n,
1039
- chainId: context.chainId,
1040
- type: txType
1041
- });
1042
- }));
1269
+ // ✅ 生成多跳路径
1270
+ const hopPaths = generateDisperseHopPaths(buyers.map(b => b.address), disperseHopCount, context.provider);
1271
+ // 收集所有中间钱包信息
1272
+ const allHopWallets = [];
1273
+ hopPaths.forEach(path => {
1274
+ allHopWallets.push(...path.hopWalletsInfo);
1275
+ });
1276
+ let transferTxs = [];
1277
+ if (disperseHopCount === 0) {
1278
+ // ✅ 无多跳:直接转账
1279
+ const transferNonces = buyers.map((_, i) => sellerNonce + i);
1280
+ sellerNonce += buyers.length;
1281
+ if (useNativeToken) {
1282
+ transferTxs = await Promise.all(buyers.map((buyer, i) => {
1283
+ const transferValue = transferAmountsWei[i] + FLAT_FEE + buyerGasCost;
1284
+ return seller.signTransaction({
1285
+ to: buyer.address,
1286
+ value: transferValue,
1287
+ nonce: transferNonces[i],
1288
+ gasPrice,
1289
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
1290
+ chainId: context.chainId,
1291
+ type: txType
1292
+ });
1293
+ }));
1294
+ }
1295
+ else {
1296
+ const erc20Interface = new ethers.Interface(ERC20_ABI);
1297
+ transferTxs = await Promise.all(buyers.map((buyer, i) => {
1298
+ const transferData = erc20Interface.encodeFunctionData('transfer', [
1299
+ buyer.address,
1300
+ transferAmountsWei[i]
1301
+ ]);
1302
+ return seller.signTransaction({
1303
+ to: quoteToken,
1304
+ data: transferData,
1305
+ value: 0n,
1306
+ nonce: transferNonces[i],
1307
+ gasPrice,
1308
+ gasLimit: ERC20_TRANSFER_GAS,
1309
+ chainId: context.chainId,
1310
+ type: txType
1311
+ });
1312
+ }));
1313
+ }
1043
1314
  }
1044
1315
  else {
1045
- // ✅ ERC20 模式:ERC20 transfer(并行签名)
1046
- const erc20Interface = new ethers.Interface([
1047
- 'function transfer(address to, uint256 amount) returns (bool)'
1048
- ]);
1049
- transferTxs = await Promise.all(buyers.map((buyer, i) => {
1050
- const transferData = erc20Interface.encodeFunctionData('transfer', [
1051
- buyer.address,
1052
- transferAmountsWei[i]
1053
- ]);
1054
- return seller.signTransaction({
1055
- to: quoteToken,
1056
- data: transferData,
1057
- value: 0n,
1058
- nonce: transferNonces[i],
1059
- gasPrice,
1060
- gasLimit: ERC20_TRANSFER_GAS,
1061
- chainId: context.chainId,
1062
- type: txType
1063
- });
1064
- }));
1316
+ // ✅ 有多跳:构建多跳转账链
1317
+ if (useNativeToken) {
1318
+ // BNB 多跳转账
1319
+ const hopChains = await Promise.all(hopPaths.map((path, i) => {
1320
+ const finalAmount = transferAmountsWei[i] + FLAT_FEE + buyerGasCost;
1321
+ const payerNonce = sellerNonce + i * (disperseHopCount + 1);
1322
+ return buildNativeHopChain(seller, path, finalAmount, gasPrice, context.chainId, txType, payerNonce);
1323
+ }));
1324
+ transferTxs = hopChains.flat();
1325
+ sellerNonce += buyers.length * (disperseHopCount + 1);
1326
+ }
1327
+ else {
1328
+ // ERC20 多跳转账:先转 BNB(给中间钱包 gas),再转 ERC20
1329
+ // 每个 buyer 需要 (H+1) 笔 BNB 转账 + (H+1) 笔 ERC20 转账
1330
+ // 1. 构建 BNB 多跳链(为中间钱包和最终钱包预留 gas)
1331
+ const bnbHopChains = await Promise.all(hopPaths.map((path, i) => {
1332
+ // 最终钱包需要的 gas(用于买入交易)
1333
+ const finalGasAmount = buyerGasCost;
1334
+ const payerNonce = sellerNonce + i * (disperseHopCount + 1);
1335
+ return buildBNBHopChainForERC20(seller, path, finalGasAmount, gasPrice, context.chainId, txType, payerNonce);
1336
+ }));
1337
+ const bnbTxs = bnbHopChains.flat();
1338
+ sellerNonce += buyers.length * (disperseHopCount + 1);
1339
+ // 2. 构建 ERC20 多跳链
1340
+ const erc20HopChains = await Promise.all(hopPaths.map((path, i) => {
1341
+ const payerNonce = sellerNonce + i * (disperseHopCount + 1);
1342
+ return buildERC20HopChain(seller, path, quoteToken, transferAmountsWei[i], gasPrice, context.chainId, txType, payerNonce);
1343
+ }));
1344
+ const erc20Txs = erc20HopChains.flat();
1345
+ sellerNonce += buyers.length * (disperseHopCount + 1);
1346
+ transferTxs = [...bnbTxs, ...erc20Txs];
1347
+ }
1065
1348
  }
1066
- console.log(`[pancakeQuickBatchSwapMerkle] ${transferTxs.length} 笔转账交易已签名`);
1349
+ console.log(`[pancakeQuickBatchSwapMerkle] ${transferTxs.length} 笔转账交易已签名 (多跳数=${disperseHopCount})`);
1067
1350
  // ==================== 4. 买入交易 ====================
1068
1351
  // ✅ 如果前端传入了 startNonces,使用 buyer 部分(从索引 1 开始)
1069
1352
  const buyerNonces = startNonces && startNonces.length > 1
@@ -1150,6 +1433,7 @@ export async function pancakeQuickBatchSwapMerkle(params) {
1150
1433
  const outputUnit = useNativeToken ? 'BNB' : 'ERC20';
1151
1434
  return {
1152
1435
  signedTransactions,
1436
+ disperseHopWallets: allHopWallets.length > 0 ? allHopWallets : undefined, // ✅ 返回中间钱包信息
1153
1437
  metadata: {
1154
1438
  sellerAddress: seller.address,
1155
1439
  buyerAddresses: buyers.map(b => b.address),
@@ -1161,7 +1445,8 @@ export async function pancakeQuickBatchSwapMerkle(params) {
1161
1445
  ? ethers.formatEther(amt)
1162
1446
  : ethers.formatUnits(amt, quoteTokenDecimals)),
1163
1447
  profitAmount: profitAmount > 0n ? ethers.formatEther(profitAmount) : undefined,
1164
- useNativeToken
1448
+ useNativeToken,
1449
+ disperseHopCount: disperseHopCount > 0 ? disperseHopCount : undefined // ✅ 返回多跳数
1165
1450
  }
1166
1451
  };
1167
1452
  }
@@ -34,6 +34,8 @@ export type HoldersMakerConfig = {
34
34
  maxWalletsPerBatch?: number;
35
35
  /** Four API URL */
36
36
  fourApiUrl?: string;
37
+ /** 分发多跳数(0=直接转账,1=1跳,2=2跳...) */
38
+ disperseHopCount?: number;
37
39
  /** V2 路由路径(如 [WBNB, TOKEN]) */
38
40
  v2Path?: string[];
39
41
  /** V3 单跳输入代币 */
@@ -79,6 +81,8 @@ export type HoldersMakerResult = {
79
81
  success: boolean;
80
82
  /** 生成的新钱包 */
81
83
  newWallets: GeneratedWallet[];
84
+ /** 分发多跳中间钱包(可选,用于导出) */
85
+ disperseHopWallets?: GeneratedWallet[];
82
86
  /** 签名交易(每批一个数组) */
83
87
  signedTransactions: string[][];
84
88
  /** 批次结果 */