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);
|
package/dist/xlayer/wash-ops.js
CHANGED
|
@@ -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++) {
|