four-flap-meme-sdk 1.5.83 → 1.5.84

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.
@@ -1551,7 +1551,7 @@ export class BundleExecutor {
1551
1551
  * 自动计算剩余毕业容量,将钱包分为内盘和外盘组,生成签名的交易列表
1552
1552
  */
1553
1553
  async bundleGraduateBuy(params) {
1554
- const { tokenAddress, privateKeys, payerPrivateKey, amountMode, totalBuyAmount, minAmount, maxAmount, walletAmounts, enableDexBuy = false, config = {} } = params;
1554
+ const { tokenAddress, privateKeys, payerPrivateKey, amountMode, totalBuyAmount, minAmount, maxAmount, walletAmounts, enableDexBuy = false, config = {}, graduationAmount, curveAddresses, dexAddresses } = params;
1555
1555
  const aaManager = this.getAAManager();
1556
1556
  const provider = aaManager.getProvider();
1557
1557
  // 1. 获取代币状态,动态计算毕业容量
@@ -1572,9 +1572,12 @@ export class BundleExecutor {
1572
1572
  graduationReserveWei = denom > 0n ? (tokenState.k * 10n ** 18n) / denom - tokenState.r : 0n;
1573
1573
  }
1574
1574
  // 剩余毕业金额 = 毕业阈值 - 当前储备(加 1.6% 手续费缓冲以覆盖 1.5% 平台费)
1575
- const remainingToGraduateWei = (tokenState.status === 4 || graduationReserveWei <= tokenState.reserve)
1576
- ? 0n
1577
- : ((graduationReserveWei - tokenState.reserve) * 1016n / 1000n);
1575
+ // 优先使用前端传入的 graduationAmount
1576
+ const remainingToGraduateWei = graduationAmount !== undefined
1577
+ ? ethers.parseEther(graduationAmount.toString())
1578
+ : ((tokenState.status === 4 || graduationReserveWei <= tokenState.reserve)
1579
+ ? 0n
1580
+ : ((graduationReserveWei - tokenState.reserve) * 1016n / 1000n));
1578
1581
  const graduationReserveStr = ethers.formatEther(graduationReserveWei);
1579
1582
  const poolReserveOkbStr = ethers.formatEther(tokenState.reserve);
1580
1583
  const remainingStr = ethers.formatEther(remainingToGraduateWei);
@@ -1611,71 +1614,111 @@ export class BundleExecutor {
1611
1614
  const amountWei = ethers.parseEther(finalAmounts[i].toFixed(18));
1612
1615
  const tasks = [];
1613
1616
  let isTrigger = false;
1614
- if (currentCurveTotal < remainingToGraduateWei) {
1615
- const needed = remainingToGraduateWei - currentCurveTotal;
1616
- if (amountWei <= needed) {
1617
- // 情况 A:全在内盘
1618
- tasks.push({
1619
- target: FLAP_PORTAL,
1620
- amount: amountWei,
1621
- data: encodeBuyCall(tokenAddress, amountWei, 0n)
1622
- });
1623
- currentCurveTotal += amountWei;
1624
- if (currentCurveTotal >= remainingToGraduateWei)
1625
- isTrigger = true;
1626
- }
1627
- else {
1628
- // 情况 B:跨内外盘(原子化拆分)
1629
- tasks.push({
1630
- target: FLAP_PORTAL,
1631
- amount: needed,
1632
- data: encodeBuyCall(tokenAddress, needed, 0n)
1633
- });
1634
- isTrigger = true; // 肯定是毕业触发者
1635
- currentCurveTotal = remainingToGraduateWei;
1636
- if (enableDexBuy) {
1637
- const excess = amountWei - needed;
1638
- const dexType = (tokenState.lpFeeProfile >= 0 && tokenState.tokenVersion >= 4) ? 'V3' : 'V2';
1639
- const deadline = Math.floor(Date.now() / 1000) + 1200;
1640
- let swapData;
1641
- let routerAddress;
1642
- if (dexType === 'V3') {
1643
- routerAddress = POTATOSWAP_V3_ROUTER;
1644
- swapData = encodeSwapExactETHForTokensV3({
1645
- tokenIn: WOKB, tokenOut: tokenAddress,
1646
- fee: lpFeeProfileToV3Fee(tokenState.lpFeeProfile),
1647
- recipient: ZERO_ADDRESS, // AA 内部 call,最终由 execute/executeBatch 决定 recipient
1648
- deadline, amountIn: excess, amountOutMinimum: 0n, sqrtPriceLimitX96: 0n
1649
- });
1650
- }
1651
- else {
1652
- routerAddress = POTATOSWAP_V2_ROUTER;
1653
- swapData = encodeSwapExactETHForTokensSupportingFee(0n, [WOKB, tokenAddress], ZERO_ADDRESS, deadline);
1654
- }
1655
- tasks.push({ target: routerAddress, amount: excess, data: swapData });
1617
+ // 优先判断地址分组(由前端强制指定)
1618
+ const forceCurve = curveAddresses?.some(a => a.toLowerCase() === wallet.address.toLowerCase());
1619
+ const forceDex = dexAddresses?.some(a => a.toLowerCase() === wallet.address.toLowerCase());
1620
+ if (forceCurve) {
1621
+ // 强制内盘
1622
+ tasks.push({
1623
+ target: FLAP_PORTAL,
1624
+ amount: amountWei,
1625
+ data: encodeBuyCall(tokenAddress, amountWei, 0n)
1626
+ });
1627
+ currentCurveTotal += amountWei;
1628
+ if (currentCurveTotal >= remainingToGraduateWei)
1629
+ isTrigger = true;
1630
+ }
1631
+ else if (forceDex) {
1632
+ // 强制外盘
1633
+ if (enableDexBuy) {
1634
+ const dexType = (tokenState.lpFeeProfile >= 0 && tokenState.tokenVersion >= 4) ? 'V3' : 'V2';
1635
+ const deadline = Math.floor(Date.now() / 1000) + 1200;
1636
+ let swapData;
1637
+ let routerAddress;
1638
+ if (dexType === 'V3') {
1639
+ routerAddress = POTATOSWAP_V3_ROUTER;
1640
+ swapData = encodeSwapExactETHForTokensV3({
1641
+ tokenIn: WOKB, tokenOut: tokenAddress,
1642
+ fee: lpFeeProfileToV3Fee(tokenState.lpFeeProfile),
1643
+ recipient: ZERO_ADDRESS,
1644
+ deadline, amountIn: amountWei, amountOutMinimum: 0n, sqrtPriceLimitX96: 0n
1645
+ });
1646
+ }
1647
+ else {
1648
+ routerAddress = POTATOSWAP_V2_ROUTER;
1649
+ swapData = encodeSwapExactETHForTokensSupportingFee(0n, [WOKB, tokenAddress], ZERO_ADDRESS, deadline);
1656
1650
  }
1651
+ tasks.push({ target: routerAddress, amount: amountWei, data: swapData });
1657
1652
  }
1658
1653
  }
1659
- else if (enableDexBuy) {
1660
- // 情况 C:全在外盘
1661
- const dexType = (tokenState.lpFeeProfile >= 0 && tokenState.tokenVersion >= 4) ? 'V3' : 'V2';
1662
- const deadline = Math.floor(Date.now() / 1000) + 1200;
1663
- let swapData;
1664
- let routerAddress;
1665
- if (dexType === 'V3') {
1666
- routerAddress = POTATOSWAP_V3_ROUTER;
1667
- swapData = encodeSwapExactETHForTokensV3({
1668
- tokenIn: WOKB, tokenOut: tokenAddress,
1669
- fee: lpFeeProfileToV3Fee(tokenState.lpFeeProfile),
1670
- recipient: ZERO_ADDRESS,
1671
- deadline, amountIn: amountWei, amountOutMinimum: 0n, sqrtPriceLimitX96: 0n
1672
- });
1654
+ else {
1655
+ // 兜底逻辑:自动分配 (无强制分组)
1656
+ if (currentCurveTotal < remainingToGraduateWei) {
1657
+ const needed = remainingToGraduateWei - currentCurveTotal;
1658
+ if (amountWei <= needed) {
1659
+ // 情况 A:全在内盘
1660
+ tasks.push({
1661
+ target: FLAP_PORTAL,
1662
+ amount: amountWei,
1663
+ data: encodeBuyCall(tokenAddress, amountWei, 0n)
1664
+ });
1665
+ currentCurveTotal += amountWei;
1666
+ if (currentCurveTotal >= remainingToGraduateWei)
1667
+ isTrigger = true;
1668
+ }
1669
+ else {
1670
+ // 情况 B:跨内外盘(原子化拆分)
1671
+ tasks.push({
1672
+ target: FLAP_PORTAL,
1673
+ amount: needed,
1674
+ data: encodeBuyCall(tokenAddress, needed, 0n)
1675
+ });
1676
+ isTrigger = true;
1677
+ currentCurveTotal = remainingToGraduateWei;
1678
+ if (enableDexBuy) {
1679
+ const excess = amountWei - needed;
1680
+ const dexType = (tokenState.lpFeeProfile >= 0 && tokenState.tokenVersion >= 4) ? 'V3' : 'V2';
1681
+ const deadline = Math.floor(Date.now() / 1000) + 1200;
1682
+ let swapData;
1683
+ let routerAddress;
1684
+ if (dexType === 'V3') {
1685
+ routerAddress = POTATOSWAP_V3_ROUTER;
1686
+ swapData = encodeSwapExactETHForTokensV3({
1687
+ tokenIn: WOKB, tokenOut: tokenAddress,
1688
+ fee: lpFeeProfileToV3Fee(tokenState.lpFeeProfile),
1689
+ recipient: ZERO_ADDRESS,
1690
+ deadline, amountIn: excess, amountOutMinimum: 0n, sqrtPriceLimitX96: 0n
1691
+ });
1692
+ }
1693
+ else {
1694
+ routerAddress = POTATOSWAP_V2_ROUTER;
1695
+ swapData = encodeSwapExactETHForTokensSupportingFee(0n, [WOKB, tokenAddress], ZERO_ADDRESS, deadline);
1696
+ }
1697
+ tasks.push({ target: routerAddress, amount: excess, data: swapData });
1698
+ }
1699
+ }
1673
1700
  }
1674
- else {
1675
- routerAddress = POTATOSWAP_V2_ROUTER;
1676
- swapData = encodeSwapExactETHForTokensSupportingFee(0n, [WOKB, tokenAddress], ZERO_ADDRESS, deadline);
1701
+ else if (enableDexBuy) {
1702
+ // 情况 C:全在外盘
1703
+ const dexType = (tokenState.lpFeeProfile >= 0 && tokenState.tokenVersion >= 4) ? 'V3' : 'V2';
1704
+ const deadline = Math.floor(Date.now() / 1000) + 1200;
1705
+ let swapData;
1706
+ let routerAddress;
1707
+ if (dexType === 'V3') {
1708
+ routerAddress = POTATOSWAP_V3_ROUTER;
1709
+ swapData = encodeSwapExactETHForTokensV3({
1710
+ tokenIn: WOKB, tokenOut: tokenAddress,
1711
+ fee: lpFeeProfileToV3Fee(tokenState.lpFeeProfile),
1712
+ recipient: ZERO_ADDRESS,
1713
+ deadline, amountIn: amountWei, amountOutMinimum: 0n, sqrtPriceLimitX96: 0n
1714
+ });
1715
+ }
1716
+ else {
1717
+ routerAddress = POTATOSWAP_V2_ROUTER;
1718
+ swapData = encodeSwapExactETHForTokensSupportingFee(0n, [WOKB, tokenAddress], ZERO_ADDRESS, deadline);
1719
+ }
1720
+ tasks.push({ target: routerAddress, amount: amountWei, data: swapData });
1677
1721
  }
1678
- tasks.push({ target: routerAddress, amount: amountWei, data: swapData });
1679
1722
  }
1680
1723
  if (tasks.length > 0) {
1681
1724
  buyerTasks.push({ wallet, calls: tasks, isGraduationTrigger: isTrigger });
@@ -69,7 +69,7 @@ export declare const ENTRYPOINT_ABI: readonly ["function getNonce(address sender
69
69
  /** SimpleAccount ABI */
70
70
  export declare const SIMPLE_ACCOUNT_ABI: readonly ["function execute(address dest, uint256 value, bytes func) external", "function executeBatch(address[] calldata dest, bytes[] calldata func) external", "function executeBatch(address[] calldata dest, uint256[] calldata values, bytes[] calldata func) external"];
71
71
  /** Flap Portal ABI */
72
- export declare const PORTAL_ABI: readonly ["function swapExactInput((address inputToken,address outputToken,uint256 inputAmount,uint256 minOutputAmount,bytes permitData) params) payable returns (uint256)", "function buy(address token, address to, uint256 minAmount) external payable returns (uint256)", "function sell(address token, uint256 amount, uint256 minEth) external returns (uint256)", "function quoteExactInput((address inputToken,address outputToken,uint256 inputAmount)) external returns (uint256)", "function previewBuy(address token, uint256 ethAmount) external view returns (uint256)", "function previewSell(address token, uint256 tokenAmount) external view returns (uint256)", "function getTokenV5(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32))", "function getTokenV7(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32,uint256,address,uint256,uint8))", "function newTokenV2((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData) params) external payable returns (address)", "function newTokenV3((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData,bytes32 extensionID,bytes extensionData) params) external payable returns (address)", "function newTokenV4((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData,bytes32 extensionID,bytes extensionData,uint8 dexId,uint8 lpFeeProfile) params) external payable returns (address)"];
72
+ export declare const PORTAL_ABI: readonly ["function swapExactInput((address inputToken,address outputToken,uint256 inputAmount,uint256 minOutputAmount,bytes permitData) params) payable returns (uint256)", "function buy(address token, address to, uint256 minAmount) external payable returns (uint256)", "function sell(address token, uint256 amount, uint256 minEth) external returns (uint256)", "function quoteExactInput((address inputToken,address outputToken,uint256 inputAmount)) external returns (uint256)", "function previewBuy(address token, uint256 ethAmount) external view returns (uint256)", "function previewSell(address token, uint256 tokenAmount) external view returns (uint256)", "function getTokenV5(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32))", "function getTokenV7(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32,uint256,address,uint256,uint8,uint8))", "function newTokenV2((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData) params) external payable returns (address)", "function newTokenV3((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData,bytes32 extensionID,bytes extensionData) params) external payable returns (address)", "function newTokenV4((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData,bytes32 extensionID,bytes extensionData,uint8 dexId,uint8 lpFeeProfile) params) external payable returns (address)"];
73
73
  /** ERC20 ABI */
74
74
  export declare const ERC20_ABI: readonly ["function balanceOf(address account) view returns (uint256)", "function allowance(address owner, address spender) view returns (uint256)", "function approve(address spender, uint256 amount) returns (bool)", "function transfer(address to, uint256 amount) returns (bool)", "function decimals() view returns (uint8)", "function symbol() view returns (string)", "function name() view returns (string)"];
75
75
  /** PotatoSwap V2 Router ABI */
@@ -113,7 +113,7 @@ export const PORTAL_ABI = [
113
113
  'function previewBuy(address token, uint256 ethAmount) external view returns (uint256)',
114
114
  'function previewSell(address token, uint256 tokenAmount) external view returns (uint256)',
115
115
  'function getTokenV5(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32))',
116
- 'function getTokenV7(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32,uint256,address,uint256,uint8))',
116
+ 'function getTokenV7(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32,uint256,address,uint256,uint8,uint8))',
117
117
  'function newTokenV2((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData) params) external payable returns (address)',
118
118
  'function newTokenV3((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData,bytes32 extensionID,bytes extensionData) params) external payable returns (address)',
119
119
  'function newTokenV4((string name,string symbol,string meta,uint8 dexThresh,bytes32 salt,uint16 taxRate,uint8 migratorType,address quoteToken,uint256 quoteAmt,address beneficiary,bytes permitData,bytes32 extensionID,bytes extensionData,uint8 dexId,uint8 lpFeeProfile) params) external payable returns (address)',
@@ -185,6 +185,7 @@ export declare class PortalQuery {
185
185
  pool: string;
186
186
  progress: bigint;
187
187
  lpFeeProfile: number;
188
+ dexId: number;
188
189
  }>;
189
190
  /**
190
191
  * 批量获取多个账户的代币余额
@@ -220,6 +220,7 @@ export class PortalQuery {
220
220
  pool: raw[13],
221
221
  progress: raw[14],
222
222
  lpFeeProfile: Number(raw[15]),
223
+ dexId: Number(raw[16]),
223
224
  };
224
225
  }
225
226
  /**
@@ -868,6 +868,12 @@ export interface BundleGraduateBuyParams {
868
868
  payerStartNonce?: number;
869
869
  /** beneficiary(默认 payer 地址) */
870
870
  beneficiary?: string;
871
+ /** 毕业剩余量覆盖 (OKB 数值,不传则自动探测) */
872
+ graduationAmount?: number;
873
+ /** 预设内盘钱包地址列表 (若提供则强制按此分组) */
874
+ curveAddresses?: string[];
875
+ /** 预设外盘钱包地址列表 (若提供则强制按此分组) */
876
+ dexAddresses?: string[];
871
877
  }
872
878
  /**
873
879
  * 捆绑买到毕业签名结果
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.5.83",
3
+ "version": "1.5.84",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",