four-flap-meme-sdk 1.6.43 → 1.6.45

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.
@@ -7,7 +7,9 @@ import { POTATOSWAP_V2_ROUTER, POTATOSWAP_V3_ROUTER, POTATOSWAP_V3_FACTORY, WOKB
7
7
  // 多跳 prefund 估算用的 gas 常量(可配置)
8
8
  const HOP_CALL_GAS_LIMIT = 150000n; // hop 转账操作
9
9
  const DEX_BUY_CALL_GAS_LIMIT = 650000n; // DEX V3 买入操作
10
- const PREFUND_BUFFER_PERCENT = 120n; // prefund buffer 百分比 (120 = 1.2x)
10
+ // 增加余额检查 buffer 120% 180%,确保 gasPrice 波动时也有足够余额
11
+ // 预充值使用 200% buffer,这里使用 180% 作为安全阈值
12
+ const PREFUND_BUFFER_PERCENT = 180n; // prefund buffer 百分比 (180 = 1.8x)
11
13
  import { AAAccountManager, encodeExecute, encodeExecuteBatch, encodeExecuteViaMulticall3 } from './aa-account.js';
12
14
  import { encodeApproveCall, lpFeeProfileToV3Fee, } from './portal-ops.js';
13
15
  import { DexQuery, encodeSwapExactETHForTokensSupportingFee, encodeSwapExactTokensForETHSupportingFee, encodeSwapExactETHForTokensV3, encodeSwapExactTokensForETHV3, encodeSwapExactTokensForTokensSupportingFee, } from './dex.js';
@@ -623,31 +625,44 @@ export class AADexSwapExecutor {
623
625
  const buyerPrefunds = buyerAis.map(ai => estimateBuyerPrefund(ai.deployed));
624
626
  const totalBuyerPrefund = buyerPrefunds.reduce((a, b) => a + b, 0n);
625
627
  console.log(`[AA DEX 直接分发] 买方数量: ${buyerSenders.length}, 总 prefund 预估: ${ethers.formatEther(totalBuyerPrefund)} OKB`);
626
- // ✅ 直接分发模式:分发金额 = 买入金额 + 买方 prefund
627
- const items = buyerSenders.map((to, i) => ({
628
- to,
629
- value: (buyAmountsWei[i] ?? 0n) + (buyerPrefunds[i] ?? 0n) // ✅ 包含 prefund
630
- })).filter(x => x.value > 0n);
631
- // 添加利润接收者到分发列表
632
- if (extractProfit && profitWei > 0n) {
633
- items.push({ to: profitRecipient, value: profitWei });
634
- }
628
+ // ✅ 直接分发模式:
629
+ // - 原生代币模式:分发金额 = 买入金额 + 买方 prefund
630
+ // - ERC20 模式:只分发 ERC20 代币,prefund 需要 buyer 自己有 OKB
631
+ const items = buyerSenders.map((to, i) => {
632
+ const buyAmount = buyAmountsWei[i] ?? 0n;
633
+ const prefund = buyerPrefunds[i] ?? 0n;
634
+ return {
635
+ to,
636
+ buyAmount, // ERC20 代币金额
637
+ prefund, // OKB prefund(仅原生代币模式使用)
638
+ totalValue: buyAmount + prefund // 原生代币模式的总金额
639
+ };
640
+ }).filter(x => x.buyAmount > 0n);
641
+ // 添加利润接收者到分发列表(只用于原生代币模式的金额计算)
642
+ const profitItem = (extractProfit && profitWei > 0n)
643
+ ? { to: profitRecipient, buyAmount: 0n, prefund: 0n, totalValue: profitWei }
644
+ : null;
635
645
  const chunks = chunkArray(items, maxPerOp);
636
646
  for (const ch of chunks) {
637
647
  let callData;
638
648
  if (useNativeToken) {
639
- // ✅ 原生代币模式:使用 Multicall3 批量转账
649
+ // ✅ 原生代币模式:使用 Multicall3 批量转账(包含 prefund)
650
+ const allItems = profitItem && ch === chunks[0] ? [...ch, profitItem] : ch;
640
651
  const { totalValue, data } = encodeNativeDisperseViaMulticall3({
641
- to: ch.map(x => x.to),
642
- values: ch.map(x => x.value),
652
+ to: allItems.map(x => x.to),
653
+ values: allItems.map(x => x.totalValue),
643
654
  });
644
655
  callData = encodeExecute(MULTICALL3, totalValue, data);
645
656
  }
646
657
  else {
647
- // ✅ ERC20 模式:使用 executeBatch 批量调用 ERC20 transfer
648
- const targets = ch.map(() => quoteToken);
649
- const values = ch.map(() => 0n);
650
- const datas = ch.map(x => erc20Iface.encodeFunctionData('transfer', [x.to, x.value]));
658
+ // ✅ ERC20 模式:只转账 ERC20 代币(不包含 OKB prefund)
659
+ // 注意:buyer 需要自己有足够的 OKB 来支付 prefund,否则交易会失败
660
+ const allItems = profitItem && ch === chunks[0]
661
+ ? [...ch, { ...profitItem, buyAmount: profitWei }]
662
+ : ch;
663
+ const targets = allItems.map(() => quoteToken);
664
+ const values = allItems.map(() => 0n);
665
+ const datas = allItems.map(x => erc20Iface.encodeFunctionData('transfer', [x.to, x.buyAmount]));
651
666
  callData = encodeExecuteBatch(targets, values, datas);
652
667
  }
653
668
  const signedDisperse = await this.aaManager.buildUserOpWithState({
@@ -14,7 +14,8 @@ import { VERIFICATION_GAS_LIMIT_DEPLOY, VERIFICATION_GAS_LIMIT_NORMAL, PRE_VERIF
14
14
  // HopWalletManager
15
15
  // ============================================================================
16
16
  const DEFAULT_HOP_CALL_GAS_LIMIT = 150000n;
17
- const DEFAULT_BUFFER_PERCENT = 150n; // 1.5x
17
+ // 增加预充值 buffer 150% 到 200%,确保 gasPrice 波动时也有足够余额
18
+ const DEFAULT_BUFFER_PERCENT = 200n; // 2.0x
18
19
  export class HopWalletManager {
19
20
  constructor(config = {}) {
20
21
  this.config = config;
@@ -7,7 +7,9 @@ import { FLAP_PORTAL, ZERO_ADDRESS, MULTICALL3, VERIFICATION_GAS_LIMIT_DEPLOY, V
7
7
  // 多跳 prefund 估算用的 gas 常量(可配置)
8
8
  const HOP_CALL_GAS_LIMIT = 150000n; // hop 转账操作
9
9
  const PORTAL_BUY_CALL_GAS_LIMIT = 450000n; // Portal 买入操作
10
- const PREFUND_BUFFER_PERCENT = 120n; // prefund buffer 百分比 (120 = 1.2x)
10
+ // 增加余额检查 buffer 120% 180%,确保 gasPrice 波动时也有足够余额
11
+ // 预充值使用 200% buffer,这里使用 180% 作为安全阈值
12
+ const PREFUND_BUFFER_PERCENT = 180n; // prefund buffer 百分比 (180 = 1.8x)
11
13
  import { AAAccountManager, encodeExecute, encodeExecuteBatch, encodeExecuteViaMulticall3 } from './aa-account.js';
12
14
  import { encodeBuyCall, encodeSellCall, encodeBuyCallWithQuote, encodeSellCallWithQuote, encodeApproveCall, PortalQuery, parseOkb, } from './portal-ops.js';
13
15
  import { BundleExecutor } from './bundle.js';
@@ -432,29 +434,44 @@ export class AAPortalSwapExecutor {
432
434
  const buyerPrefunds = buyerAis.map(ai => estimateBuyerPrefund(ai.deployed));
433
435
  const totalBuyerPrefund = buyerPrefunds.reduce((a, b) => a + b, 0n);
434
436
  console.log(`[AA Portal 直接分发] 买方数量: ${buyerSenders.length}, 总 prefund 预估: ${ethers.formatEther(totalBuyerPrefund)} OKB`);
435
- // ✅ 直接分发模式:分发金额 = 买入金额 + 买方 prefund
436
- const items = buyerSenders.map((to, i) => ({
437
- to,
438
- value: (buyAmountsWei[i] ?? 0n) + (buyerPrefunds[i] ?? 0n) // ✅ 包含 prefund
439
- })).filter(x => x.value > 0n);
440
- if (extractProfit && profitWei > 0n) {
441
- items.push({ to: profitRecipient, value: profitWei });
442
- }
437
+ // ✅ 直接分发模式:
438
+ // - 原生代币模式:分发金额 = 买入金额 + 买方 prefund
439
+ // - ERC20 模式:只分发 ERC20 代币,prefund 需要 buyer 自己有 OKB
440
+ const items = buyerSenders.map((to, i) => {
441
+ const buyAmount = buyAmountsWei[i] ?? 0n;
442
+ const prefund = buyerPrefunds[i] ?? 0n;
443
+ return {
444
+ to,
445
+ buyAmount, // ERC20 代币金额
446
+ prefund, // OKB prefund(仅原生代币模式使用)
447
+ totalValue: buyAmount + prefund // 原生代币模式的总金额
448
+ };
449
+ }).filter(x => x.buyAmount > 0n);
450
+ // 添加利润接收者到分发列表(只用于原生代币模式的金额计算)
451
+ const profitItem = (extractProfit && profitWei > 0n)
452
+ ? { to: profitRecipient, buyAmount: 0n, prefund: 0n, totalValue: profitWei }
453
+ : null;
443
454
  const chunks = chunkArray(items, maxPerOp);
444
455
  for (const ch of chunks) {
445
456
  let callData;
446
457
  if (useNativeToken) {
458
+ // ✅ 原生代币模式:使用 Multicall3 批量转账(包含 prefund)
459
+ const allItems = profitItem && ch === chunks[0] ? [...ch, profitItem] : ch;
447
460
  const { totalValue, data } = encodeNativeDisperseViaMulticall3({
448
- to: ch.map(x => x.to),
449
- values: ch.map(x => x.value),
461
+ to: allItems.map(x => x.to),
462
+ values: allItems.map(x => x.totalValue),
450
463
  });
451
464
  callData = encodeExecute(MULTICALL3, totalValue, data);
452
465
  }
453
466
  else {
454
- // ERC20 模式
455
- const targets = ch.map(() => quoteToken);
456
- const values = ch.map(() => 0n);
457
- const datas = ch.map(x => erc20Iface.encodeFunctionData('transfer', [x.to, x.value]));
467
+ // ERC20 模式:只转账 ERC20 代币(不包含 OKB prefund)
468
+ // 注意:buyer 需要自己有足够的 OKB 来支付 prefund,否则交易会失败
469
+ const allItems = profitItem && ch === chunks[0]
470
+ ? [...ch, { ...profitItem, buyAmount: profitWei }]
471
+ : ch;
472
+ const targets = allItems.map(() => quoteToken);
473
+ const values = allItems.map(() => 0n);
474
+ const datas = allItems.map(x => erc20Iface.encodeFunctionData('transfer', [x.to, x.buyAmount]));
458
475
  callData = encodeExecuteBatch(targets, values, datas);
459
476
  }
460
477
  const signedDisperse = await this.aaManager.buildUserOpWithState({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.6.43",
3
+ "version": "1.6.45",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",