four-flap-meme-sdk 1.7.71 → 1.7.73

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.
@@ -420,10 +420,21 @@ export async function bundleCreateToDex(params) {
420
420
  }
421
421
  // ✅ 利润从 Payer 钱包余额转出,主交易只支付创建费用
422
422
  const totalValue = params.quoteAmt ?? 0n;
423
- // 构建签名交易(一键发射会触发毕业,使用高 gas limit)
423
+ // 动态计算 Gas Limit:基础操作 + 毕业额外 gas
424
+ // 毕业操作需要约 800 万 gas,加上其他操作的 gas
425
+ const baseGas = GAS_ESTIMATE.BASE
426
+ + BigInt(allWallets.length) * GAS_ESTIMATE.PER_AUTHORIZATION
427
+ + BigInt(calls.length) * GAS_ESTIMATE.PER_CALL_BASE
428
+ + BigInt(curveBuyerWallets.length) * GAS_ESTIMATE.BUY_EXTRA // 内盘买入
429
+ + BigInt(dexBuyerWallets.length) * GAS_ESTIMATE.BUY_EXTRA // 外盘买入
430
+ + GAS_ESTIMATE.CREATE_TOKEN // 创建代币
431
+ + GAS_ESTIMATE.GRADUATE; // 毕业操作 (800万)
432
+ const dynamicGasLimit = BigInt(Math.ceil(Number(baseGas) * GAS_ESTIMATE.SAFETY_MULTIPLIER));
433
+ const finalGasLimit = dynamicGasLimit > GAS_ESTIMATE.MAX ? GAS_ESTIMATE.MAX : dynamicGasLimit;
434
+ console.log(`[bundleCreateToDex] 动态 Gas 计算: 授权=${allWallets.length}, 调用=${calls.length}, 内盘=${curveBuyerWallets.length}, 外盘=${dexBuyerWallets.length}, Gas=${finalGasLimit.toString()}`);
424
435
  const toDexConfig = {
425
436
  ...config,
426
- gasLimit: GAS_ESTIMATE.GRADUATE, // ✅ 一键发射(创建+毕业)需要约 800 万 gas
437
+ gasLimit: finalGasLimit, // ✅ 动态计算的 Gas Limit
427
438
  };
428
439
  const signedTransaction = buildEIP7702TransactionSync(mainWallet, authorizations, calls, totalValue, nonces[mainWalletIndex], feeData, toDexConfig);
