four-flap-meme-sdk 1.7.80 → 1.7.82

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,7 +1,7 @@
1
1
  import { ethers, Wallet } from 'ethers';
2
2
  import { getOptimizedGasPrice, NonceManager, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
3
- import { PROFIT_CONFIG, ZERO_ADDRESS } from '../../utils/constants.js';
4
- import { getTxType, getGasPriceConfig, shouldExtractProfit, getProfitRecipient } from './config.js';
3
+ import { PROFIT_CONFIG, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA } from '../../utils/constants.js';
4
+ import { getTxType, getGasPriceConfig, shouldExtractProfit, getProfitRecipient, getBribeAmount } from './config.js';
5
5
  import { getErc20DecimalsMerkle as _getErc20DecimalsMerkle, generateHopWallets as _generateHopWallets, normalizeAmounts as _normalizeAmounts, batchGetBalances as _batchGetBalances, calculateGasLimit as _calculateGasLimit, isNativeTokenAddress as _isNativeTokenAddress } from './internal.js';
6
6
  /**
7
7
  * 根据用户类型获取利润费率(bps)
@@ -27,8 +27,8 @@ function calculateProfit(amount, userType) {
27
27
  import { quote, QUOTE_CONFIG } from '../../utils/quote-helpers.js';
28
28
  import { Helper3 } from '../helper3.js';
29
29
  import { FlapPortal } from '../../flap/portal.js';
30
- /** 最低利润(Wei):无法获取报价时使用,0.0001 BNB */
31
- const MIN_PROFIT_WEI = 100000000000000n; // 0.0001 BNB = 10^14 wei
30
+ /** 最低利润(Wei):报价成功但金额过低时的阈值,0.00000001 BNB */
31
+ const MIN_PROFIT_WEI = 10000000000n; // 0.00000001 BNB = 10^10 wei(降低阈值以支持小额利润多跳)
32
32
  /** 链 ID → 链名称 映射 */
33
33
  const CHAIN_ID_TO_NAME = {
34
34
  56: 'BSC',
@@ -261,7 +261,10 @@ export async function disperseWithBundleMerkle(params) {
261
261
  const nonceManager = new NonceManager(provider);
262
262
  if (!preparedHops) {
263
263
  // ========== 无多跳:直接批量转账 ==========
264
- const extraTxCount = extractProfit ? 1 : 0;
264
+ // BSC 链贿赂支持
265
+ const bribeAmount = chainIdNum === 56 ? getBribeAmount(config) : 0n;
266
+ const needBribeTx = bribeAmount > 0n;
267
+ const extraTxCount = (extractProfit ? 1 : 0) + (needBribeTx ? 1 : 0);
265
268
  const totalTxCount = recipients.length + extraTxCount;
266
269
  // ✅ 优化:并行获取 gasPrice 和 nonces
267
270
  const [gasPrice, nonces] = await Promise.all([
@@ -270,6 +273,21 @@ export async function disperseWithBundleMerkle(params) {
270
273
  ? Promise.resolve(Array.from({ length: totalTxCount }, (_, i) => startNonce + i))
271
274
  : nonceManager.getNextNonceBatch(mainWallet, totalTxCount)
272
275
  ]);
276
+ // ✅ 贿赂交易放在最前面
277
+ let nonceOffset = 0;
278
+ if (needBribeTx) {
279
+ const bribeTx = await mainWallet.signTransaction({
280
+ to: BLOCKRAZOR_BUILDER_EOA,
281
+ value: bribeAmount,
282
+ nonce: nonces[nonceOffset++],
283
+ gasPrice,
284
+ gasLimit: 21000n,
285
+ chainId: chainIdNum,
286
+ type: txType
287
+ });
288
+ signedTxs.push(bribeTx);
289
+ console.log(`[disperse] 贿赂交易已添加: ${ethers.formatEther(bribeAmount)} BNB`);
290
+ }
273
291
  if (isNative) {
274
292
  // ✅ 原生币:先计算所有金额和利润(同步),再并行签名
275
293
  const txDataList = recipients.map((to, i) => {
@@ -281,7 +299,7 @@ export async function disperseWithBundleMerkle(params) {
281
299
  actualAmount = remaining;
282
300
  totalProfit += profit;
283
301
  }
284
- return { to, value: actualAmount, nonce: nonces[i] };
302
+ return { to, value: actualAmount, nonce: nonces[nonceOffset + i] };
285
303
  });
286
304
  // ✅ 并行签名所有交易
287
305
  const txPromises = txDataList.map(({ to, value, nonce }) => mainWallet.signTransaction({
@@ -305,7 +323,7 @@ export async function disperseWithBundleMerkle(params) {
305
323
  gasPrice,
306
324
  chainId: chainIdNum,
307
325
  txType,
308
- startNonce: nonces[recipients.length]
326
+ startNonce: nonces[nonceOffset + recipients.length]
309
327
  });
310
328
  signedTxs.push(...profitHopResult.signedTransactions);
311
329
  profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
@@ -355,7 +373,7 @@ export async function disperseWithBundleMerkle(params) {
355
373
  }
356
374
  // 报价成功:全额分发 ERC20(不扣 ERC20)
357
375
  const data = iface.encodeFunctionData('transfer', [to, actualAmount]);
358
- return { data, nonce: nonces[i] };
376
+ return { data, nonce: nonces[nonceOffset + i] };
359
377
  });
360
378
  // ✅ 并行签名所有交易
361
379
  const txPromises = txDataList.map(({ data, nonce }) => mainWallet.signTransaction({
@@ -369,7 +387,7 @@ export async function disperseWithBundleMerkle(params) {
369
387
  type: txType
370
388
  }));
371
389
  signedTxs.push(...(await Promise.all(txPromises)));
372
- // ✅ 利润多跳转账(强制 2 跳中转)- 仅在报价成功时扣 OKB
390
+ // ✅ 利润多跳转账(强制 2 跳中转)- 仅在报价成功时扣 OKB/BNB
373
391
  if (extractProfit && profitIsNative && nativeProfitAmount > 0n) {
374
392
  const profitHopResult = await buildProfitHopTransactions({
375
393
  provider,
@@ -380,15 +398,19 @@ export async function disperseWithBundleMerkle(params) {
380
398
  gasPrice,
381
399
  chainId: chainIdNum,
382
400
  txType,
383
- startNonce: nonces[recipients.length]
401
+ startNonce: nonces[nonceOffset + recipients.length]
384
402
  });
385
403
  signedTxs.push(...profitHopResult.signedTransactions);
386
404
  profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
405
+ console.log(`[disperse ERC20] 利润多跳已添加: ${ethers.formatEther(nativeProfitAmount)} 原生币`);
387
406
  }
388
407
  }
389
408
  }
390
409
  else {
391
410
  // ========== 有多跳:构建跳转链 ==========
411
+ // ✅ BSC 链贿赂支持
412
+ const bribeAmountHop = chainIdNum === 56 ? getBribeAmount(config) : 0n;
413
+ const needBribeTxHop = bribeAmountHop > 0n;
392
414
  // ✅ 优化:并行获取 gasPrice 和 decimals
393
415
  const [gasPrice, decimals] = await Promise.all([
394
416
  getOptimizedGasPrice(provider, getGasPriceConfig(config)),
@@ -409,6 +431,9 @@ export async function disperseWithBundleMerkle(params) {
409
431
  // - 原生代币多跳:主钱包只需要 1 个 nonce(一笔转账包含后续所有 gas)
410
432
  // - ERC20 多跳:主钱包需要 2 个 nonce(转 gas + 转 ERC20)
411
433
  let mainWalletNonceCount = 0;
434
+ // 贿赂交易需要 1 个额外的 nonce
435
+ if (needBribeTxHop)
436
+ mainWalletNonceCount += 1;
412
437
  for (let i = 0; i < recipients.length; i++) {
413
438
  const hopChain = preparedHops[i];
414
439
  if (hopChain.length === 0) {
@@ -430,6 +455,20 @@ export async function disperseWithBundleMerkle(params) {
430
455
  ? Array.from({ length: mainWalletNonceCount }, (_, i) => startNonce + i)
431
456
  : await nonceManager.getNextNonceBatch(mainWallet, mainWalletNonceCount);
432
457
  let mainNonceIdx = 0;
458
+ // ✅ 贿赂交易放在最前面(多跳场景)
459
+ if (needBribeTxHop) {
460
+ const bribeTx = await mainWallet.signTransaction({
461
+ to: BLOCKRAZOR_BUILDER_EOA,
462
+ value: bribeAmountHop,
463
+ nonce: allMainNonces[mainNonceIdx++],
464
+ gasPrice,
465
+ gasLimit: 21000n,
466
+ chainId: chainIdNum,
467
+ type: txType
468
+ });
469
+ signedTxs.push(bribeTx);
470
+ console.log(`[disperse with hops] 贿赂交易已添加: ${ethers.formatEther(bribeAmountHop)} BNB`);
471
+ }
433
472
  const txsToSign = [];
434
473
  // ✅ ERC20 多跳:累计代币利润,最后统一转换为原生代币
435
474
  let totalTokenProfit = 0n;
@@ -727,6 +766,28 @@ export async function sweepWithBundleMerkle(params) {
727
766
  let totalProfit = 0n;
728
767
  let totalAmountBeforeProfit = 0n;
729
768
  let profitHopWallets; // ✅ 收集利润多跳钱包
769
+ // ✅ BSC 链贿赂支持(由 targetWallet 支付,如果提供了 targetPrivateKey)
770
+ const bribeAmount = chainIdNum === 56 ? getBribeAmount(config) : 0n;
771
+ const needBribeTx = bribeAmount > 0n && targetWallet !== null;
772
+ const bribeSignedTx = [];
773
+ // ✅ 贿赂交易放在最前面(由 targetWallet 签名)
774
+ if (needBribeTx && targetWallet) {
775
+ const [bribeGasPrice, bribeNonce] = await Promise.all([
776
+ getOptimizedGasPrice(provider, getGasPriceConfig(config)),
777
+ provider.getTransactionCount(targetWallet.address)
778
+ ]);
779
+ const bribeTx = await targetWallet.signTransaction({
780
+ to: BLOCKRAZOR_BUILDER_EOA,
781
+ value: bribeAmount,
782
+ nonce: bribeNonce,
783
+ gasPrice: bribeGasPrice,
784
+ gasLimit: 21000n,
785
+ chainId: chainIdNum,
786
+ type: txType
787
+ });
788
+ bribeSignedTx.push(bribeTx);
789
+ console.log(`[sweep] 贿赂交易已添加: ${ethers.formatEther(bribeAmount)} BNB (by targetWallet)`);
790
+ }
730
791
  if (!preparedHops) {
731
792
  // ========== 无多跳:直接批量归集 ==========
732
793
  const wallets = actualKeys.map(pk => new Wallet(pk, provider));
@@ -1403,9 +1464,9 @@ export async function sweepWithBundleMerkle(params) {
1403
1464
  }
1404
1465
  }
1405
1466
  }
1406
- // ✅ 简化返回:只返回签名交易、多跳钱包和元数据
1467
+ // ✅ 简化返回:贿赂交易放在最前面,然后是签名交易、多跳钱包和元数据
1407
1468
  return {
1408
- signedTransactions: signedTxs,
1469
+ signedTransactions: [...bribeSignedTx, ...signedTxs],
1409
1470
  hopWallets: preparedHops || undefined,
1410
1471
  profitHopWallets, // ✅ 返回利润多跳钱包
1411
1472
  metadata: extractProfit ? {
@@ -1414,7 +1475,9 @@ export async function sweepWithBundleMerkle(params) {
1414
1475
  profitRecipient: getProfitRecipient(),
1415
1476
  sourceCount: actualKeys.length,
1416
1477
  isNative,
1417
- tokenAddress: isNative ? undefined : tokenAddress
1478
+ tokenAddress: isNative ? undefined : tokenAddress,
1479
+ hasBribeTx: bribeSignedTx.length > 0, // ✅ 标记是否有贿赂交易
1480
+ bribeAmount: bribeSignedTx.length > 0 ? ethers.formatEther(bribeAmount) : undefined
1418
1481
  } : undefined
1419
1482
  };
1420
1483
  }
@@ -1498,6 +1561,10 @@ export async function pairwiseTransferWithBundleMerkle(params) {
1498
1561
  if (!isNative && extractProfit && totalTokenProfit > 0n) {
1499
1562
  totalProfitNative = await getTokenToNativeQuote(provider, tokenAddress, totalTokenProfit, chainIdNum, tokenPoolType, quoteToken, config.rpcUrl);
1500
1563
  }
1564
+ // ✅ BSC 链贿赂支持(由第一个 sender 支付)
1565
+ const bribeAmount = chainIdNum === 56 ? getBribeAmount(config) : 0n;
1566
+ const needBribeTx = bribeAmount > 0n;
1567
+ const bribeSignedTx = [];
1501
1568
  // 计算每个 sender 需要的 nonce 数量(聚合到地址)
1502
1569
  const senderWallets = senderPrivateKeys.map(pk => new Wallet(pk, provider));
1503
1570
  const senderAddrLowerList = senderWallets.map(w => w.address.toLowerCase());
@@ -1517,6 +1584,12 @@ export async function pairwiseTransferWithBundleMerkle(params) {
1517
1584
  else
1518
1585
  nonceNeedBySender.set(addrLower, { wallet: senderWallets[i], count: perPairTxCount });
1519
1586
  }
1587
+ // ✅ 贿赂交易需要 1 个额外的 nonce
1588
+ if (needBribeTx) {
1589
+ const cur = nonceNeedBySender.get(firstSenderAddrLower);
1590
+ if (cur)
1591
+ cur.count += 1;
1592
+ }
1520
1593
  if (extractProfit && totalProfitNative > 0n) {
1521
1594
  const cur = nonceNeedBySender.get(firstSenderAddrLower);
1522
1595
  if (cur)
@@ -1671,6 +1744,22 @@ export async function pairwiseTransferWithBundleMerkle(params) {
1671
1744
  }
1672
1745
  }
1673
1746
  }
1747
+ // ✅ 贿赂交易签名(放在最前面)
1748
+ if (needBribeTx) {
1749
+ const firstSenderWallet = senderWallets[0];
1750
+ const bribeNonce = popNonce(firstSenderAddrLower);
1751
+ const bribeTx = await firstSenderWallet.signTransaction({
1752
+ to: BLOCKRAZOR_BUILDER_EOA,
1753
+ value: bribeAmount,
1754
+ nonce: bribeNonce,
1755
+ gasPrice,
1756
+ gasLimit: 21000n,
1757
+ chainId: chainIdNum,
1758
+ type: txType
1759
+ });
1760
+ bribeSignedTx.push(bribeTx);
1761
+ console.log(`[pairwise] 贿赂交易已添加: ${ethers.formatEther(bribeAmount)} BNB`);
1762
+ }
1674
1763
  const signedTxs = await Promise.all(txsToSign.map(({ wallet, tx }) => wallet.signTransaction(tx)));
1675
1764
  // 利润多跳(固定 2 hop)
1676
1765
  let profitHopWallets;
@@ -1692,7 +1781,7 @@ export async function pairwiseTransferWithBundleMerkle(params) {
1692
1781
  profitHopWallets = profitHopResult.hopWallets;
1693
1782
  }
1694
1783
  return {
1695
- signedTransactions: signedTxs,
1784
+ signedTransactions: [...bribeSignedTx, ...signedTxs], // ✅ 贿赂交易放在最前面
1696
1785
  hopWallets: preparedHops || undefined,
1697
1786
  profitHopWallets,
1698
1787
  metadata: extractProfit ? {
@@ -1702,6 +1791,8 @@ export async function pairwiseTransferWithBundleMerkle(params) {
1702
1791
  totalAmount: isNative ? ethers.formatEther(totalAmountBeforeProfit) : ethers.formatUnits(totalAmountBeforeProfit, decimals),
1703
1792
  profitAmount: ethers.formatEther(totalProfitNative),
1704
1793
  profitRecipient: getProfitRecipient(),
1794
+ hasBribeTx: bribeSignedTx.length > 0, // ✅ 标记是否有贿赂交易
1795
+ bribeAmount: bribeSignedTx.length > 0 ? ethers.formatEther(bribeAmount) : undefined
1705
1796
  } : undefined
1706
1797
  };
1707
1798
  }
@@ -305,10 +305,7 @@ export async function flapBundleCreateToDex(params) {
305
305
  // V4: 提供了 dexId 或 lpFeeProfile(支持 DEX 选择和 LP 费率配置)
306
306
  // V3: 提供了 extensionID(支持扩展数据)
307
307
  // V2: 默认
308
- console.log('[create-to-dex] 🔍 taxV2Config:', params.taxV2Config);
309
- console.log('[create-to-dex] 🔍 taxRate:', params.taxRate);
310
308
  const useV5 = params.taxV2Config !== undefined && (params.taxRate ?? 0) > 0;
311
- console.log('[create-to-dex] 🔍 useV5:', useV5);
312
309
  const useV4 = !useV5 && (params.dexId !== undefined || params.lpFeeProfile !== undefined);
313
310
  const useV3 = !useV5 && !useV4 && !!params.extensionID;
314
311
  let createUnsigned;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.7.80",
3
+ "version": "1.7.82",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",