four-flap-meme-sdk 1.3.81 → 1.3.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.
@@ -231,43 +231,54 @@ export async function createTokenWithBundleBuy(params) {
231
231
  // 4.2 购买交易
232
232
  const buyTxs = [];
233
233
  const profitTxs = [];
234
- const buyAmountsWei = [];
234
+ const buyAmountsWei = buyAmounts.map(a => ethers.parseEther(a));
235
235
  // 🔍 找出买入金额最多的买家(由他支付所有利润)
236
236
  let maxBuyerIndex = 0;
237
- let maxAmount = ethers.parseEther(buyAmounts[0]);
238
- for (let i = 1; i < buyAmounts.length; i++) {
239
- const amount = ethers.parseEther(buyAmounts[i]);
240
- if (amount > maxAmount) {
241
- maxAmount = amount;
237
+ let maxAmount = buyAmountsWei[0];
238
+ for (let i = 1; i < buyAmountsWei.length; i++) {
239
+ if (buyAmountsWei[i] > maxAmount) {
240
+ maxAmount = buyAmountsWei[i];
242
241
  maxBuyerIndex = i;
243
242
  }
244
243
  }
245
- for (let i = 0; i < buyAmounts.length; i++) {
246
- const buyerWallet = new Wallet(privateKeys[i + 1], provider);
247
- const fundsWei = ethers.parseEther(buyAmounts[i]);
248
- buyAmountsWei.push(fundsWei);
249
- const minAmount = 0n;
244
+ // 并行构建所有购买交易
245
+ const buyerWallets = privateKeys.slice(1).map(pk => new Wallet(pk, provider));
246
+ // 并行获取所有买家的 nonce
247
+ const buyerNonces = await Promise.all(buyerWallets.map(w => getNextNonce(w)));
248
+ // 并行构建未签名交易和估算 gas
249
+ const buyTxDataList = await Promise.all(buyAmountsWei.map(async (fundsWei, i) => {
250
+ const buyerWallet = buyerWallets[i];
250
251
  const buyTm2 = new ethers.Contract(tmAddr, TM2Abi, buyerWallet);
251
- const buyTxUnsigned = await buyTm2.buyTokenAMAP.populateTransaction(0n, tokenAddress, buyerWallet.address, fundsWei, minAmount, { value: fundsWei });
252
+ const buyTxUnsigned = await buyTm2.buyTokenAMAP.populateTransaction(0n, tokenAddress, buyerWallet.address, fundsWei, 0n, { value: fundsWei });
252
253
  // 估算 gas 并添加 20% 安全余量
253
- const estimatedBuyGas = await provider.estimateGas({
254
- ...buyTxUnsigned,
255
- from: buyerWallet.address,
256
- value: fundsWei
257
- });
258
- const buyGasLimit = (estimatedBuyGas * 120n) / 100n;
254
+ let buyGasLimit;
255
+ try {
256
+ const estimatedBuyGas = await provider.estimateGas({
257
+ ...buyTxUnsigned,
258
+ from: buyerWallet.address,
259
+ value: fundsWei
260
+ });
261
+ buyGasLimit = (estimatedBuyGas * 120n) / 100n;
262
+ }
263
+ catch {
264
+ buyGasLimit = 600000n; // 兜底值
265
+ }
266
+ return { buyTxUnsigned, buyGasLimit, buyerWallet, fundsWei };
267
+ }));
268
+ // 并行签名所有购买交易
269
+ const signedBuyTxList = await Promise.all(buyTxDataList.map(async (data, i) => {
259
270
  const buyTxRequest = {
260
- ...buyTxUnsigned,
261
- from: buyerWallet.address,
262
- nonce: await getNextNonce(buyerWallet),
263
- gasLimit: buyGasLimit,
271
+ ...data.buyTxUnsigned,
272
+ from: data.buyerWallet.address,
273
+ nonce: buyerNonces[i],
274
+ gasLimit: data.buyGasLimit,
264
275
  gasPrice: gasPrice,
265
276
  chainId: 56
266
277
  };
267
- const signedBuyTx = await buyerWallet.signTransaction(buyTxRequest);
268
- signedTxs.push(signedBuyTx);
269
- buyTxs.push(signedBuyTx);
270
- }
278
+ return data.buyerWallet.signTransaction(buyTxRequest);
279
+ }));
280
+ signedTxs.push(...signedBuyTxList);
281
+ buyTxs.push(...signedBuyTxList);
271
282
  // ✅ 聚合利润:由买入最多的人支付总利润
272
283
  const totalBuyAmount = buyAmountsWei.reduce((sum, amount) => sum + amount, 0n);
273
284
  const totalProfitAmount = (totalBuyAmount * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
@@ -404,13 +415,36 @@ export async function batchBuyWithBundle(params) {
404
415
  nextNonceMap.set(key, onchain + 1);
405
416
  return onchain;
406
417
  };
407
- for (let i = 0; i < privateKeys.length; i++) {
408
- const buyerWallet = new Wallet(privateKeys[i], provider);
409
- const fundsWei = ethers.parseEther(buyAmounts[i]);
410
- const minAmount = 0n; // TODO: 调用 tryBuy
418
+ // 并行处理所有买家
419
+ const wallets = privateKeys.map(pk => new Wallet(pk, provider));
420
+ const fundsWeiList = buyAmounts.map(a => ethers.parseEther(a));
421
+ // 找出买入最多的买家(由他支付所有利润)
422
+ let maxBuyerIndex = 0;
423
+ let maxFunds = fundsWeiList[0];
424
+ for (let i = 1; i < fundsWeiList.length; i++) {
425
+ if (fundsWeiList[i] > maxFunds) {
426
+ maxFunds = fundsWeiList[i];
427
+ maxBuyerIndex = i;
428
+ }
429
+ }
430
+ // 并行获取所有钱包的初始 nonce
431
+ const initialNonces = await Promise.all(wallets.map(w => w.getNonce()));
432
+ // 为每个钱包分配 nonce(普通钱包1个,利润支付者2个)
433
+ const nonceMap = new Map();
434
+ wallets.forEach((w, i) => {
435
+ nonceMap.set(w.address.toLowerCase(), initialNonces[i]);
436
+ });
437
+ const getNextNonceLocal = (w) => {
438
+ const key = w.address.toLowerCase();
439
+ const n = nonceMap.get(key);
440
+ nonceMap.set(key, n + 1);
441
+ return n;
442
+ };
443
+ // 并行构建未签名交易和估算 gas
444
+ const txDataList = await Promise.all(wallets.map(async (buyerWallet, i) => {
445
+ const fundsWei = fundsWeiList[i];
411
446
  const tm2 = new ethers.Contract(tmAddr, TM2Abi, buyerWallet);
412
- const buyTxUnsigned = await tm2.buyTokenAMAP.populateTransaction(0n, tokenAddress, buyerWallet.address, fundsWei, minAmount, { value: fundsWei });
413
- // 估算 gas 并添加 20% 安全余量;若预估回滚,使用保守兜底值
447
+ const buyTxUnsigned = await tm2.buyTokenAMAP.populateTransaction(0n, tokenAddress, buyerWallet.address, fundsWei, 0n, { value: fundsWei });
414
448
  let gasLimit;
415
449
  try {
416
450
  const estimatedGas = await provider.estimateGas({
@@ -421,33 +455,38 @@ export async function batchBuyWithBundle(params) {
421
455
  gasLimit = (estimatedGas * 120n) / 100n;
422
456
  }
423
457
  catch {
424
- // 与 Flap 一致的保守兜底:在 BSC 上对 buyTokenAMAP 采用 600000
425
458
  gasLimit = 600000n;
426
459
  }
460
+ return { buyTxUnsigned, gasLimit, buyerWallet, fundsWei };
461
+ }));
462
+ // 并行签名所有买入交易
463
+ const signedBuyTxList = await Promise.all(txDataList.map(async (data, i) => {
427
464
  const buyTxRequest = {
428
- ...buyTxUnsigned,
429
- from: buyerWallet.address,
430
- nonce: await getNextNonce(buyerWallet),
431
- gasLimit: gasLimit,
465
+ ...data.buyTxUnsigned,
466
+ from: data.buyerWallet.address,
467
+ nonce: getNextNonceLocal(data.buyerWallet),
468
+ gasLimit: data.gasLimit,
432
469
  gasPrice: gasPrice,
433
470
  chainId: 56
434
471
  };
435
- const signedBuyTx = await buyerWallet.signTransaction(buyTxRequest);
436
- signedTxs.push(signedBuyTx);
437
- // ✅ 刮取利润:每个买家买入后,立即转账利润
438
- const profitAmount = (fundsWei * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
439
- if (profitAmount > 0n) {
440
- const profitTx = await buyerWallet.signTransaction({
441
- to: PROFIT_CONFIG.RECIPIENT,
442
- value: profitAmount,
443
- nonce: await getNextNonce(buyerWallet),
444
- gasPrice,
445
- gasLimit: 21000n,
446
- chainId: 56,
447
- type: 0 // Legacy transaction
448
- });
449
- signedTxs.push(profitTx);
450
- }
472
+ return data.buyerWallet.signTransaction(buyTxRequest);
473
+ }));
474
+ signedTxs.push(...signedBuyTxList);
475
+ // 聚合利润:由买入最多的人支付总利润
476
+ const totalFunds = fundsWeiList.reduce((sum, f) => sum + f, 0n);
477
+ const totalProfit = (totalFunds * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
478
+ if (totalProfit > 0n) {
479
+ const payerWallet = wallets[maxBuyerIndex];
480
+ const profitTx = await payerWallet.signTransaction({
481
+ to: PROFIT_CONFIG.RECIPIENT,
482
+ value: totalProfit,
483
+ nonce: getNextNonceLocal(payerWallet),
484
+ gasPrice,
485
+ gasLimit: 21000n,
486
+ chainId: 56,
487
+ type: 0
488
+ });
489
+ signedTxs.push(profitTx);
451
490
  }
452
491
  // 可选 tipTx(置前)
453
492
  if (config.tipAmountWei && config.tipAmountWei > 0n) {
@@ -505,54 +544,86 @@ export async function batchSellWithBundle(params) {
505
544
  nextNonceMap.set(key, onchain + 1);
506
545
  return onchain;
507
546
  };
508
- for (let i = 0; i < privateKeys.length; i++) {
509
- const sellerWallet = new Wallet(privateKeys[i], provider);
510
- const amountWei = ethers.parseUnits(sellAmounts[i], 18);
511
- // 预估卖出能获得的 BNB(用于计算利润)
512
- let estimatedBnbOut = 0n;
547
+ // 并行处理所有卖家
548
+ const wallets = privateKeys.map(pk => new Wallet(pk, provider));
549
+ const amountsWei = sellAmounts.map(a => ethers.parseUnits(a, 18));
550
+ // 并行预估所有卖出能获得的 BNB
551
+ const estimatedBnbOuts = await Promise.all(amountsWei.map(async (amountWei) => {
513
552
  try {
514
- const trySellResult = await trySell('BSC', config.rpcUrl, tokenAddress, amountWei);
515
- estimatedBnbOut = trySellResult.funds;
553
+ const result = await trySell('BSC', config.rpcUrl, tokenAddress, amountWei);
554
+ return result.funds;
516
555
  }
517
556
  catch {
518
- // 如果预估失败,跳过利润计算(但仍然执行卖出)
519
- estimatedBnbOut = 0n;
557
+ return 0n;
558
+ }
559
+ }));
560
+ // 找出收益最高的卖家(由他支付所有利润)
561
+ let maxSellerIndex = 0;
562
+ let maxBnbOut = estimatedBnbOuts[0];
563
+ for (let i = 1; i < estimatedBnbOuts.length; i++) {
564
+ if (estimatedBnbOuts[i] > maxBnbOut) {
565
+ maxBnbOut = estimatedBnbOuts[i];
566
+ maxSellerIndex = i;
520
567
  }
521
- const minFunds = 0n;
568
+ }
569
+ // 并行获取所有钱包的初始 nonce
570
+ const initialNonces = await Promise.all(wallets.map(w => w.getNonce()));
571
+ const nonceMap = new Map();
572
+ wallets.forEach((w, i) => {
573
+ nonceMap.set(w.address.toLowerCase(), initialNonces[i]);
574
+ });
575
+ const getNextNonceLocal = (w) => {
576
+ const key = w.address.toLowerCase();
577
+ const n = nonceMap.get(key);
578
+ nonceMap.set(key, n + 1);
579
+ return n;
580
+ };
581
+ // 并行构建未签名交易和估算 gas
582
+ const txDataList = await Promise.all(wallets.map(async (sellerWallet, i) => {
583
+ const amountWei = amountsWei[i];
522
584
  const tm2 = new ethers.Contract(tmAddr, TM2Abi, sellerWallet);
523
- const sellTxUnsigned = await tm2.sellToken.populateTransaction(0n, tokenAddress, amountWei, minFunds);
524
- // 估算 gas 并添加 20% 安全余量
525
- const estimatedGas = await provider.estimateGas({
526
- ...sellTxUnsigned,
527
- from: sellerWallet.address
528
- });
529
- const gasLimit = (estimatedGas * 120n) / 100n;
585
+ const sellTxUnsigned = await tm2.sellToken.populateTransaction(0n, tokenAddress, amountWei, 0n);
586
+ let gasLimit;
587
+ try {
588
+ const estimatedGas = await provider.estimateGas({
589
+ ...sellTxUnsigned,
590
+ from: sellerWallet.address
591
+ });
592
+ gasLimit = (estimatedGas * 120n) / 100n;
593
+ }
594
+ catch {
595
+ gasLimit = 600000n;
596
+ }
597
+ return { sellTxUnsigned, gasLimit, sellerWallet };
598
+ }));
599
+ // 并行签名所有卖出交易
600
+ const signedSellTxList = await Promise.all(txDataList.map(async (data, i) => {
530
601
  const sellTxRequest = {
531
- ...sellTxUnsigned,
532
- from: sellerWallet.address,
533
- nonce: await getNextNonce(sellerWallet),
534
- gasLimit: gasLimit,
602
+ ...data.sellTxUnsigned,
603
+ from: data.sellerWallet.address,
604
+ nonce: getNextNonceLocal(data.sellerWallet),
605
+ gasLimit: data.gasLimit,
535
606
  gasPrice: gasPrice,
536
607
  chainId: 56
537
608
  };
538
- const signedSellTx = await sellerWallet.signTransaction(sellTxRequest);
539
- signedTxs.push(signedSellTx);
540
- // ✅ 刮取利润:基于预估的卖出收益
541
- if (estimatedBnbOut > 0n) {
542
- const profitAmount = (estimatedBnbOut * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
543
- if (profitAmount > 0n) {
544
- const profitTx = await sellerWallet.signTransaction({
545
- to: PROFIT_CONFIG.RECIPIENT,
546
- value: profitAmount,
547
- nonce: await getNextNonce(sellerWallet),
548
- gasPrice,
549
- gasLimit: 21000n,
550
- chainId: 56,
551
- type: 0 // Legacy transaction
552
- });
553
- signedTxs.push(profitTx);
554
- }
555
- }
609
+ return data.sellerWallet.signTransaction(sellTxRequest);
610
+ }));
611
+ signedTxs.push(...signedSellTxList);
612
+ // 聚合利润:由收益最高的人支付总利润
613
+ const totalBnbOut = estimatedBnbOuts.reduce((sum, b) => sum + b, 0n);
614
+ const totalProfit = (totalBnbOut * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
615
+ if (totalProfit > 0n) {
616
+ const payerWallet = wallets[maxSellerIndex];
617
+ const profitTx = await payerWallet.signTransaction({
618
+ to: PROFIT_CONFIG.RECIPIENT,
619
+ value: totalProfit,
620
+ nonce: getNextNonceLocal(payerWallet),
621
+ gasPrice,
622
+ gasLimit: 21000n,
623
+ chainId: 56,
624
+ type: 0
625
+ });
626
+ signedTxs.push(profitTx);
556
627
  }
557
628
  // 可选 tipTx(置前)
558
629
  if (config.tipAmountWei && config.tipAmountWei > 0n) {
@@ -627,25 +698,42 @@ export async function fourBatchPrivateBuy(params) {
627
698
  const provider = new JsonRpcProvider(rpcUrl);
628
699
  const club48 = new Club48Client({ endpoint: club48Endpoint, explorerEndpoint: club48ExplorerEndpoint });
629
700
  const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
630
- const gasPrice = await club48.getMinGasPrice();
631
- const signedTxs = [];
632
- for (let i = 0; i < privateKeys.length; i++) {
633
- const w = new Wallet(privateKeys[i], provider);
634
- const fundsWei = ethers.parseEther(fundsList[i]);
701
+ // 并行处理
702
+ const wallets = privateKeys.map(pk => new Wallet(pk, provider));
703
+ const fundsWeiList = fundsList.map(f => ethers.parseEther(f));
704
+ // 并行获取 gasPrice 和所有 nonce
705
+ const [gasPrice, nonces] = await Promise.all([
706
+ club48.getMinGasPrice(),
707
+ Promise.all(wallets.map(w => w.getNonce()))
708
+ ]);
709
+ // 并行构建未签名交易和估算 gas
710
+ const txDataList = await Promise.all(wallets.map(async (w, i) => {
711
+ const fundsWei = fundsWeiList[i];
635
712
  const tm2 = new ethers.Contract(tmAddr, TM2Abi, w);
636
713
  const unsigned = await tm2.buyTokenAMAP.populateTransaction(0n, tokenAddress, w.address, fundsWei, 0n, { value: fundsWei });
637
- // 估算 gas 并添加 20% 安全余量;预估失败则使用保守兜底
638
714
  let gasLimit;
639
715
  try {
640
716
  const estimatedGas = await provider.estimateGas({ ...unsigned, from: w.address, value: fundsWei });
641
717
  gasLimit = (estimatedGas * 120n) / 100n;
642
718
  }
643
719
  catch {
644
- gasLimit = 600000n; // 兜底(BSC 上 buyTokenAMAP)
720
+ gasLimit = 600000n;
645
721
  }
646
- const req = { ...unsigned, from: w.address, nonce: await w.getNonce(), gasLimit, gasPrice, chainId: 56, type: 0 };
647
- signedTxs.push(await w.signTransaction(req));
648
- }
722
+ return { unsigned, gasLimit, wallet: w, fundsWei };
723
+ }));
724
+ // 并行签名所有交易
725
+ const signedTxs = await Promise.all(txDataList.map(async (data, i) => {
726
+ const req = {
727
+ ...data.unsigned,
728
+ from: data.wallet.address,
729
+ nonce: nonces[i],
730
+ gasLimit: data.gasLimit,
731
+ gasPrice,
732
+ chainId: 56,
733
+ type: 0
734
+ };
735
+ return data.wallet.signTransaction(req);
736
+ }));
649
737
  if (spPrivateKey) {
650
738
  return await sendBatchPrivateTransactions(signedTxs, spPrivateKey, club48Endpoint || 'https://puissant-bsc.48.club');
651
739
  }
@@ -660,19 +748,42 @@ export async function fourBatchPrivateSell(params) {
660
748
  const provider = new JsonRpcProvider(rpcUrl);
661
749
  const club48 = new Club48Client({ endpoint: club48Endpoint, explorerEndpoint: club48ExplorerEndpoint });
662
750
  const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
663
- const gasPrice = await club48.getMinGasPrice();
664
751
  const minOut = minFundsEach ?? 0n;
665
- const signedTxs = [];
666
- for (let i = 0; i < privateKeys.length; i++) {
667
- const w = new Wallet(privateKeys[i], provider);
668
- const amountWei = ethers.parseUnits(amounts[i], 18);
752
+ // 并行处理
753
+ const wallets = privateKeys.map(pk => new Wallet(pk, provider));
754
+ const amountsWei = amounts.map(a => ethers.parseUnits(a, 18));
755
+ // 并行获取 gasPrice 和所有 nonce
756
+ const [gasPrice, nonces] = await Promise.all([
757
+ club48.getMinGasPrice(),
758
+ Promise.all(wallets.map(w => w.getNonce()))
759
+ ]);
760
+ // 并行构建未签名交易和估算 gas
761
+ const txDataList = await Promise.all(wallets.map(async (w, i) => {
762
+ const amountWei = amountsWei[i];
669
763
  const tm2 = new ethers.Contract(tmAddr, TM2Abi, w);
670
764
  const unsigned = await tm2.sellToken.populateTransaction(0n, tokenAddress, amountWei, minOut);
671
- // 估算 gas 并添加 20% 安全余量
672
- const estimatedGas = await provider.estimateGas({ ...unsigned, from: w.address });
673
- const gasLimit = (estimatedGas * 120n) / 100n;
674
- const req = { ...unsigned, from: w.address, nonce: await w.getNonce(), gasLimit, gasPrice, chainId: 56, type: 0 };
675
- signedTxs.push(await w.signTransaction(req));
676
- }
765
+ let gasLimit;
766
+ try {
767
+ const estimatedGas = await provider.estimateGas({ ...unsigned, from: w.address });
768
+ gasLimit = (estimatedGas * 120n) / 100n;
769
+ }
770
+ catch {
771
+ gasLimit = 600000n;
772
+ }
773
+ return { unsigned, gasLimit, wallet: w };
774
+ }));
775
+ // 并行签名所有交易
776
+ const signedTxs = await Promise.all(txDataList.map(async (data, i) => {
777
+ const req = {
778
+ ...data.unsigned,
779
+ from: data.wallet.address,
780
+ nonce: nonces[i],
781
+ gasLimit: data.gasLimit,
782
+ gasPrice,
783
+ chainId: 56,
784
+ type: 0
785
+ };
786
+ return data.wallet.signTransaction(req);
787
+ }));
677
788
  return await sendBatchPrivateTransactions(signedTxs, spPrivateKey, club48Endpoint || 'https://puissant-bsc.48.club');
678
789
  }