four-flap-meme-sdk 1.5.35 → 1.5.36

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.
package/dist/index.d.ts CHANGED
@@ -53,4 +53,4 @@ export { submitDirectToRpc, submitDirectToRpcSequential, // ✅ 新增:顺序
53
53
  submitDirectToRpcParallel, type DirectSubmitConfig, type DirectSubmitResult, type DirectTxResult } from './contracts/tm-bundle-merkle/submit.js';
54
54
  export { directV2BatchBuy, directV2BatchSell, directV3BatchBuy, directV3BatchSell, getRouterAddress, DIRECT_ROUTERS, type DirectV2BuyParams, type DirectV2SellParams, type DirectV3BuyParams, type DirectV3SellParams, type DirectRouterResult, type DirectRouterSignConfig, type DexKey, type RouterVersion, } from './dex/index.js';
55
55
  export * as XLayer from './xlayer/index.js';
56
- export { bundleBuy as xlayerBundleBuy, bundleSell as xlayerBundleSell, bundleBuySell as xlayerBundleBuySell, bundleSwapSign as xlayerBundleSwapSign, bundleBatchSwapSign as xlayerBundleBatchSwapSign, createBundleExecutor as xlayerCreateBundleExecutor, BundleExecutor as XLayerBundleExecutor, makeVolume as xlayerMakeVolume, singleRoundVolume as xlayerSingleRoundVolume, createVolumeExecutor as xlayerCreateVolumeExecutor, VolumeExecutor as XLayerVolumeExecutor, makeBuyFirstVolume as xlayerMakeBuyFirstVolume, BuyFirstVolumeExecutor as XLayerBuyFirstVolumeExecutor, AAPortalBuyFirstExecutor as XLayerAAPortalBuyFirstExecutor, AADexBuyFirstExecutor as XLayerAADexBuyFirstExecutor, createDexExecutor as xlayerCreateDexExecutor, createDexQuery as xlayerCreateDexQuery, quoteOkbToToken as xlayerQuoteOkbToToken, quoteTokenToOkb as xlayerQuoteTokenToOkb, DexExecutor as XLayerDexExecutor, DexQuery as XLayerDexQuery, createAAAccountManager as xlayerCreateAAAccountManager, predictSender as xlayerPredictSender, createWallet as xlayerCreateWallet, AAAccountManager as XLayerAAAccountManager, generateAAWallets as xlayerGenerateAAWallets, generateAAWalletsFromMnemonic as xlayerGenerateAAWalletsFromMnemonic, predictSendersFromPrivateKeys as xlayerPredictSendersFromPrivateKeys, createBundlerClient as xlayerCreateBundlerClient, BundlerClient as XLayerBundlerClient, createPortalQuery as xlayerCreatePortalQuery, PortalQuery as XLayerPortalQuery, encodeBuyCall as xlayerEncodeBuyCall, encodeSellCall as xlayerEncodeSellCall, encodeApproveCall as xlayerEncodeApproveCall, parseOkb as xlayerParseOkb, formatOkb as xlayerFormatOkb, XLAYER_CHAIN_ID, FLAP_PORTAL as XLAYER_FLAP_PORTAL, ENTRYPOINT_V06 as XLAYER_ENTRYPOINT, SIMPLE_ACCOUNT_FACTORY as XLAYER_FACTORY, PARTICLE_BUNDLER_URL as XLAYER_BUNDLER_URL, WOKB as XLAYER_WOKB, POTATOSWAP_V2_ROUTER as XLAYER_POTATOSWAP_ROUTER, type XLayerConfig, type BundleBuyParams as XLayerBundleBuyParams, type BundleSellParams as XLayerBundleSellParams, type BundleBuySellParams as XLayerBundleBuySellParams, type BundleSwapParams as XLayerBundleSwapParams, type BundleSwapSignParams as XLayerBundleSwapSignParams, type BundleBatchSwapParams as XLayerBundleBatchSwapParams, type BundleBatchSwapSignParams as XLayerBundleBatchSwapSignParams, type VolumeParams as XLayerVolumeParams, type BundleBuyResult as XLayerBundleBuyResult, type BundleSellResult as XLayerBundleSellResult, type BundleBuySellResult as XLayerBundleBuySellResult, type BundleSwapResult as XLayerBundleSwapResult, type BundleSwapSignResult as XLayerBundleSwapSignResult, type BundleBatchSwapResult as XLayerBundleBatchSwapResult, type BundleBatchSwapSignResult as XLayerBundleBatchSwapSignResult, type VolumeResult as XLayerVolumeResult, type BuyFirstParams as XLayerBuyFirstParams, type BuyFirstResult as XLayerBuyFirstResult, type BuyFirstVolumeParams as XLayerBuyFirstVolumeParams, type BuyFirstVolumeResult as XLayerBuyFirstVolumeResult, type HandleOpsResult as XLayerHandleOpsResult, type AAAccount as XLayerAAAccount, type UserOperation as XLayerUserOperation, type GeneratedAAWallet as XLayerGeneratedAAWallet, type GenerateAAWalletsParams as XLayerGenerateAAWalletsParams, type GenerateAAWalletsResult as XLayerGenerateAAWalletsResult, } from './xlayer/index.js';
56
+ export { bundleBuy as xlayerBundleBuy, bundleSell as xlayerBundleSell, bundleBuySell as xlayerBundleBuySell, bundleCreateBuy as xlayerBundleCreateBuy, bundleCreateBuySign as xlayerBundleCreateBuySign, bundleSwapSign as xlayerBundleSwapSign, bundleBatchSwapSign as xlayerBundleBatchSwapSign, createBundleExecutor as xlayerCreateBundleExecutor, BundleExecutor as XLayerBundleExecutor, makeVolume as xlayerMakeVolume, singleRoundVolume as xlayerSingleRoundVolume, createVolumeExecutor as xlayerCreateVolumeExecutor, VolumeExecutor as XLayerVolumeExecutor, makeBuyFirstVolume as xlayerMakeBuyFirstVolume, BuyFirstVolumeExecutor as XLayerBuyFirstVolumeExecutor, AAPortalBuyFirstExecutor as XLayerAAPortalBuyFirstExecutor, AADexBuyFirstExecutor as XLayerAADexBuyFirstExecutor, createDexExecutor as xlayerCreateDexExecutor, createDexQuery as xlayerCreateDexQuery, quoteOkbToToken as xlayerQuoteOkbToToken, quoteTokenToOkb as xlayerQuoteTokenToOkb, DexExecutor as XLayerDexExecutor, DexQuery as XLayerDexQuery, createAAAccountManager as xlayerCreateAAAccountManager, predictSender as xlayerPredictSender, createWallet as xlayerCreateWallet, AAAccountManager as XLayerAAAccountManager, generateAAWallets as xlayerGenerateAAWallets, generateAAWalletsFromMnemonic as xlayerGenerateAAWalletsFromMnemonic, predictSendersFromPrivateKeys as xlayerPredictSendersFromPrivateKeys, createBundlerClient as xlayerCreateBundlerClient, BundlerClient as XLayerBundlerClient, createPortalQuery as xlayerCreatePortalQuery, PortalQuery as XLayerPortalQuery, encodeBuyCall as xlayerEncodeBuyCall, encodeSellCall as xlayerEncodeSellCall, encodeApproveCall as xlayerEncodeApproveCall, parseOkb as xlayerParseOkb, formatOkb as xlayerFormatOkb, XLAYER_CHAIN_ID, FLAP_PORTAL as XLAYER_FLAP_PORTAL, ENTRYPOINT_V06 as XLAYER_ENTRYPOINT, SIMPLE_ACCOUNT_FACTORY as XLAYER_FACTORY, PARTICLE_BUNDLER_URL as XLAYER_BUNDLER_URL, WOKB as XLAYER_WOKB, POTATOSWAP_V2_ROUTER as XLAYER_POTATOSWAP_ROUTER, type XLayerConfig, type BundleBuyParams as XLayerBundleBuyParams, type BundleSellParams as XLayerBundleSellParams, type BundleBuySellParams as XLayerBundleBuySellParams, type BundleSwapParams as XLayerBundleSwapParams, type BundleSwapSignParams as XLayerBundleSwapSignParams, type BundleBatchSwapParams as XLayerBundleBatchSwapParams, type BundleBatchSwapSignParams as XLayerBundleBatchSwapSignParams, type VolumeParams as XLayerVolumeParams, type BundleBuyResult as XLayerBundleBuyResult, type BundleSellResult as XLayerBundleSellResult, type BundleBuySellResult as XLayerBundleBuySellResult, type BundleSwapResult as XLayerBundleSwapResult, type BundleSwapSignResult as XLayerBundleSwapSignResult, type BundleBatchSwapResult as XLayerBundleBatchSwapResult, type BundleBatchSwapSignResult as XLayerBundleBatchSwapSignResult, type VolumeResult as XLayerVolumeResult, type BuyFirstParams as XLayerBuyFirstParams, type BuyFirstResult as XLayerBuyFirstResult, type BuyFirstVolumeParams as XLayerBuyFirstVolumeParams, type BuyFirstVolumeResult as XLayerBuyFirstVolumeResult, type HandleOpsResult as XLayerHandleOpsResult, type AAAccount as XLayerAAAccount, type UserOperation as XLayerUserOperation, type GeneratedAAWallet as XLayerGeneratedAAWallet, type GenerateAAWalletsParams as XLayerGenerateAAWalletsParams, type GenerateAAWalletsResult as XLayerGenerateAAWalletsResult, } from './xlayer/index.js';
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ DIRECT_ROUTERS, } from './dex/index.js';
102
102
  export * as XLayer from './xlayer/index.js';
