four-flap-meme-sdk 1.7.26 → 1.7.28
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/contracts/tm-bundle-merkle/utils.js +2 -2
- package/dist/eip7702/xlayer/bundle-create.js +35 -15
- package/dist/eip7702/xlayer/constants.d.ts +2 -2
- package/dist/eip7702/xlayer/constants.js +2 -2
- package/dist/utils/erc20.d.ts +4 -0
- package/dist/utils/erc20.js +8 -6
- package/package.json +2 -2
|
@@ -10,8 +10,8 @@ import { getErc20DecimalsMerkle as _getErc20DecimalsMerkle, generateHopWallets a
|
|
|
10
10
|
*/
|
|
11
11
|
function getProfitRateBps(userType) {
|
|
12
12
|
if (userType === 'v1')
|
|
13
|
-
return PROFIT_CONFIG.
|
|
14
|
-
return PROFIT_CONFIG.
|
|
13
|
+
return PROFIT_CONFIG.RATE_BPS_V1_DOUBLE; // v1 用户:万分之5
|
|
14
|
+
return PROFIT_CONFIG.RATE_BPS_V0_DOUBLE; // v0 用户(默认):万分之6
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* 计算利润金额
|
|
@@ -52,18 +52,35 @@ function encodeCreateCallV4(params) {
|
|
|
52
52
|
return portalIface.encodeFunctionData('newTokenV4', [params]);
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* 编码内盘买入调用
|
|
55
|
+
* 编码内盘买入调用
|
|
56
|
+
*
|
|
57
|
+
* 根据是否需要 extensionData 选择使用 swapExactInput 或 swapExactInputV3
|
|
58
|
+
* - V2 代币:使用 swapExactInput(无 extensionData)
|
|
59
|
+
* - V3/V4 代币:使用 swapExactInputV3(支持 extensionData)
|
|
56
60
|
*/
|
|
57
|
-
function encodeFlapBuyCall(tokenAddress, inputAmount, extensionData = '0x') {
|
|
61
|
+
function encodeFlapBuyCall(tokenAddress, inputAmount, useV3OrV4 = false, extensionData = '0x') {
|
|
58
62
|
const portalIface = new Interface(FLAP_PORTAL_ABI);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
if (useV3OrV4) {
|
|
64
|
+
// V3/V4 代币使用 swapExactInputV3(支持 extensionData)
|
|
65
|
+
return portalIface.encodeFunctionData('swapExactInputV3', [{
|
|
66
|
+
inputToken: ZERO_ADDRESS,
|
|
67
|
+
outputToken: tokenAddress,
|
|
68
|
+
inputAmount,
|
|
69
|
+
minOutputAmount: 0n,
|
|
70
|
+
permitData: '0x',
|
|
71
|
+
extensionData,
|
|
72
|
+
}]);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// V2 代币使用 swapExactInput
|
|
76
|
+
return portalIface.encodeFunctionData('swapExactInput', [{
|
|
77
|
+
inputToken: ZERO_ADDRESS,
|
|
78
|
+
outputToken: tokenAddress,
|
|
79
|
+
inputAmount,
|
|
80
|
+
minOutputAmount: 0n,
|
|
81
|
+
permitData: '0x',
|
|
82
|
+
}]);
|
|
83
|
+
}
|
|
67
84
|
}
|
|
68
85
|
/**
|
|
69
86
|
* 编码外盘 V3 买入调用
|
|
@@ -226,11 +243,12 @@ export async function bundleCreateBuy(params) {
|
|
|
226
243
|
});
|
|
227
244
|
// 3. 买家买入
|
|
228
245
|
const extensionData = params.extensionData ?? '0x';
|
|
246
|
+
const useV3OrV4 = useV4 || useV3; // 根据代币版本选择买入函数
|
|
229
247
|
for (let i = 0; i < buyerWallets.length; i++) {
|
|
230
248
|
const buyerWallet = buyerWallets[i];
|
|
231
249
|
const buyAmount = buyAmountsWei[i];
|
|
232
|
-
// 使用 executeBatch 从 buyerWallet 调用 Portal
|
|
233
|
-
const buyData = encodeFlapBuyCall(tokenAddress, buyAmount, extensionData);
|
|
250
|
+
// 使用 executeBatch 从 buyerWallet 调用 Portal
|
|
251
|
+
const buyData = encodeFlapBuyCall(tokenAddress, buyAmount, useV3OrV4, extensionData);
|
|
234
252
|
const buyBatchCall = delegateInterface.encodeFunctionData('executeBatch', [[{
|
|
235
253
|
target: FLAP_PORTAL_ADDRESS,
|
|
236
254
|
value: buyAmount,
|
|
@@ -347,12 +365,12 @@ export async function bundleCreateToDex(params) {
|
|
|
347
365
|
value: params.quoteAmt ?? 0n,
|
|
348
366
|
callData: createBatchCall,
|
|
349
367
|
});
|
|
350
|
-
// 3.
|
|
368
|
+
// 3. 内盘买入(一键发射始终使用 V4,所以 useV3OrV4 = true)
|
|
351
369
|
const extensionData = params.extensionData ?? '0x';
|
|
352
370
|
for (let i = 0; i < curveBuyerWallets.length; i++) {
|
|
353
371
|
const buyerWallet = curveBuyerWallets[i];
|
|
354
372
|
const buyAmount = curveBuyAmountsWei[i];
|
|
355
|
-
const buyData = encodeFlapBuyCall(tokenAddress, buyAmount, extensionData);
|
|
373
|
+
const buyData = encodeFlapBuyCall(tokenAddress, buyAmount, true, extensionData);
|
|
356
374
|
const buyBatchCall = delegateInterface.encodeFunctionData('executeBatch', [[{
|
|
357
375
|
target: FLAP_PORTAL_ADDRESS,
|
|
358
376
|
value: buyAmount,
|
|
@@ -547,9 +565,11 @@ export async function bundleGraduateBuy(params) {
|
|
|
547
565
|
calls.push(buildProfitCall(payerWallet.address, profitAmount, profitRecipient, delegateInterface));
|
|
548
566
|
}
|
|
549
567
|
// 2. 内盘买入
|
|
568
|
+
// lpFeeProfile >= 0 表示 V3 池子,需要使用 swapExactInputV3
|
|
569
|
+
const useV3OrV4 = lpFeeProfile !== undefined && lpFeeProfile >= 0;
|
|
550
570
|
for (let i = 0; i < curveBuyers.length; i++) {
|
|
551
571
|
const { wallet, amount } = curveBuyers[i];
|
|
552
|
-
const buyData = encodeFlapBuyCall(tokenAddress, amount, extensionData);
|
|
572
|
+
const buyData = encodeFlapBuyCall(tokenAddress, amount, useV3OrV4, extensionData);
|
|
553
573
|
const buyBatchCall = delegateInterface.encodeFunctionData('executeBatch', [[{
|
|
554
574
|
target: FLAP_PORTAL_ADDRESS,
|
|
555
575
|
value: amount,
|
|
@@ -31,11 +31,11 @@ export declare const PROFIT_CONFIG: {
|
|
|
31
31
|
/** 利润比例(换手模式):6 bps = 0.06% */
|
|
32
32
|
readonly RATE_BPS_SWAP: 6;
|
|
33
33
|
/** 利润比例(单边基点):8 bps = 0.08%(用户类型 v0) */
|
|
34
|
-
readonly RATE_BPS_V0:
|
|
34
|
+
readonly RATE_BPS_V0: 4;
|
|
35
35
|
/** 利润比例(双边基点):4 bps = 0.04%(用户类型 v0) */
|
|
36
36
|
readonly RATE_BPS_V0_DOUBLE: 4;
|
|
37
37
|
/** 利润比例(单边基点):10 bps = 0.10%(用户类型 v1) */
|
|
38
|
-
readonly RATE_BPS_V1:
|
|
38
|
+
readonly RATE_BPS_V1: 5;
|
|
39
39
|
/** 利润比例(双边基点):5 bps = 0.05%(用户类型 v1) */
|
|
40
40
|
readonly RATE_BPS_V1_DOUBLE: 5;
|
|
41
41
|
};
|
|
@@ -43,11 +43,11 @@ export const PROFIT_CONFIG = {
|
|
|
43
43
|
/** 利润比例(换手模式):6 bps = 0.06% */
|
|
44
44
|
RATE_BPS_SWAP: 6,
|
|
45
45
|
/** 利润比例(单边基点):8 bps = 0.08%(用户类型 v0) */
|
|
46
|
-
RATE_BPS_V0:
|
|
46
|
+
RATE_BPS_V0: 4,
|
|
47
47
|
/** 利润比例(双边基点):4 bps = 0.04%(用户类型 v0) */
|
|
48
48
|
RATE_BPS_V0_DOUBLE: 4,
|
|
49
49
|
/** 利润比例(单边基点):10 bps = 0.10%(用户类型 v1) */
|
|
50
|
-
RATE_BPS_V1:
|
|
50
|
+
RATE_BPS_V1: 5,
|
|
51
51
|
/** 利润比例(双边基点):5 bps = 0.05%(用户类型 v1) */
|
|
52
52
|
RATE_BPS_V1_DOUBLE: 5,
|
|
53
53
|
};
|
package/dist/utils/erc20.d.ts
CHANGED
|
@@ -176,6 +176,8 @@ export type ApproveTokenBatchParams = {
|
|
|
176
176
|
gasLimit?: number;
|
|
177
177
|
/** 链ID(可选,默认56=BSC,signOnly=true 时生效) */
|
|
178
178
|
chainId?: number;
|
|
179
|
+
/** 跳过合约地址验证(可选,用于某些特殊场景) */
|
|
180
|
+
skipValidation?: boolean;
|
|
179
181
|
};
|
|
180
182
|
export type ApproveTokenBatchRawParams = {
|
|
181
183
|
rpcUrl: string;
|
|
@@ -193,6 +195,8 @@ export type ApproveTokenBatchRawParams = {
|
|
|
193
195
|
chainId?: number;
|
|
194
196
|
/** 外部 NonceManager(可选,用于同一钱包签多笔交易时共享 nonce 状态) */
|
|
195
197
|
nonceManager?: NonceManager;
|
|
198
|
+
/** 跳过合约地址验证(可选,用于某些特殊场景,如 RPC 返回异常时) */
|
|
199
|
+
skipValidation?: boolean;
|
|
196
200
|
};
|
|
197
201
|
/** signOnly=false 时的返回结果(直接发送交易) */
|
|
198
202
|
export type ApproveTokenBatchResult = {
|
package/dist/utils/erc20.js
CHANGED
|
@@ -483,12 +483,12 @@ export async function checkAllowanceBatchRaw(rpcUrl, tokenAddress, ownerAddresse
|
|
|
483
483
|
return batchCheckAllowances(provider, normalizedToken, normalizedOwners, normalizedSpender);
|
|
484
484
|
}
|
|
485
485
|
export async function approveTokenBatch(params) {
|
|
486
|
-
const { chain, platform, rpcUrl, privateKeys, tokenAddress, amounts, signOnly, gasPriceGwei, gasLimit, chainId } = params;
|
|
486
|
+
const { chain, platform, rpcUrl, privateKeys, tokenAddress, amounts, signOnly, gasPriceGwei, gasLimit, chainId, skipValidation } = params;
|
|
487
487
|
const spenderAddress = resolveSpenderAddress(chain, platform);
|
|
488
|
-
return approveTokenBatchRaw({ rpcUrl, privateKeys, tokenAddress, spenderAddress, amounts, signOnly, gasPriceGwei, gasLimit, chainId });
|
|
488
|
+
return approveTokenBatchRaw({ rpcUrl, privateKeys, tokenAddress, spenderAddress, amounts, signOnly, gasPriceGwei, gasLimit, chainId, skipValidation });
|
|
489
489
|
}
|
|
490
490
|
export async function approveTokenBatchRaw(params) {
|
|
491
|
-
const { rpcUrl, privateKeys, tokenAddress, spenderAddress, amounts, signOnly, gasPriceGwei, gasLimit, chainId = 56, nonceManager: externalNonceManager } = params;
|
|
491
|
+
const { rpcUrl, privateKeys, tokenAddress, spenderAddress, amounts, signOnly, gasPriceGwei, gasLimit, chainId = 56, nonceManager: externalNonceManager, skipValidation } = params;
|
|
492
492
|
if (privateKeys.length === 0 || amounts.length !== privateKeys.length) {
|
|
493
493
|
throw new Error('❌ 私钥数量和授权数量必须匹配');
|
|
494
494
|
}
|
|
@@ -496,9 +496,11 @@ export async function approveTokenBatchRaw(params) {
|
|
|
496
496
|
// ✅ 规范化地址(转为小写,避免 checksum 错误)
|
|
497
497
|
const normalizedToken = tokenAddress.toLowerCase();
|
|
498
498
|
const normalizedSpender = spenderAddress.toLowerCase();
|
|
499
|
-
//
|
|
500
|
-
|
|
501
|
-
|
|
499
|
+
// 验证地址(如果 skipValidation=true 则跳过)
|
|
500
|
+
if (!skipValidation) {
|
|
501
|
+
await validateContractAddress(provider, normalizedToken, 'Token');
|
|
502
|
+
await validateContractAddress(provider, normalizedSpender, 'Spender');
|
|
503
|
+
}
|
|
502
504
|
// ✅ 优化:批量创建钱包和合约实例
|
|
503
505
|
const wallets = privateKeys.map(key => new Wallet(key, provider));
|
|
504
506
|
const ownerAddresses = wallets.map(w => w.address);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "four-flap-meme-sdk",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.28",
|
|
4
4
|
"description": "SDK for Flap bonding curve and four.meme TokenManager",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -38,4 +38,4 @@
|
|
|
38
38
|
"solc": "^0.8.33",
|
|
39
39
|
"typescript": "^5.6.3"
|
|
40
40
|
}
|
|
41
|
-
}
|
|
41
|
+
}
|