four-flap-meme-sdk 1.6.68 → 1.6.69

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.
@@ -17,8 +17,8 @@ import { createAAAccountManager, encodeExecute, createWallet } from './aa-accoun
17
17
  import { encodeBuyCall, encodeSellCall, PortalQuery, lpFeeProfileToV3Fee } from './portal-ops.js';
18
18
  import { encodeSwapExactETHForTokensSupportingFee, encodeSwapExactTokensForETHSupportingFee, encodeSwapExactETHForTokensV3, encodeSwapExactTokensForETHV3, } from './dex.js';
19
19
  import { encodeApproveCall } from './portal-ops.js';
20
- import { FLAP_PORTAL, WOKB, XLAYER_CHAIN_ID, DEFAULT_RPC_URL, ENTRYPOINT_V06, SIMPLE_ACCOUNT_FACTORY, PARTICLE_BUNDLER_URL, POTATOSWAP_V2_ROUTER, POTATOSWAP_V3_ROUTER, POTATOSWAP_V3_FACTORY, } from './constants.js';
21
- import { PROFIT_CONFIG, ZERO_ADDRESS } from '../utils/constants.js';
20
+ import { FLAP_PORTAL, WOKB, XLAYER_CHAIN_ID, DEFAULT_RPC_URL, ENTRYPOINT_V06, SIMPLE_ACCOUNT_FACTORY, PARTICLE_BUNDLER_URL, POTATOSWAP_V2_ROUTER, POTATOSWAP_V3_ROUTER, } from './constants.js';
21
+ import { PROFIT_CONFIG } from '../utils/constants.js';
22
22
  import { mapWithConcurrency } from '../utils/concurrency.js';
23
23
  // ============================================================================
24
24
  // 工具函数
@@ -63,69 +63,6 @@ function normalizeConfig(cfg) {
63
63
  };
64
64
  }
65
65
  // ============================================================================
66
- // V3 报价工具函数
67
- // ============================================================================
68
- const V3_FACTORY_ABI = [
69
- 'function getPool(address tokenA, address tokenB, uint24 fee) view returns (address pool)',
70
- ];
71
- const V3_POOL_ABI = [
72
- 'function slot0() view returns (uint160 sqrtPriceX96,int24 tick,uint16 observationIndex,uint16 observationCardinality,uint16 observationCardinalityNext,uint8 feeProtocol,bool unlocked)',
73
- 'function token0() view returns (address)',
74
- 'function token1() view returns (address)',
75
- ];
76
- const V3_FEE_DENOMINATOR = 1000000n;
77
- /**
78
- * 使用 V3 Pool 的 slot0 获取 Token → WOKB 的报价(卖出方向)
79
- */
80
- async function quoteV3SellViaSlot0(params) {
81
- try {
82
- const { rpcUrl, tokenAddress, tokenAmount, fee } = params;
83
- if (!tokenAddress || tokenAmount <= 0n)
84
- return 0n;
85
- const provider = new ethers.JsonRpcProvider(rpcUrl);
86
- const wokbLower = WOKB.toLowerCase();
87
- const tokenLower = tokenAddress.toLowerCase();
88
- if (wokbLower === tokenLower)
89
- return tokenAmount;
90
- const factory = new ethers.Contract(POTATOSWAP_V3_FACTORY, V3_FACTORY_ABI, provider);
91
- const poolAddr = await factory.getPool(tokenAddress, WOKB, fee);
92
- if (!poolAddr || poolAddr.toLowerCase() === ZERO_ADDRESS.toLowerCase())
93
- return 0n;
94
- const pool = new ethers.Contract(poolAddr, V3_POOL_ABI, provider);
95
- const [t0, t1, slot0] = await Promise.all([pool.token0(), pool.token1(), pool.slot0()]);
96
- if (!t0 || !t1 || !slot0)
97
- return 0n;
98
- const sqrtPriceX96 = BigInt(slot0[0]);
99
- if (sqrtPriceX96 <= 0n)
100
- return 0n;
101
- // 扣除手续费
102
- const amountInLessFee = (tokenAmount * (V3_FEE_DENOMINATOR - BigInt(fee))) / V3_FEE_DENOMINATOR;
103
- if (amountInLessFee <= 0n)
104
- return 0n;
105
- const Q192 = 2n ** 192n;
106
- const num = sqrtPriceX96 * sqrtPriceX96;
107
- const t0Lower = String(t0).toLowerCase();
108
- const t1Lower = String(t1).toLowerCase();
109
- // sqrtPriceX96 表示 token1/token0 的现货价
110
- // 卖出方向:Token → WOKB
111
- if (tokenLower === t0Lower && wokbLower === t1Lower) {
112
- // Token 是 token0,WOKB 是 token1
113
- // price = token1/token0 = WOKB/Token, 所以 wokbOut = tokenIn * price = tokenIn * num / Q192
114
- return (amountInLessFee * num) / Q192;
115
- }
116
- if (tokenLower === t1Lower && wokbLower === t0Lower) {
117
- // Token 是 token1,WOKB 是 token0
118
- // price = token1/token0 = Token/WOKB, 所以 wokbOut = tokenIn / price = tokenIn * Q192 / num
119
- return (amountInLessFee * Q192) / num;
120
- }
121
- return 0n;
122
- }
123
- catch (e) {
124
- console.warn('[quoteV3SellViaSlot0] 报价失败:', e);
125
- return 0n;
126
- }
127
- }
128
- // ============================================================================
129
66
  // 买入 UserOps 构建