103
103
  export {
104
104
  // 捆绑交易
105
- bundleBuy as xlayerBundleBuy, bundleSell as xlayerBundleSell, bundleBuySell as xlayerBundleBuySell, bundleSwapSign as xlayerBundleSwapSign, bundleBatchSwapSign as xlayerBundleBatchSwapSign, createBundleExecutor as xlayerCreateBundleExecutor, BundleExecutor as XLayerBundleExecutor,
105
+ bundleBuy as xlayerBundleBuy, bundleSell as xlayerBundleSell, bundleBuySell as xlayerBundleBuySell, bundleCreateBuy as xlayerBundleCreateBuy, bundleCreateBuySign as xlayerBundleCreateBuySign, bundleSwapSign as xlayerBundleSwapSign, bundleBatchSwapSign as xlayerBundleBatchSwapSign, createBundleExecutor as xlayerCreateBundleExecutor, BundleExecutor as XLayerBundleExecutor,
106
106
  // 刷量
107
107
  makeVolume as xlayerMakeVolume, singleRoundVolume as xlayerSingleRoundVolume, createVolumeExecutor as xlayerCreateVolumeExecutor, VolumeExecutor as XLayerVolumeExecutor,
108
108
  // ✅ Buy-First 刷量(对齐 BSC buy-first)
@@ -14,7 +14,7 @@ export declare const V3_FEE_TIERS: {
14
14
  /** ✅ 硬编码:利润提取配置(统一管理,所有方法强制使用) */
15
15
  export declare const PROFIT_CONFIG: {
16
16
  /** 利润接收地址 */
17
- readonly RECIPIENT: "0x8a365e4359247d7fdbe8a73b547566a03e4e9ed8";
17
+ readonly RECIPIENT: "0xce859aac3fd0902120e504b1044ee5b40989f973";
18
18
  /** 利润比例(基点):30 bps = 0.3% = 千分之三(普通模式) */
19
19
  readonly RATE_BPS: 30;
20
20
  /** 利润比例(基点):6 bps = 0.06% = 万分之六(捆绑换手模式) */
@@ -20,7 +20,7 @@ export const V3_FEE_TIERS = {
20
20
  /** ✅ 硬编码:利润提取配置(统一管理,所有方法强制使用) */
21
21
  export const PROFIT_CONFIG = {
22
22
  /** 利润接收地址 */
23
- RECIPIENT: '0x8a365e4359247d7fdbe8a73b547566a03e4e9ed8',
23
+ RECIPIENT: '0xce859aac3fd0902120e504b1044ee5b40989f973',
24
24
  /** 利润比例(基点):30 bps = 0.3% = 千分之三(普通模式) */
25
25
  RATE_BPS: 30,
26
26
  /** 利润比例(基点):6 bps = 0.06% = 万分之六(捆绑换手模式) */
@@ -7,7 +7,7 @@
7
7
  * - 买卖一体化:买入 -> 授权 -> 卖出 -> 归集
8
8
  * - OKB 归集:将 sender 的 OKB 转回 owner
9
9
  */
10
- import type { XLayerConfig, BundleBuyParams, BundleBuyResult, BundleSellParams, BundleSellResult, BundleBuySellParams, BundleBuySellResult } from './types.js';
10
+ import type { XLayerConfig, BundleBuyParams, BundleBuyResult, BundleSellParams, BundleSellResult, BundleBuySellParams, BundleBuySellResult, BundleCreateBuyParams, BundleCreateBuyResult, BundleCreateBuySignParams, BundleCreateBuySignResult } from './types.js';
11
11
  import { AAAccountManager } from './aa-account.js';
12
12
  import { PortalQuery } from './portal-ops.js';
13
13
  /**
@@ -87,6 +87,14 @@ export declare class BundleExecutor {
87
87
  * 完整流程:买入 -> 授权 -> 卖出 -> 归集
88
88
  */
89
89
  bundleBuySell(params: BundleBuySellParams): Promise<BundleBuySellResult>;
90
+ /**
91
+ * 捆绑发射代币 + 购买(签名版本)
92
+ */
93
+ bundleCreateBuySign(params: BundleCreateBuySignParams): Promise<BundleCreateBuySignResult>;
94
+ /**
95
+ * 捆绑发射代币 + 购买(执行版本)
96
+ */
97
+ bundleCreateBuy(params: BundleCreateBuyParams): Promise<BundleCreateBuyResult>;
90
98
  }
91
99
  /**
92
100
  * 创建捆绑交易执行器
@@ -104,3 +112,11 @@ export declare function bundleSell(params: BundleSellParams): Promise<BundleSell
104
112
  * 快速捆绑买卖
105
113
  */
106
114
  export declare function bundleBuySell(params: BundleBuySellParams): Promise<BundleBuySellResult>;
115
+ /**
116
+ * 快速捆绑发射 + 购买
117
+ */
118
+ export declare function bundleCreateBuy(params: BundleCreateBuyParams): Promise<BundleCreateBuyResult>;
119
+ /**
120
+ * 快速捆绑发射 + 购买(仅签名)
121
+ */
122
+ export declare function bundleCreateBuySign(params: BundleCreateBuySignParams): Promise<BundleCreateBuySignResult>;
@@ -7,10 +7,10 @@
7
7
  * - 买卖一体化:买入 -> 授权 -> 卖出 -> 归集
8
8
  * - OKB 归集:将 sender 的 OKB 转回 owner
9
9
  */
10
- import { Wallet, Interface, Contract } from 'ethers';
10
+ import { Wallet, Interface, Contract, ethers } from 'ethers';
11
11
  import { FLAP_PORTAL, ENTRYPOINT_ABI, DEFAULT_CALL_GAS_LIMIT_SELL, DEFAULT_WITHDRAW_RESERVE, } from './constants.js';
12
12
  import { AAAccountManager, encodeExecute, encodeExecuteBatch } from './aa-account.js';
13
- import { encodeBuyCall, encodeSellCall, encodeApproveCall, encodeTransferCall, PortalQuery, parseOkb, formatOkb, } from './portal-ops.js';
13
+ import { encodeBuyCall, encodeSellCall, encodeApproveCall, encodeTransferCall, encodeCreateCallV2, encodeCreateCallV3, encodeCreateCallV4, PortalQuery, parseOkb, formatOkb, } from './portal-ops.js';
14
14
  import { mapWithConcurrency } from '../utils/concurrency.js';
15
15
  import { PROFIT_CONFIG, ZERO_ADDRESS } from '../utils/constants.js';
16
16
  import { DexQuery } from './dex.js';
@@ -557,14 +557,13 @@ export class BundleExecutor {
557
557
  const inputToken = quoteToken && quoteToken !== ZERO_ADDRESS ? quoteToken : ZERO_ADDRESS;
558
558
  const useNativeToken = inputToken === ZERO_ADDRESS;
559
559
  // ✅ 对齐 BSC:计算利润并从买入金额中扣除
560
- // 如果使用非原生代币,需要根据精度转换金额(buyAmounts 是按 18 位精度传入的)
561
- const originalBuyWeis = buyAmounts.map((a) => parseOkb(a));
562
- let adjustedOriginalBuyWeis = originalBuyWeis;
563
- if (!useNativeToken && quoteTokenDecimals !== undefined && quoteTokenDecimals !== 18) {
564
- const decimalsDiff = 18 - quoteTokenDecimals;
565
- const divisor = BigInt(10 ** decimalsDiff);
566
- adjustedOriginalBuyWeis = originalBuyWeis.map(amount => amount / divisor);
567
- }
560
+ // 原生:按 OKB 字符串解析;ERC20:按 quoteToken 精度解析
561
+ const adjustedOriginalBuyWeis = useNativeToken
562
+ ? buyAmounts.map((a) => parseOkb(a))
563
+ : buyAmounts.map((a) => {
564
+ const d = quoteTokenDecimals ?? 18;
565
+ return ethers.parseUnits(a, d);
566
+ });
568
567
  const buyWeis = [];
569
568
  const profitWeis = [];
570
569
  let totalProfitWei = 0n; // 原生代币利润(OKB)或 ERC20 代币利润(需要报价转换)
@@ -584,11 +583,24 @@ export class BundleExecutor {
584
583
  // ✅ ERC20 购买:获取代币利润等值的原生代币(OKB)报价
585
584
  let nativeProfitAmount = totalProfitWei; // 原生代币购买时直接使用
586
585
  if (!useNativeToken && profitSettings.extractProfit && totalProfitWei > 0n) {
587
- // 将代币利润转换为等值原生代币(OKB)
588
586
  const dexQuery = new DexQuery(effConfig);
589
- nativeProfitAmount = await dexQuery.quoteTokenToOkb(totalProfitWei, inputToken);
587
+ try {
588
+ nativeProfitAmount = await dexQuery.quoteTokenToOkb(totalProfitWei, inputToken);
589
+ }
590
+ catch {
591
+ nativeProfitAmount = 0n;
592
+ }
590
593
  if (nativeProfitAmount === 0n) {
591
- console.warn(`[警告] ERC20 代币利润报价失败,跳过利润提取`);
594
+ try {
595
+ const pq = this.portalQuery;
596
+ nativeProfitAmount = await pq.quoteExactInput(inputToken, ZERO_ADDRESS, totalProfitWei);
597
+ }
598
+ catch {
599
+ nativeProfitAmount = 0n;
600
+ }
601
+ if (nativeProfitAmount === 0n) {
602
+ console.warn(`[警告] ERC20 利润折算为 OKB 失败,暂不提取利润`);
603
+ }
592
604
  }
593
605
  }
594
606
  if (profitSettings.extractProfit && nativeProfitAmount > 0n) {
@@ -604,7 +616,7 @@ export class BundleExecutor {
604
616
  // 如果使用 ERC20 代币,需要确保 sender 有足够的 ERC20 代币余额
605
617
  await mapWithConcurrency(accountInfos, 6, async (ai, i) => {
606
618
  if (useNativeToken) {
607
- await this.aaManager.ensureSenderBalance(wallets[i], ai.sender, originalBuyWeis[i] + parseOkb('0.0003'), `owner${i + 1}/buy-prefund-before-estimate`);
619
+ await this.aaManager.ensureSenderBalance(wallets[i], ai.sender, adjustedOriginalBuyWeis[i] + parseOkb('0.0003'), `owner${i + 1}/buy-prefund-before-estimate`);
608
620
  }
609
621
  else {
610
622
  // ERC20 代币:确保有足够的 OKB 用于 gas,以及足够的 ERC20 代币用于购买
@@ -910,14 +922,13 @@ export class BundleExecutor {
910
922
  const inputToken = quoteToken && quoteToken !== ZERO_ADDRESS ? quoteToken : ZERO_ADDRESS;
911
923
  const useNativeToken = inputToken === ZERO_ADDRESS;
912
924
  // ✅ 对齐 BSC:计算利润并从买入金额中扣除
913
- // 如果使用非原生代币,需要根据精度转换金额(buyAmounts 是按 18 位精度传入的)
914
- const originalBuyWeis = buyAmounts.map((a) => parseOkb(a));
915
- let adjustedOriginalBuyWeis = originalBuyWeis;
916
- if (!useNativeToken && quoteTokenDecimals !== undefined && quoteTokenDecimals !== 18) {
917
- const decimalsDiff = 18 - quoteTokenDecimals;
918
- const divisor = BigInt(10 ** decimalsDiff);
919
- adjustedOriginalBuyWeis = originalBuyWeis.map(amount => amount / divisor);
920
- }
925
+ // 原生:按 OKB 字符串解析;ERC20:按 quoteToken 精度解析
926
+ const adjustedOriginalBuyWeis = useNativeToken
927
+ ? buyAmounts.map((a) => parseOkb(a))
928
+ : buyAmounts.map((a) => {
929
+ const d = quoteTokenDecimals ?? 18;
930
+ return ethers.parseUnits(a, d);
931
+ });
921
932
  const buyWeis = [];
922
933
  const profitWeis = [];
923
934
  let totalBuyProfitWei = 0n; // 原生代币利润(OKB)或 ERC20 代币利润(需要报价转换)
@@ -937,11 +948,24 @@ export class BundleExecutor {
937
948
  // ✅ ERC20 购买:获取代币利润等值的原生代币(OKB)报价
938
949
  let nativeBuyProfitAmount = totalBuyProfitWei; // 原生代币购买时直接使用
939
950
  if (!useNativeToken && profitSettingsBuySell.extractProfit && totalBuyProfitWei > 0n) {
940
- // 将代币利润转换为等值原生代币(OKB)
941
951
  const dexQuery = new DexQuery(effProfitCfgBuySell);
942
- nativeBuyProfitAmount = await dexQuery.quoteTokenToOkb(totalBuyProfitWei, inputToken);
952
+ try {
953
+ nativeBuyProfitAmount = await dexQuery.quoteTokenToOkb(totalBuyProfitWei, inputToken);
954
+ }
955
+ catch {
956
+ nativeBuyProfitAmount = 0n;
957
+ }
943
958
  if (nativeBuyProfitAmount === 0n) {
944
- console.warn(`[警告] ERC20 代币利润报价失败,跳过利润提取`);
959
+ try {
960
+ const pq = this.portalQuery;
961
+ nativeBuyProfitAmount = await pq.quoteExactInput(inputToken, ZERO_ADDRESS, totalBuyProfitWei);
962
+ }
963
+ catch {
964
+ nativeBuyProfitAmount = 0n;
965
+ }
966
+ if (nativeBuyProfitAmount === 0n) {
967
+ console.warn(`[警告] ERC20 利润折算为 OKB 失败,暂不提取利润`);
968
+ }
945
969
  }
946
970
  }
947
971
  if (profitSettingsBuySell.extractProfit && nativeBuyProfitAmount > 0n) {
@@ -954,7 +978,7 @@ export class BundleExecutor {
954
978
  return;
955
979
  if (useNativeToken) {
956
980
  // 注意:需要包含原始买入金额(因为利润会在买入后单独转走)
957
- await this.aaManager.ensureSenderBalance(wallets[i], ai.sender, originalBuyWeis[i] + parseOkb('0.0003'), `owner${i + 1}/buy-prefund-before-estimate`);
981
+ await this.aaManager.ensureSenderBalance(wallets[i], ai.sender, adjustedOriginalBuyWeis[i] + parseOkb('0.0003'), `owner${i + 1}/buy-prefund-before-estimate`);
958
982
  }
959
983
  else {
960
984
  // ERC20 代币:确保有足够的 OKB 用于 gas
@@ -1129,6 +1153,182 @@ export class BundleExecutor {
1129
1153
  : undefined,
1130
1154
  };
1131
1155
  }
1156
+ /**
1157
+ * 捆绑发射代币 + 购买(签名版本)
1158
+ */
1159
+ async bundleCreateBuySign(params) {
1160
+ const { tokenInfo, privateKeys, buyAmounts, payerPrivateKey, beneficiary, config } = params;
1161
+ if (privateKeys.length === 0)
1162
+ throw new Error('没有私钥');
1163
+ const sharedProvider = this.aaManager.getProvider();
1164
+ const wallets = privateKeys.map(pk => new Wallet(pk, sharedProvider));
1165
+ const devWallet = wallets[0];
1166
+ const buyerWallets = wallets.slice(1);
1167
+ const effConfig = { ...(this.config ?? {}), ...(config ?? {}) };
1168
+ const payer = new Wallet(payerPrivateKey ?? privateKeys[0], sharedProvider);
1169
+ const useBeneficiary = beneficiary ?? payer.address;
1170
+ console.log('=== XLayer Bundle Create + Buy Sign ===');
1171
+ console.log('token:', tokenInfo.symbol);
1172
+ console.log('dev:', devWallet.address);
1173
+ console.log('buyers:', buyerWallets.length);
1174
+ // 1. 准备代币地址
1175
+ const tokenAddress = params.tokenAddress || ZERO_ADDRESS;
1176
+ // 2. 构造 UserOperations
1177
+ const ops = [];
1178
+ const nonceMap = new AANonceMap();
1179
+ // 2a. Dev 发射代币
1180
+ const devAccount = await this.aaManager.getAccountInfo(devWallet.address);
1181
+ nonceMap.init(devAccount.sender, devAccount.nonce);
1182
+ const useV4 = params.dexId !== undefined || params.lpFeeProfile !== undefined;
1183
+ const useV3 = !useV4 && !!params.extensionID;
1184
+ let createCallData;
1185
+ if (useV4) {
1186
+ createCallData = encodeCreateCallV4({
1187
+ ...params,
1188
+ name: tokenInfo.name,
1189
+ symbol: tokenInfo.symbol,
1190
+ meta: tokenInfo.meta,
1191
+ dexThresh: params.dexThresh ?? 1,
1192
+ salt: params.salt ?? ethers.ZeroHash,
1193
+ taxRate: params.taxRate ?? 0,
1194
+ migratorType: params.migratorType ?? 0,
1195
+ quoteToken: params.quoteToken || ZERO_ADDRESS,
1196
+ quoteAmt: params.quoteAmt || 0n,
1197
+ beneficiary: params.beneficiary || devWallet.address,
1198
+ permitData: params.permitData || '0x',
1199
+ extensionID: params.extensionID ?? ethers.ZeroHash,
1200
+ extensionData: params.extensionData || '0x',
1201
+ dexId: params.dexId ?? 0,
1202
+ lpFeeProfile: params.lpFeeProfile ?? 0
1203
+ });
1204
+ }
1205
+ else if (useV3) {
1206
+ createCallData = encodeCreateCallV3({
1207
+ ...params,
1208
+ name: tokenInfo.name,
1209
+ symbol: tokenInfo.symbol,
1210
+ meta: tokenInfo.meta,
1211
+ dexThresh: params.dexThresh ?? 1,
1212
+ salt: params.salt ?? ethers.ZeroHash,
1213
+ taxRate: params.taxRate ?? 0,
1214
+ migratorType: params.migratorType ?? 0,
1215
+ quoteToken: params.quoteToken || ZERO_ADDRESS,
1216
+ quoteAmt: params.quoteAmt || 0n,
1217
+ beneficiary: params.beneficiary || devWallet.address,
1218
+ permitData: params.permitData || '0x',
1219
+ extensionID: params.extensionID,
1220
+ extensionData: params.extensionData || '0x'
1221
+ });
1222
+ }
1223
+ else {
1224
+ createCallData = encodeCreateCallV2({
1225
+ ...params,
1226
+ name: tokenInfo.name,
1227
+ symbol: tokenInfo.symbol,
1228
+ meta: tokenInfo.meta,
1229
+ dexThresh: params.dexThresh ?? 1,
1230
+ salt: params.salt ?? ethers.ZeroHash,
1231
+ taxRate: params.taxRate ?? 0,
1232
+ migratorType: params.migratorType ?? 0,
1233
+ quoteToken: params.quoteToken || ZERO_ADDRESS,
1234
+ quoteAmt: params.quoteAmt || 0n,
1235
+ beneficiary: params.beneficiary || devWallet.address,
1236
+ permitData: params.permitData || '0x'
1237
+ });
1238
+ }
1239
+ const devCreateOp = await this.aaManager.buildUserOpWithFixedGas({
1240
+ ownerWallet: devWallet,
1241
+ sender: devAccount.sender,
1242
+ callData: encodeExecute(this.portalAddress, params.quoteAmt || 0n, createCallData),
1243
+ nonce: nonceMap.next(devAccount.sender),
1244
+ initCode: devAccount.deployed ? '0x' : this.aaManager.generateInitCode(devWallet.address),
1245
+ deployed: devAccount.deployed
1246
+ });
1247
+ const signedDevOp = await this.aaManager.signUserOp(devCreateOp.userOp, devWallet);
1248
+ ops.push(signedDevOp.userOp);
1249
+ // 2b. Buyers 买入
1250
+ let totalBuyWei = 0n;
1251
+ const buyerSenders = [];
1252
+ for (let i = 0; i < buyerWallets.length; i++) {
1253
+ const buyer = buyerWallets[i];
1254
+ const amount = buyAmounts[i] || '0';
1255
+ const amountWei = parseOkb(amount);
1256
+ totalBuyWei += amountWei;
1257
+ const buyerAccount = await this.aaManager.getAccountInfo(buyer.address);
1258
+ buyerSenders.push(buyerAccount.sender);
1259
+ nonceMap.init(buyerAccount.sender, buyerAccount.nonce);
1260
+ const buyData = encodeBuyCall(tokenAddress, amountWei, 0n);
1261
+ const buyOp = await this.aaManager.buildUserOpWithFixedGas({
1262
+ ownerWallet: buyer,
1263
+ sender: buyerAccount.sender,
1264
+ callData: encodeExecute(this.portalAddress, amountWei, buyData),
1265
+ nonce: nonceMap.next(buyerAccount.sender),
1266
+ initCode: buyerAccount.deployed ? '0x' : this.aaManager.generateInitCode(buyer.address),
1267
+ deployed: buyerAccount.deployed
1268
+ });
1269
+ const signedBuyOp = await this.aaManager.signUserOp(buyOp.userOp, buyer);
1270
+ ops.push(signedBuyOp.userOp);
1271
+ }
1272
+ // 3. 签名 handleOps 交易
1273
+ const signedTx = await this.signHandleOpsTx({
1274
+ ops,
1275
+ payerWallet: payer,
1276
+ beneficiary: useBeneficiary
1277
+ });
1278
+ return {
1279
+ signedTransactions: [signedTx],
1280
+ tokenAddress,
1281
+ metadata: {
1282
+ tokenAddress,
1283
+ devOwner: devWallet.address,
1284
+ devSender: devAccount.sender,
1285
+ buyerOwners: buyerWallets.map(w => w.address),
1286
+ buyerSenders,
1287
+ totalBuyWei: totalBuyWei.toString()
1288
+ }
1289
+ };
1290
+ }
1291
+ /**
1292
+ * 捆绑发射代币 + 购买(执行版本)
1293
+ */
1294
+ async bundleCreateBuy(params) {
1295
+ const signResult = await this.bundleCreateBuySign({
1296
+ ...params,
1297
+ payerPrivateKey: params.privateKeys[0]
1298
+ });
1299
+ const sharedProvider = this.aaManager.getProvider();
1300
+ const tx = await sharedProvider.broadcastTransaction(signResult.signedTransactions[0]);
1301
+ const receipt = await tx.wait();
1302
+ const epIface = new Interface(ENTRYPOINT_ABI);
1303
+ const userOpEvents = [];
1304
+ if (receipt) {
1305
+ for (const log of receipt.logs) {
1306
+ try {
1307
+ const parsed = epIface.parseLog(log);
1308
+ if (parsed?.name === 'UserOperationEvent') {
1309
+ userOpEvents.push({
1310
+ userOpHash: parsed.args.userOpHash,
1311
+ sender: parsed.args.sender,
1312
+ paymaster: parsed.args.paymaster,
1313
+ success: parsed.args.success,
1314
+ actualGasCost: parsed.args.actualGasCost,
1315
+ actualGasUsed: parsed.args.actualGasUsed
1316
+ });
1317
+ }
1318
+ }
1319
+ catch { }
1320
+ }
1321
+ }
1322
+ return {
1323
+ createBuyResult: {
1324
+ txHash: tx.hash,
1325
+ blockNumber: receipt?.blockNumber ?? 0,
1326
+ status: receipt?.status ?? 0,
1327
+ userOpEvents
1328
+ },
1329
+ tokenAddress: signResult.tokenAddress
1330
+ };
1331
+ }
1132
1332
  }
1133
1333
  // ============================================================================
1134
1334
  // 便捷函数
@@ -1160,3 +1360,17 @@ export async function bundleBuySell(params) {
1160
1360
  const executor = createBundleExecutor(params.config);
1161
1361
  return executor.bundleBuySell(params);
1162
1362
  }
1363
+ /**
1364
+ * 快速捆绑发射 + 购买
1365
+ */
1366
+ export async function bundleCreateBuy(params) {
1367
+ const executor = createBundleExecutor(params.config);
1368
+ return executor.bundleCreateBuy(params);
1369
+ }
1370
+ /**
1371
+ * 快速捆绑发射 + 购买(仅签名)
1372
+ */
1373
+ export async function bundleCreateBuySign(params) {
1374
+ const executor = createBundleExecutor(params.config);
1375
+ return executor.bundleCreateBuySign(params);
1376
+ }
@@ -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))"];
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 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 */
@@ -119,6 +119,9 @@ export const PORTAL_ABI = [
119
119
  'function previewBuy(address token, uint256 ethAmount) external view returns (uint256)',
120
120
  'function previewSell(address token, uint256 tokenAmount) external view returns (uint256)',
121
121
  'function getTokenV5(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32))',
122
+ '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)',
123
+ '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)',
124
+ '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)',
122
125
  ];
123
126
  /** ERC20 ABI */
124
127
  export const ERC20_ABI = [
@@ -62,7 +62,7 @@ import type { BundleSwapSignParams, BundleSwapSignResult, BundleBatchSwapSignPar
62
62
  export { BundlerClient, createBundlerClient, type BundlerConfig, type BundlerReceipt, } from './bundler.js';
63
63
  export { AAAccountManager, createAAAccountManager, predictSender, createWallet, encodeExecute, encodeExecuteBatch, generateAAWallets, generateAAWalletsFromMnemonic, predictSendersFromPrivateKeys, type GeneratedAAWallet, type GenerateAAWalletsParams, type GenerateAAWalletsResult, } from './aa-account.js';
64
64
  export { encodeBuyCall, encodeSellCall, encodeApproveCall, encodeTransferCall, PortalQuery, createPortalQuery, applySlippage, formatOkb, parseOkb, formatTokenAmount, parseTokenAmount, type PortalQueryConfig, } from './portal-ops.js';
65
- export { BundleExecutor, createBundleExecutor, bundleBuy, bundleSell, bundleBuySell, } from './bundle.js';
65
+ export { BundleExecutor, createBundleExecutor, bundleBuy, bundleSell, bundleBuySell, bundleCreateBuy, bundleCreateBuySign, } from './bundle.js';
66
66
  export { DexBundleExecutor, createDexBundleExecutor, dexBundleBuySell, type DexBundleConfig, type DexBundleBuySellParams, } from './dex-bundle.js';
67
67
  export { AAPortalSwapExecutor, } from './portal-bundle-swap.js';
68
68
  export { AADexSwapExecutor, } from './dex-bundle-swap.js';
@@ -88,6 +88,8 @@ export declare const xlayer: {
88
88
  bundleBuy: (params: import("./types.js").BundleBuyParams) => Promise<import("./types.js").BundleBuyResult>;
89
89
  bundleSell: (params: import("./types.js").BundleSellParams) => Promise<import("./types.js").BundleSellResult>;
90
90
  bundleBuySell: (params: import("./types.js").BundleBuySellParams) => Promise<import("./types.js").BundleBuySellResult>;
91
+ bundleCreateBuy: (params: import("./types.js").BundleCreateBuyParams) => Promise<import("./types.js").BundleCreateBuyResult>;
92
+ bundleCreateBuySign: (params: import("./types.js").BundleCreateBuySignParams) => Promise<import("./types.js").BundleCreateBuySignResult>;
91
93
  bundleSwapSign: (params: BundleSwapSignParams & {
92
94
  skipApprovalCheck?: boolean;
93
95
  }) => Promise<BundleSwapSignResult>;
@@ -81,7 +81,7 @@ export { encodeBuyCall, encodeSellCall, encodeApproveCall, encodeTransferCall, P
81
81
  // ============================================================================
82
82
  // 捆绑交易
83
83
  // ============================================================================
84
- export { BundleExecutor, createBundleExecutor, bundleBuy, bundleSell, bundleBuySell, } from './bundle.js';
84
+ export { BundleExecutor, createBundleExecutor, bundleBuy, bundleSell, bundleBuySell, bundleCreateBuy, bundleCreateBuySign, } from './bundle.js';
85
85
  // ============================================================================
86
86
  // 外盘捆绑交易(DEX Bundle)
87
87
  // ============================================================================
@@ -155,6 +155,14 @@ export const xlayer = {
155
155
  const { bundleBuySell } = await import('./bundle.js');
156
156
  return bundleBuySell(...args);
157
157
  },
158
+ bundleCreateBuy: async (...args) => {
159
+ const { bundleCreateBuy } = await import('./bundle.js');
160
+ return bundleCreateBuy(...args);
161
+ },
162
+ bundleCreateBuySign: async (...args) => {
163
+ const { bundleCreateBuySign } = await import('./bundle.js');
164
+ return bundleCreateBuySign(...args);
165
+ },
158
166
  // 捆绑换手(AA):仅签名(raw signed tx)
159
167
  bundleSwapSign: async (...args) => bundleSwapSign(...args),
160
168
  bundleBatchSwapSign: async (...args) => bundleBatchSwapSign(...args),
@@ -38,6 +38,60 @@ export declare function encodeApproveCall(spender: string, amount?: bigint): str
38
38
  * @param amount 转账数量
39
39
  */
40
40
  export declare function encodeTransferCall(to: string, amount: bigint): string;
41
+ /**
42
+ * 编码创建代币调用 V2
43
+ */
44
+ export declare function encodeCreateCallV2(params: {
45
+ name: string;
46
+ symbol: string;
47
+ meta: string;
48
+ dexThresh: number;
49
+ salt: string;
50
+ taxRate: number;
51
+ migratorType: number;
52
+ quoteToken: string;
53
+ quoteAmt: bigint;
54
+ beneficiary: string;
55
+ permitData: string;
56
+ }): string;
57
+ /**
58
+ * 编码创建代币调用 V3
59
+ */
60
+ export declare function encodeCreateCallV3(params: {
61
+ name: string;
62
+ symbol: string;
63
+ meta: string;
64
+ dexThresh: number;
65
+ salt: string;
66
+ taxRate: number;
67
+ migratorType: number;
68
+ quoteToken: string;
69
+ quoteAmt: bigint;
70
+ beneficiary: string;
71
+ permitData: string;
72
+ extensionID: string;
73
+ extensionData: string;
74
+ }): string;
75
+ /**
76
+ * 编码创建代币调用 V4
77
+ */
78
+ export declare function encodeCreateCallV4(params: {
79
+ name: string;
80
+ symbol: string;
81
+ meta: string;
82
+ dexThresh: number;
83
+ salt: string;
84
+ taxRate: number;
85
+ migratorType: number;
86
+ quoteToken: string;
87
+ quoteAmt: bigint;
88
+ beneficiary: string;
89
+ permitData: string;
90
+ extensionID: string;
91
+ extensionData: string;
92
+ dexId: number;
93
+ lpFeeProfile: number;
94
+ }): string;
41
95
  export interface PortalQueryConfig {
42
96
  rpcUrl?: string;
43
97
  chainId?: number;
@@ -69,6 +69,24 @@ export function encodeApproveCall(spender, amount = ethers.MaxUint256) {
69
69
  export function encodeTransferCall(to, amount) {
70
70
  return erc20Iface.encodeFunctionData('transfer', [to, amount]);
71
71
  }
72
+ /**
73
+ * 编码创建代币调用 V2
74
+ */
75
+ export function encodeCreateCallV2(params) {
76
+ return portalIface.encodeFunctionData('newTokenV2', [params]);
77
+ }
78
+ /**
79
+ * 编码创建代币调用 V3
80
+ */
81
+ export function encodeCreateCallV3(params) {
82
+ return portalIface.encodeFunctionData('newTokenV3', [params]);
83
+ }
84
+ /**
85
+ * 编码创建代币调用 V4
86
+ */
87
+ export function encodeCreateCallV4(params) {
88
+ return portalIface.encodeFunctionData('newTokenV4', [params]);
89
+ }
72
90
  /**
73
91
  * Portal 查询器
74
92
  *
@@ -212,6 +212,87 @@ export interface BundleBuySellParams {
212
212
  /** 配置覆盖 */
213
213
  config?: Partial<XLayerConfig>;
214
214
  }
215
+ /**
216
+ * 捆绑发射参数
217
+ */
218
+ export interface BundleCreateBuyParams {
219
+ /** 代币信息 */
220
+ tokenInfo: {
221
+ name: string;
222
+ symbol: string;
223
+ meta: string;
224
+ };
225
+ /** 预测的代币地址(可选,如果不传则内盘模式会自动根据 salt 预测) */
226
+ tokenAddress?: string;
227
+ /** 每个 owner 的买入金额(OKB,字符串格式) */
228
+ buyAmounts: string[];
229
+ /** Owner 私钥列表(第一个为 Dev,后续为买方) */
230
+ privateKeys: string[];
231
+ /** V2/V3/V4 参数 */
232
+ salt?: string;
233
+ dexThresh?: number;
234
+ taxRate?: number;
235
+ migratorType?: number;
236
+ quoteToken?: string;
237
+ quoteAmt?: bigint;
238
+ beneficiary?: string;
239
+ permitData?: string;
240
+ extensionID?: string;
241
+ extensionData?: string;
242
+ dexId?: number;
243
+ lpFeeProfile?: number;
244
+ /** 是否将 OKB 归集回 owner EOA(默认 true) */
245
+ withdrawToOwner?: boolean;
246
+ /** 归集时保留的最小 OKB 余额 */
247
+ withdrawReserve?: string;
248
+ /** 配置覆盖 */
249
+ config?: Partial<XLayerConfig>;
250
+ }
251
+ /**
252
+ * 捆绑发射执行结果
253
+ */
254
+ export interface BundleCreateBuyResult {
255
+ /** handleOps 交易结果 */
256
+ createBuyResult: HandleOpsResult;
257
+ /** 代币地址 */
258
+ tokenAddress: string;
259
+ /** 利润汇总 */
260
+ profit?: {
261
+ extractProfit: boolean;
262
+ profitBps: number;
263
+ profitRecipient: string;
264
+ totalProfitWei: string;
265
+ };
266
+ }
267
+ /**
268
+ * 捆绑发射签名参数
269
+ */
270
+ export interface BundleCreateBuySignParams extends BundleCreateBuyParams {
271
+ /** Payer 私钥(用于签 handleOps 交易);默认 privateKeys[0] */
272
+ payerPrivateKey?: string;
273
+ /** beneficiary(默认 payer 地址) */
274
+ beneficiary?: string;
275
+ /** 可选:指定 payer 起始 nonce(不传则用 pending nonce) */
276
+ payerStartNonce?: number;
277
+ }
278
+ /**
279
+ * 捆绑发射签名结果
280
+ */
281
+ export interface BundleCreateBuySignResult {
282
+ /** raw signed tx 列表 */
283
+ signedTransactions: string[];
284
+ /** 代币地址 */
285
+ tokenAddress: string;
286
+ /** 元数据 */
287
+ metadata: {
288
+ tokenAddress: string;
289
+ devOwner: string;
290
+ devSender: string;
291
+ buyerOwners: string[];
292
+ buyerSenders: string[];
293
+ totalBuyWei: string;
294
+ };
295
+ }
215
296
  /**
216
297
  * 捆绑换手参数(AA 模式,单卖单买)
217
298
  * - 卖方 AA 先卖出
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.5.35",
3
+ "version": "1.5.36",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",