429
440
  return {
@@ -57,7 +57,7 @@ export declare const GAS_ESTIMATE: {
57
57
  readonly TRANSFER: 30000n;
58
58
  /** 创建代币额外 gas(普通创建) */
59
59
  readonly CREATE_TOKEN: 500000n;
60
- /** 毕业操作额外 gas(流动性迁移到 DEX,约 800 万) */
60
+ /** 毕业操作额外 gas(流动性迁移到 DEX,需要约 500-800 万) */
61
61
  readonly GRADUATE: 8000000n;
62
62
  /** 最小 gas limit */
63
63
  readonly MIN: 200000n;
@@ -75,7 +75,7 @@ export const GAS_ESTIMATE = {
75
75
  TRANSFER: 30000n,
76
76
  /** 创建代币额外 gas(普通创建) */
77
77
  CREATE_TOKEN: 500000n,
78
- /** 毕业操作额外 gas(流动性迁移到 DEX,约 800 万) */
78
+ /** 毕业操作额外 gas(流动性迁移到 DEX,需要约 500-800 万) */
79
79
  GRADUATE: 8000000n,
80
80
  /** 最小 gas limit */
81
81
  MIN: 200000n,
@@ -338,31 +338,82 @@ export async function batchBuyWithBundleMerkle(params) {
338
338
  fundsList: adjustedFundsList, // ✅ 使用调整后的金额
339
339
  useNativeToken // ✅ USDT 购买时 value=0,BNB 购买时 value=金额
340
340
  });
341
- // ✅ 利润多跳转账(强制 2 跳中转)
341
+ // ✅ 利润多跳转账
342
342
  const profitTxs = [];
343
343
  let profitHopWallets;
344
- if (extractProfit && nativeProfitAmount > 0n && maxFundsIndex >= 0) {
345
- const profitNonce = buyerNonces[maxFundsIndex] + 1;
346
- const profitHopResult = await buildProfitHopTransactions({
347
- provider,
348
- payerWallet: buyers[maxFundsIndex],
349
- profitAmount: nativeProfitAmount,
350
- profitRecipient: getProfitRecipient(),
351
- hopCount: PROFIT_HOP_COUNT,
352
- gasPrice,
353
- chainId,
354
- txType: getTxType(config),
355
- startNonce: profitNonce
356
- });
357
- profitTxs.push(...profitHopResult.signedTransactions);
358
- profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
344
+ // 检查是否使用分布式利润模式
345
+ const profitMode = config.profitMode || 'single';
346
+ if (extractProfit && nativeProfitAmount > 0n) {
347
+ if (profitMode === 'distributed') {
348
+ // ✅ 分布式模式:每个钱包独立扣除自己的利润,每个都有独立的多跳
349
+ // 最多支持 12 个钱包(12 交易 + 36 多跳 + 1 贿赂 = 49 笔)
350
+ const MAX_DISTRIBUTED_WALLETS = 12;
351
+ if (buyers.length > MAX_DISTRIBUTED_WALLETS) {
352
+ throw new Error(`分布式利润模式最多支持 ${MAX_DISTRIBUTED_WALLETS} 个钱包,当前 ${buyers.length} 个`);
353
+ }
354
+ profitHopWallets = [];
355
+ // 计算每个钱包的利润(按比例分配)
356
+ const perWalletProfits = [];
357
+ for (let i = 0; i < buyers.length; i++) {
358
+ const walletOriginalAmount = originalAmounts[i];
359
+ // 按比例计算该钱包应承担的利润
360
+ const walletProfit = totalBuyAmount > 0n
361
+ ? (nativeProfitAmount * walletOriginalAmount) / totalBuyAmount
362
+ : 0n;
363
+ perWalletProfits.push(walletProfit);
364
+ }
365
+ // 为每个钱包生成独立的利润多跳交易
366
+ for (let i = 0; i < buyers.length; i++) {
367
+ const walletProfit = perWalletProfits[i];
368
+ if (walletProfit > 0n) {
369
+ const profitNonce = buyerNonces[i] + 1; // 每个钱包买入后 +1
370
+ const profitHopResult = await buildProfitHopTransactions({
371
+ provider,
372
+ payerWallet: buyers[i],
373
+ profitAmount: walletProfit,
374
+ profitRecipient: getProfitRecipient(),
375
+ hopCount: PROFIT_HOP_COUNT,
376
+ gasPrice,
377
+ chainId,
378
+ txType: getTxType(config),
379
+ startNonce: profitNonce
380
+ });
381
+ profitTxs.push(...profitHopResult.signedTransactions);
382
+ if (profitHopResult.hopWallets) {
383
+ profitHopWallets.push(...profitHopResult.hopWallets);
384
+ }
385
+ }
386
+ }
387
+ }
388
+ else {
389
+ // ✅ 单一模式(默认):从金额最大的钱包统一扣除所有利润
390
+ if (maxFundsIndex >= 0) {
391
+ const profitNonce = buyerNonces[maxFundsIndex] + 1;
392
+ const profitHopResult = await buildProfitHopTransactions({
393
+ provider,
394
+ payerWallet: buyers[maxFundsIndex],
395
+ profitAmount: nativeProfitAmount,
396
+ profitRecipient: getProfitRecipient(),
397
+ hopCount: PROFIT_HOP_COUNT,
398
+ gasPrice,
399
+ chainId,
400
+ txType: getTxType(config),
401
+ startNonce: profitNonce
402
+ });
403
+ profitTxs.push(...profitHopResult.signedTransactions);
404
+ profitHopWallets = profitHopResult.hopWallets;
405
+ }
406
+ }
359
407
  }
360
408
  nonceManager.clearTemp();
361
409
  // ✅ 组装顺序:贿赂 → 买入 → 利润多跳
362
410
  return {
363
411
  signedTransactions: [...bribeTxs, ...signedBuys, ...profitTxs],
364
412
  profitHopWallets, // ✅ 返回利润多跳钱包
365
- metadata: buildProfitMetadata(extractProfit, totalBuyAmount, nativeProfitAmount, buyers.length)
413
+ metadata: {
414
+ ...buildProfitMetadata(extractProfit, totalBuyAmount, nativeProfitAmount, buyers.length),
415
+ profitMode, // ✅ 返回使用的利润模式
416
+ }
366
417
  };
367
418
  }
368
419
  /**
@@ -496,36 +547,83 @@ export async function batchSellWithBundleMerkle(params) {
496
547
  type: getTxType(config),
497
548
  value: 0n // ✅ 卖出交易不发送原生代币
498
549
  })));
499
- // ✅ 利润多跳转账(强制 2 跳中转)
550
+ // ✅ 利润多跳转账
500
551
  const profitTxs = [];
501
552
  let profitHopWallets;
502
- if (needProfitTx && profitNonce !== undefined) {
553
+ // 检查是否使用分布式利润模式
554
+ const profitMode = config.profitMode || 'single';
555
+ if (needProfitTx) {
503
556
  // ERC20 输出时:获取代币利润等值的原生代币(BNB)报价
504
- let nativeProfitAmount = totalTokenProfit;
557
+ let totalNativeProfitAmount = totalTokenProfit;
505
558
  if (!useNativeOutput && outputToken) {
506
- nativeProfitAmount = await getTokenToNativeQuote(provider, outputToken, totalTokenProfit, chainId);
559
+ totalNativeProfitAmount = await getTokenToNativeQuote(provider, outputToken, totalTokenProfit, chainId);
507
560
  }
508
- if (nativeProfitAmount > 0n) {
509
- const profitHopResult = await buildProfitHopTransactions({
510
- provider,
511
- payerWallet: wallets[maxRevenueIndex],
512
- profitAmount: nativeProfitAmount,
513
- profitRecipient: getProfitRecipient(),
514
- hopCount: PROFIT_HOP_COUNT,
515
- gasPrice,
516
- chainId,
517
- txType: getTxType(config),
518
- startNonce: profitNonce
519
- });
520
- profitTxs.push(...profitHopResult.signedTransactions);
521
- profitHopWallets = profitHopResult.hopWallets; // 收集利润多跳钱包
561
+ if (totalNativeProfitAmount > 0n) {
562
+ if (profitMode === 'distributed') {
563
+ // ✅ 分布式模式:每个钱包独立扣除自己的利润,每个都有独立的多跳
564
+ // 最多支持 12 个钱包(12 交易 + 36 多跳 + 1 贿赂 = 49 笔)
565
+ const MAX_DISTRIBUTED_WALLETS = 12;
566
+ if (wallets.length > MAX_DISTRIBUTED_WALLETS) {
567
+ throw new Error(`分布式利润模式最多支持 ${MAX_DISTRIBUTED_WALLETS} 个钱包,当前 ${wallets.length} 个`);
568
+ }
569
+ profitHopWallets = [];
570
+ // 计算每个钱包的利润(按卖出收益比例分配)
571
+ const totalQuoted = quotedOutputs.reduce((sum, q) => sum + q, 0n);
572
+ for (let i = 0; i < wallets.length; i++) {
573
+ const quoted = quotedOutputs[i];
574
+ if (quoted > 0n && totalQuoted > 0n) {
575
+ // 按比例计算该钱包应承担的利润
576
+ const walletProfit = (totalNativeProfitAmount * quoted) / totalQuoted;
577
+ if (walletProfit > 0n) {
578
+ const walletProfitNonce = nonces[i] + 1; // 每个钱包卖出后 +1
579
+ const profitHopResult = await buildProfitHopTransactions({
580
+ provider,
581
+ payerWallet: wallets[i],
582
+ profitAmount: walletProfit,
583
+ profitRecipient: getProfitRecipient(),
584
+ hopCount: PROFIT_HOP_COUNT,
585
+ gasPrice,
586
+ chainId,
587
+ txType: getTxType(config),
588
+ startNonce: walletProfitNonce
589
+ });
590
+ profitTxs.push(...profitHopResult.signedTransactions);
591
+ if (profitHopResult.hopWallets) {
592
+ profitHopWallets.push(...profitHopResult.hopWallets);
593
+ }
594
+ }
595
+ }
596
+ }
597
+ }
598
+ else {
599
+ // ✅ 单一模式(默认):从收益最大的钱包统一扣除所有利润
600
+ if (profitNonce !== undefined) {
601
+ const profitHopResult = await buildProfitHopTransactions({
602
+ provider,
603
+ payerWallet: wallets[maxRevenueIndex],
604
+ profitAmount: totalNativeProfitAmount,
605
+ profitRecipient: getProfitRecipient(),
606
+ hopCount: PROFIT_HOP_COUNT,
607
+ gasPrice,
608
+ chainId,
609
+ txType: getTxType(config),
610
+ startNonce: profitNonce
611
+ });
612
+ profitTxs.push(...profitHopResult.signedTransactions);
613
+ profitHopWallets = profitHopResult.hopWallets;
614
+ }
615
+ }
522
616
  }
523
617
  }
524
618
  nonceManager.clearTemp();
525
619
  // ✅ 组装顺序:贿赂 → 卖出 → 利润多跳
526
620
  return {
527
621
  signedTransactions: [...bribeTxs, ...signedList, ...profitTxs],
528
- profitHopWallets // ✅ 返回利润多跳钱包
622
+ profitHopWallets, // ✅ 返回利润多跳钱包
623
+ metadata: {
624
+ profitMode, // ✅ 返回使用的利润模式
625
+ totalProfit: totalTokenProfit.toString(),
626
+ }
529
627
  };
530
628
  }
531
629
  // ✅ Provider 缓存(复用连接,减少初始化开销)
@@ -1,4 +1,11 @@
1
1
  import type { GeneratedWallet } from '../../utils/wallet.js';
2
+ /**
3
+ * ✅ 利润模式:
4
+ * - 'single': 单一模式(默认),从金额最大的钱包统一扣除所有利润,只有一组多跳交易
5
+ * - 'distributed': 分布式模式,每个钱包独立扣除自己的利润,每个都有独立的多跳交易
6
+ * - 分布式模式最多支持 12 个钱包(12 交易 + 36 多跳 + 1 贿赂 = 49 笔)
7
+ */
8
+ export type FlapProfitMode = 'single' | 'distributed';
2
9
  export type FlapSignConfig = {
3
10
  rpcUrl: string;
4
11
  txType?: 0 | 2;
@@ -9,6 +16,7 @@ export type FlapSignConfig = {
9
16
  nonces?: number[];
10
17
  gasPrice?: bigint;
11
18
  bribeAmount?: number;
19
+ profitMode?: FlapProfitMode;
12
20
  };
13
21
  export type FlapBundleMerkleConfig = {
14
22
  apiKey: string;
package/dist/index.d.ts CHANGED
@@ -27,7 +27,7 @@ export { createTokenWithBundleBuy as fourCreateTokenWithBundleBuy, batchBuyWithB
27
27
  export { createTokenWithBundleBuy as flapCreateTokenWithBundleBuy, batchBuyWithBundle as flapBatchBuyWithBundle, batchSellWithBundle as flapBatchSellWithBundle, type FlapBundleConfig, type FlapChainForBundle, type FlapCreateWithBundleBuyParams, type FlapCreateWithBundleBuyResult, type FlapBatchBuyParams, type FlapBatchBuyResult, type FlapBatchSellParams, type FlapBatchSellResult } from './flap/portal-bundle.js';
28
28
  export { fourPrivateBuy, fourPrivateSell, fourBatchPrivateBuy, fourBatchPrivateSell, type FourPrivateBuyParams, type FourPrivateSellParams, type FourBatchPrivateBuyParams, type FourBatchPrivateSellParams } from './contracts/tm-bundle.js';
29
29
  export { flapPrivateBuy, flapPrivateSell, flapBatchPrivateBuy, flapBatchPrivateSell, type FlapPrivateBuyParams, type FlapPrivateSellParams, type FlapBatchPrivateBuyParams, type FlapBatchPrivateSellParams, type FlapBatchPrivateSellResult } from './flap/portal-bundle.js';
30
- export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle, flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle, pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch, flapDisperseWithBundleMerkle, flapSweepWithBundleMerkle, type FlapBundleMerkleConfig, type FlapSignConfig, type FlapChainForMerkleBundle, type FlapCreateWithBundleBuySignParams, type FlapCreateWithBundleBuyMerkleParams, type FlapCreateWithBundleBuyMerkleResult, type FlapBatchBuySignParams, type FlapBatchBuyMerkleParams, type FlapBatchBuyMerkleResult, type FlapBatchSellSignParams, type FlapBatchSellMerkleParams, type FlapBatchSellMerkleResult, type MerkleTransactionStatus, type MerkleBundleStatus, type FlapPrivateBuyMerkleParams, type FlapPrivateSellMerkleParams, type FlapBatchPrivateBuyMerkleParams, type FlapBatchPrivateSellMerkleParams, type FlapBatchPrivateMerkleResult, type FlapPrivateTransactionResult, type PancakeProxyBatchBuyParams, type PancakeProxyBatchBuyResult, type PancakeProxyBatchSellParams, type PancakeProxyBatchSellResult, type PancakeProxyApprovalParams, type PancakeProxyApprovalBatchParams, type PancakeProxyApprovalBatchResult, type FlapDisperseSignParams, type FlapDisperseMerkleResult, type FlapSweepSignParams, type FlapSweepMerkleResult } from './flap/portal-bundle-merkle/index.js';
30
+ export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle, flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle, pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch, flapDisperseWithBundleMerkle, flapSweepWithBundleMerkle, type FlapBundleMerkleConfig, type FlapSignConfig, type FlapProfitMode, type FlapChainForMerkleBundle, type FlapCreateWithBundleBuySignParams, type FlapCreateWithBundleBuyMerkleParams, type FlapCreateWithBundleBuyMerkleResult, type FlapBatchBuySignParams, type FlapBatchBuyMerkleParams, type FlapBatchBuyMerkleResult, type FlapBatchSellSignParams, type FlapBatchSellMerkleParams, type FlapBatchSellMerkleResult, type MerkleTransactionStatus, type MerkleBundleStatus, type FlapPrivateBuyMerkleParams, type FlapPrivateSellMerkleParams, type FlapBatchPrivateBuyMerkleParams, type FlapBatchPrivateSellMerkleParams, type FlapBatchPrivateMerkleResult, type FlapPrivateTransactionResult, type PancakeProxyBatchBuyParams, type PancakeProxyBatchBuyResult, type PancakeProxyBatchSellParams, type PancakeProxyBatchSellResult, type PancakeProxyApprovalParams, type PancakeProxyApprovalBatchParams, type PancakeProxyApprovalBatchResult, type FlapDisperseSignParams, type FlapDisperseMerkleResult, type FlapSweepSignParams, type FlapSweepMerkleResult } from './flap/portal-bundle-merkle/index.js';
31
31
  export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, pairwiseTransferWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, submitBundleToBlockRazor, submitMultipleBundlesToBlockRazor, submitMultipleBundlesToBlockRazorParallel, type MerkleSubmitConfig, type SubmitBundleResult, type BlockRazorSubmitConfig, type BlockRazorSubmitResult, type FourBundleMerkleConfig, type FourSignConfig, type FourCreateWithBundleBuySignParams, type FourBatchBuySignParams, type FourBatchSellSignParams, type FourPrivateBuySignParams, type FourPrivateSellSignParams, type FourBatchPrivateBuySignParams, type FourBatchPrivateSellSignParams, type FourPancakeProxyBatchBuySignParams, type FourPancakeProxyBatchSellSignParams, type DisperseSignParams as FourDisperseSignParams, type SweepSignParams as FourSweepSignParams, type FourCreateWithBundleBuyMerkleParams, type FourCreateWithBundleBuyMerkleResult, type FourBatchBuyMerkleParams, type FourBatchBuyMerkleResult, type FourBatchSellMerkleParams, type FourBatchSellMerkleResult, type FourPrivateBuyMerkleParams, type FourPrivateSellMerkleParams, type FourBatchPrivateBuyMerkleParams, type FourBatchPrivateSellMerkleParams, type FourBatchPrivateMerkleResult, type FourPrivateTransactionResult, type DisperseMerkleParams, type DisperseMerkleResult, type SweepMerkleParams, type SweepMerkleResult, type FourPancakeProxyBatchBuyParams, type FourPancakeProxyBatchBuyResult, type FourPancakeProxyBatchSellParams, type FourPancakeProxyBatchSellResult, type FourPancakeProxyApprovalParams, type FourPancakeProxyApprovalBatchParams, type FourPancakeProxyApprovalBatchResult, type ApproveFourTokenManagerBatchParams, type ApproveFourTokenManagerBatchResult } from './contracts/tm-bundle-merkle/index.js';
32
32
  export { PinataClient, type PinataConfig } from './flap/pinata.js';
33
33
  export { pinFileToIPFSWithJWT, pinImageByPath, pinFileToIPFSWithJWTWeb, pinDataURLWithJWTWeb, dataURLToBlob, type PinataPinResp } from './flap/pinata.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.7.71",
3
+ "version": "1.7.73",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",