130
67
  // ============================================================================
131
68
  /**
@@ -400,21 +337,6 @@ export async function buildBundleSellOps(params) {
400
337
  targetContract = portal;
401
338
  }
402
339
  else if (poolType === 'v3') {
403
- // ✅ V3 卖出报价:使用 slot0 计算预期输出,并应用 2% 滑点保护
404
- let amountOutMinimum = 0n;
405
- try {
406
- const quotedOut = await quoteV3SellViaSlot0({
407
- rpcUrl: config.rpcUrl,
408
- tokenAddress: params.tokenAddress,
409
- tokenAmount: sellAmount,
410
- fee: v3Fee,
411
- });
412
- // 应用 2% 滑点保护
413
- amountOutMinimum = (quotedOut * 98n) / 100n;
414
- }
415
- catch (e) {
416
- console.warn(`[buildBundleSellOps] V3 卖出报价失败,使用 amountOutMinimum=0:`, e);
417
- }
418
340
  swapData = encodeSwapExactTokensForETHV3({
419
341
  tokenIn: params.tokenAddress,
420
342
  tokenOut: wokb,
@@ -423,7 +345,7 @@ export async function buildBundleSellOps(params) {
423
345
  unwrapRecipient: sender,
424
346
  deadline,
425
347
  amountIn: sellAmount,
426
- amountOutMinimum,
348
+ amountOutMinimum: 0n,
427
349
  sqrtPriceLimitX96: 0n,
428
350
  });
429
351
  targetContract = routerAddress;
@@ -35,6 +35,8 @@ export interface WashOpsParams {
35
35
  deadlineMinutes?: number;
36
36
  /** 用户类型(影响利润费率:v0=0.08%, v1=0.10%) */
37
37
  userType?: WashUserType;
38
+ /** 买卖操作的 callGasLimit(默认 400_000) */
39
+ tradeGasLimit?: bigint;
38
40
  /** SDK 配置 */
39
41
  config?: Partial<XLayerConfig>;
40
42
  }
@@ -277,8 +277,7 @@ export async function buildWashOps(params) {
277
277
  wokbAmount: buyWei,
278
278
  fee: v3Fee,
279
279
  });
280
- // 应用 2% 滑点保护,避免因价格波动导致卖出失败
281
- return (quoted * 98n) / 100n;
280
+ return quoted;
282
281
  }
283
282
  catch {
284
283
  return 0n;
@@ -384,9 +383,9 @@ export async function buildWashOps(params) {
384
383
  opType: 'sell',
385
384
  });
386
385
  }
387
- // 固定 Gas
386
+ // 固定 Gas(买卖操作支持前端传入)
388
387
  const profitCallGasLimit = 120000n;
389
- const tradeCallGasLimit = 400000n;
388
+ const tradeCallGasLimit = params.tradeGasLimit ?? 400000n;
390
389
  // 构造 UserOps
391
390
  const built = await mapWithConcurrency(allSkeletons, 20, async (sk) => {
392
391
  const callGasLimit = sk.opType === 'profit' ? profitCallGasLimit : tradeCallGasLimit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.6.68",
3
+ "version": "1.6.69",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",