four-flap-meme-sdk 1.6.62 → 1.6.63

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.
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { ethers } from 'ethers';
16
16
  import { createAAAccountManager, encodeExecute, createWallet } from './aa-account.js';
17
- import { encodeBuyCall, encodeSellCall } from './portal-ops.js';
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
20
  import { FLAP_PORTAL, WOKB, XLAYER_CHAIN_ID, DEFAULT_RPC_URL, ENTRYPOINT_V06, SIMPLE_ACCOUNT_FACTORY, PARTICLE_BUNDLER_URL, } from './constants.js';
@@ -71,7 +71,6 @@ function normalizeConfig(cfg) {
71
71
  export async function buildBundleBuyOps(params) {
72
72
  const poolType = params.poolType || 'flap';
73
73
  const wokb = params.wrappedOkbAddress || WOKB;
74
- const v3Fee = params.v3Fee || 2500;
75
74
  const deadline = Math.floor(Date.now() / 1000) + 60 * Math.max(1, Number(params.deadlineMinutes ?? 20));
76
75
  const portal = FLAP_PORTAL;
77
76
  const routerAddress = params.routerAddress || '';
@@ -85,6 +84,22 @@ export async function buildBundleBuyOps(params) {
85
84
  // ✅ 归一化配置,填充默认值(与前端 normalizeXLayerAAConfig 保持一致)
86
85
  const config = normalizeConfig(params.config);
87
86
  const aaManager = createAAAccountManager(config);
87
+ // ✅ V3 模式:直接从链上读取 lpFeeProfile 获取正确的 fee(与 bundleGraduateBuy 保持一致)
88
+ let v3Fee = params.v3Fee || 2500;
89
+ if (poolType === 'v3') {
90
+ try {
91
+ const portalQuery = new PortalQuery({ rpcUrl: config.rpcUrl, chainId: config.chainId });
92
+ const tokenState = await portalQuery.getTokenV7(params.tokenAddress);
93
+ const correctV3Fee = lpFeeProfileToV3Fee(tokenState.lpFeeProfile);
94
+ if (correctV3Fee !== v3Fee) {
95
+ console.log(`[buildBundleBuyOps] V3 Fee 校正: 前端传入 ${v3Fee}, 链上 lpFeeProfile=${tokenState.lpFeeProfile} → 正确 fee=${correctV3Fee}`);
96
+ }
97
+ v3Fee = correctV3Fee;
98
+ }
99
+ catch (e) {
100
+ console.warn(`[buildBundleBuyOps] 读取 lpFeeProfile 失败,使用前端传入的 v3Fee=${v3Fee}:`, e);
101
+ }
102
+ }
88
103
  const ownerWallets = params.ownerPrivateKeys.map(pk => createWallet(pk, config));
89
104
  const owners = ownerWallets.map(w => w.address);
90
105
  const accounts = await aaManager.getMultipleAccountInfo(owners);
@@ -223,7 +238,6 @@ export async function buildBundleBuyOps(params) {
223
238
  export async function buildBundleSellOps(params) {
224
239
  const poolType = params.poolType || 'flap';
225
240
  const wokb = params.wrappedOkbAddress || WOKB;
226
- const v3Fee = params.v3Fee || 2500;
227
241
  const deadline = Math.floor(Date.now() / 1000) + 60 * Math.max(1, Number(params.deadlineMinutes ?? 20));
228
242
  const portal = FLAP_PORTAL;
229
243
  const routerAddress = params.routerAddress || '';
@@ -238,6 +252,22 @@ export async function buildBundleSellOps(params) {
238
252
  // ✅ 归一化配置,填充默认值(与前端 normalizeXLayerAAConfig 保持一致)
239
253
  const config = normalizeConfig(params.config);
240
254
  const aaManager = createAAAccountManager(config);
255
+ // ✅ V3 模式:直接从链上读取 lpFeeProfile 获取正确的 fee(与 bundleGraduateBuy 保持一致)
256
+ let v3Fee = params.v3Fee || 2500;
257
+ if (poolType === 'v3') {
258
+ try {
259
+ const portalQuery = new PortalQuery({ rpcUrl: config.rpcUrl, chainId: config.chainId });
260
+ const tokenState = await portalQuery.getTokenV7(params.tokenAddress);
261
+ const correctV3Fee = lpFeeProfileToV3Fee(tokenState.lpFeeProfile);
262
+ if (correctV3Fee !== v3Fee) {
263
+ console.log(`[buildBundleSellOps] V3 Fee 校正: 前端传入 ${v3Fee}, 链上 lpFeeProfile=${tokenState.lpFeeProfile} → 正确 fee=${correctV3Fee}`);
264
+ }
265
+ v3Fee = correctV3Fee;
266
+ }
267
+ catch (e) {
268
+ console.warn(`[buildBundleSellOps] 读取 lpFeeProfile 失败,使用前端传入的 v3Fee=${v3Fee}:`, e);
269
+ }
270
+ }
241
271
  const ownerWallets = params.ownerPrivateKeys.map(pk => createWallet(pk, config));
242
272
  const owners = ownerWallets.map(w => w.address);
243
273
  const accounts = await aaManager.getMultipleAccountInfo(owners);
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { ethers } from 'ethers';
16
16
  import { createAAAccountManager, encodeExecute, createWallet } from './aa-account.js';
17
- import { encodeBuyCall, encodeSellCall, PortalQuery } from './portal-ops.js';
17
+ import { encodeBuyCall, encodeSellCall, PortalQuery, lpFeeProfileToV3Fee } from './portal-ops.js';
18
18
  import { encodeSwapExactETHForTokensSupportingFee, encodeSwapExactTokensForETHSupportingFee, encodeSwapExactETHForTokensV3, encodeSwapExactTokensForETHV3, DexQuery, } from './dex.js';
19
19
  import { FLAP_PORTAL, WOKB, XLAYER_CHAIN_ID, DEFAULT_RPC_URL, ENTRYPOINT_V06, SIMPLE_ACCOUNT_FACTORY, PARTICLE_BUNDLER_URL, } from './constants.js';
20
20
  import { PROFIT_CONFIG } from '../utils/constants.js';
@@ -77,7 +77,6 @@ function normalizeConfig(cfg) {
77
77
  export async function buildWashOps(params) {
78
78
  const poolType = params.poolType || 'flap';
79
79
  const wokb = params.wrappedOkbAddress || WOKB;
80
- const v3Fee = params.v3Fee || 2500;
81
80
  const deadline = Math.floor(Date.now() / 1000) + 60 * Math.max(1, Number(params.deadlineMinutes ?? 20));
82
81
  const portal = FLAP_PORTAL;
83
82
  const routerAddress = params.routerAddress || '';
@@ -88,15 +87,29 @@ export async function buildWashOps(params) {
88
87
  if (poolType === 'v3' && !routerAddress) {
89
88
  throw new Error('[buildWashOps] poolType=v3 时必须提供 routerAddress');
90
89
  }
91
- if (poolType === 'v3' && !params.v3Fee) {
92
- throw new Error('[buildWashOps] poolType=v3 时必须提供 v3Fee');
93
- }
94
90
  if (params.ownerPrivateKeys.length !== params.buyAmountsOkb.length) {
95
91
  throw new Error('[buildWashOps] 私钥数量与买入金额数量不一致');
96
92
  }
97
93
  // ✅ 归一化配置,填充默认值(与前端 normalizeXLayerAAConfig 保持一致)
98
94
  const config = normalizeConfig(params.config);
99
95
  const aaManager = createAAAccountManager(config);
96
+ // ✅ V3 模式:直接从链上读取 lpFeeProfile 获取正确的 fee(与 bundleGraduateBuy 保持一致)
97
+ // 不再依赖前端传入的 v3Fee 参数,避免前端传入错误值导致交易失败
98
+ let v3Fee = params.v3Fee || 2500;
99
+ if (poolType === 'v3') {
100
+ try {
101
+ const portalQuery = new PortalQuery({ rpcUrl: config.rpcUrl, chainId: config.chainId });
102
+ const tokenState = await portalQuery.getTokenV7(params.tokenAddress);
103
+ const correctV3Fee = lpFeeProfileToV3Fee(tokenState.lpFeeProfile);
104
+ if (correctV3Fee !== v3Fee) {
105
+ console.log(`[buildWashOps] V3 Fee 校正: 前端传入 ${v3Fee}, 链上 lpFeeProfile=${tokenState.lpFeeProfile} → 正确 fee=${correctV3Fee}`);
106
+ }
107
+ v3Fee = correctV3Fee;
108
+ }
109
+ catch (e) {
110
+ console.warn(`[buildWashOps] 读取 lpFeeProfile 失败,使用前端传入的 v3Fee=${v3Fee}:`, e);
111
+ }
112
+ }
100
113
  // ✅ 预先过滤无效私钥并保持索引对应
101
114
  const validEntries = [];
102
115
  for (let i = 0; i < params.ownerPrivateKeys.length; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.6.62",
3
+ "version": "1.6.63",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",