four-flap-meme-sdk 1.2.13 → 1.2.15
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/config.d.ts +9 -8
- package/dist/contracts/tm-bundle-merkle/core.d.ts +10 -10
- package/dist/contracts/tm-bundle-merkle/core.js +16 -23
- package/dist/contracts/tm-bundle-merkle/submit.d.ts +18 -9
- package/dist/contracts/tm-bundle-merkle/submit.js +48 -26
- package/dist/contracts/tm-bundle-merkle/types.d.ts +93 -0
- package/dist/contracts/tm-bundle-merkle/utils.d.ts +11 -3
- package/dist/contracts/tm-bundle-merkle/utils.js +19 -7
- package/dist/flap/portal-bundle-merkle/core.d.ts +7 -5
- package/dist/flap/portal-bundle-merkle/core.js +12 -13
- package/dist/flap/portal-bundle-merkle/pancake-proxy.d.ts +9 -4
- package/dist/flap/portal-bundle-merkle/pancake-proxy.js +12 -11
- package/dist/flap/portal-bundle-merkle/types.d.ts +64 -0
- package/dist/index.d.ts +3 -3
- package/dist/utils/airdrop-sweep.d.ts +44 -2
- package/dist/utils/airdrop-sweep.js +20 -13
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { FourBundleMerkleConfig } from './types.js';
|
|
2
|
-
export type { FourBundleMerkleConfig };
|
|
1
|
+
import type { FourBundleMerkleConfig, FourSignConfig } from './types.js';
|
|
2
|
+
export type { FourBundleMerkleConfig, FourSignConfig };
|
|
3
|
+
export type FourAnyConfig = FourBundleMerkleConfig | FourSignConfig;
|
|
3
4
|
export declare const ERRORS: {
|
|
4
5
|
NO_PRIVATE_KEY: {
|
|
5
6
|
en: string;
|
|
@@ -23,27 +24,27 @@ export declare const ERRORS: {
|
|
|
23
24
|
};
|
|
24
25
|
};
|
|
25
26
|
export declare function getErrorMessage(key: keyof typeof ERRORS, ...args: any[]): string;
|
|
26
|
-
export declare function getTxType(config:
|
|
27
|
-
export declare function getGasPriceMultiplier(config:
|
|
27
|
+
export declare function getTxType(config: FourAnyConfig): 0 | 2;
|
|
28
|
+
export declare function getGasPriceMultiplier(config: FourAnyConfig): number;
|
|
28
29
|
export declare function getBundleOptions(config: FourBundleMerkleConfig, blockOffset?: number): {
|
|
29
30
|
blockOffset: number;
|
|
30
31
|
minBlockOffset: number;
|
|
31
32
|
autoRetry: boolean;
|
|
32
33
|
maxRetries: number;
|
|
33
34
|
};
|
|
34
|
-
export declare function getGasPriceConfig(config:
|
|
35
|
+
export declare function getGasPriceConfig(config: FourAnyConfig): any;
|
|
35
36
|
/**
|
|
36
37
|
* 判断是否需要提取利润
|
|
37
38
|
*/
|
|
38
|
-
export declare function shouldExtractProfit(config:
|
|
39
|
+
export declare function shouldExtractProfit(config: FourAnyConfig): boolean;
|
|
39
40
|
/**
|
|
40
41
|
* 获取利润比例(基点)
|
|
41
42
|
*/
|
|
42
|
-
export declare function getProfitRateBps(config:
|
|
43
|
+
export declare function getProfitRateBps(config: FourAnyConfig): number;
|
|
43
44
|
/**
|
|
44
45
|
* 计算利润金额
|
|
45
46
|
*/
|
|
46
|
-
export declare function calculateProfit(amount: bigint, config:
|
|
47
|
+
export declare function calculateProfit(amount: bigint, config: FourAnyConfig): {
|
|
47
48
|
profit: bigint;
|
|
48
49
|
remaining: bigint;
|
|
49
50
|
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FourCreateWithBundleBuySignParams, FourCreateWithBundleBuyMerkleResult, FourBatchBuySignParams, FourBatchBuyMerkleResult, FourBatchSellSignParams, FourBatchSellMerkleResult } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* four.meme: 创建代币 +
|
|
3
|
+
* four.meme: 创建代币 + 捆绑购买(仅签名版本 - 不依赖 Merkle)
|
|
4
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
4
5
|
*
|
|
5
6
|
* ⚠️ 重要:
|
|
6
7
|
* - 创建代币:使用原始 four.meme 合约(不收费)
|
|
7
8
|
* - 购买交易:使用收费版合约
|
|
8
9
|
* - 创建者地址会被验证,确保与私钥匹配
|
|
9
10
|
*/
|
|
10
|
-
export declare function createTokenWithBundleBuyMerkle(params:
|
|
11
|
+
export declare function createTokenWithBundleBuyMerkle(params: FourCreateWithBundleBuySignParams): Promise<FourCreateWithBundleBuyMerkleResult>;
|
|
11
12
|
/**
|
|
12
|
-
* four.meme:
|
|
13
|
-
*
|
|
13
|
+
* four.meme: 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
14
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
14
15
|
*/
|
|
15
|
-
export declare function batchBuyWithBundleMerkle(params:
|
|
16
|
+
export declare function batchBuyWithBundleMerkle(params: FourBatchBuySignParams): Promise<FourBatchBuyMerkleResult>;
|
|
16
17
|
/**
|
|
17
|
-
* four.meme:
|
|
18
|
-
*
|
|
19
|
-
* ✅ 自动检查授权,智能处理授权+卖出
|
|
18
|
+
* four.meme: 批量卖出(仅签名版本 - 不依赖 Merkle)
|
|
19
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
20
20
|
*/
|
|
21
|
-
export declare function batchSellWithBundleMerkle(params:
|
|
21
|
+
export declare function batchSellWithBundleMerkle(params: FourBatchSellSignParams): Promise<FourBatchSellMerkleResult>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
|
-
import { MerkleClient } from '../../clients/merkle.js';
|
|
3
2
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
4
3
|
import { ADDRESSES } from '../../utils/constants.js';
|
|
5
4
|
import { FourClient, buildLoginMessage } from '../../clients/four.js';
|
|
@@ -32,7 +31,8 @@ function getGasLimit(config, defaultGas = 800000) {
|
|
|
32
31
|
return BigInt(calculatedGas);
|
|
33
32
|
}
|
|
34
33
|
/**
|
|
35
|
-
* four.meme: 创建代币 +
|
|
34
|
+
* four.meme: 创建代币 + 捆绑购买(仅签名版本 - 不依赖 Merkle)
|
|
35
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
36
36
|
*
|
|
37
37
|
* ⚠️ 重要:
|
|
38
38
|
* - 创建代币:使用原始 four.meme 合约(不收费)
|
|
@@ -49,15 +49,13 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
49
49
|
}
|
|
50
50
|
const creatorKey = privateKeys[0];
|
|
51
51
|
const buyerKeys = privateKeys.slice(1);
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
53
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
54
54
|
chainId: 56,
|
|
55
|
-
|
|
55
|
+
name: 'BSC'
|
|
56
56
|
});
|
|
57
|
-
const provider = merkle.getProvider();
|
|
58
57
|
const devWallet = new Wallet(creatorKey, provider);
|
|
59
58
|
const fourClient = new FourClient({ baseUrl: config.fourApiUrl });
|
|
60
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
61
59
|
// 1. 登录 four.meme
|
|
62
60
|
const nonce = await fourClient.generateNonce({
|
|
63
61
|
accountAddress: devWallet.address,
|
|
@@ -240,21 +238,19 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
240
238
|
};
|
|
241
239
|
}
|
|
242
240
|
/**
|
|
243
|
-
* four.meme:
|
|
244
|
-
*
|
|
241
|
+
* four.meme: 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
242
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
245
243
|
*/
|
|
246
244
|
export async function batchBuyWithBundleMerkle(params) {
|
|
247
245
|
const { privateKeys, buyAmounts, tokenAddress, config } = params;
|
|
248
246
|
if (privateKeys.length === 0 || buyAmounts.length !== privateKeys.length) {
|
|
249
247
|
throw new Error(getErrorMessage('KEY_AMOUNT_MISMATCH'));
|
|
250
248
|
}
|
|
251
|
-
|
|
252
|
-
|
|
249
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
250
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
253
251
|
chainId: 56,
|
|
254
|
-
|
|
252
|
+
name: 'BSC'
|
|
255
253
|
});
|
|
256
|
-
const provider = merkle.getProvider();
|
|
257
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
258
254
|
// 使用官方合约(内盘代币限制,无法使用代理)
|
|
259
255
|
const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
|
|
260
256
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
@@ -324,22 +320,19 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
324
320
|
};
|
|
325
321
|
}
|
|
326
322
|
/**
|
|
327
|
-
* four.meme:
|
|
328
|
-
*
|
|
329
|
-
* ✅ 自动检查授权,智能处理授权+卖出
|
|
323
|
+
* four.meme: 批量卖出(仅签名版本 - 不依赖 Merkle)
|
|
324
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
330
325
|
*/
|
|
331
326
|
export async function batchSellWithBundleMerkle(params) {
|
|
332
327
|
const { privateKeys, sellAmounts, tokenAddress, minOutputAmounts, config } = params;
|
|
333
328
|
if (privateKeys.length === 0 || sellAmounts.length !== privateKeys.length) {
|
|
334
329
|
throw new Error(getErrorMessage('SELL_KEY_AMOUNT_MISMATCH'));
|
|
335
330
|
}
|
|
336
|
-
|
|
337
|
-
|
|
331
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
332
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
338
333
|
chainId: 56,
|
|
339
|
-
|
|
334
|
+
name: 'BSC'
|
|
340
335
|
});
|
|
341
|
-
const provider = merkle.getProvider();
|
|
342
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
343
336
|
// 使用官方合约(内盘代币限制,无法使用代理)
|
|
344
337
|
const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
|
|
345
338
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
@@ -356,7 +349,7 @@ export async function batchSellWithBundleMerkle(params) {
|
|
|
356
349
|
}
|
|
357
350
|
else {
|
|
358
351
|
// ✅ 自动调用 trySell 获取每个钱包的预期收益
|
|
359
|
-
const rpcUrl = config.
|
|
352
|
+
const rpcUrl = config.rpcUrl;
|
|
360
353
|
quotedOutputs = await Promise.all(amountsWei.map(async (amount, i) => {
|
|
361
354
|
try {
|
|
362
355
|
const result = await trySell('BSC', rpcUrl, tokenAddress, amount);
|
|
@@ -26,14 +26,18 @@ export interface MerkleSubmitConfig {
|
|
|
26
26
|
* Bundle提交结果
|
|
27
27
|
*/
|
|
28
28
|
export interface SubmitBundleResult {
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
|
|
29
|
+
/** 提交状态:true=成功,false=失败 */
|
|
30
|
+
code: boolean;
|
|
31
|
+
/** Bundle哈希(成功时返回) */
|
|
32
|
+
bundleHash?: string;
|
|
33
|
+
/** 交易哈希列表(成功时返回) */
|
|
34
|
+
txHashes?: string[];
|
|
35
|
+
/** 目标区块号(成功时返回) */
|
|
36
|
+
targetBlock?: number;
|
|
37
|
+
/** 交易数量(成功时返回) */
|
|
38
|
+
txCount?: number;
|
|
39
|
+
/** 错误信息(失败时返回) */
|
|
40
|
+
error?: string;
|
|
37
41
|
}
|
|
38
42
|
/**
|
|
39
43
|
* 提交已签名的交易到Merkle(服务器端使用)
|
|
@@ -55,7 +59,12 @@ export interface SubmitBundleResult {
|
|
|
55
59
|
* bundleBlockOffset: 5
|
|
56
60
|
* });
|
|
57
61
|
*
|
|
58
|
-
*
|
|
62
|
+
* if (result.code) {
|
|
63
|
+
* console.log('✅ Bundle提交成功:', result.bundleHash);
|
|
64
|
+
* console.log('交易哈希:', result.txHashes);
|
|
65
|
+
* } else {
|
|
66
|
+
* console.error('❌ Bundle提交失败:', result.error);
|
|
67
|
+
* }
|
|
59
68
|
* ```
|
|
60
69
|
*/
|
|
61
70
|
export declare function submitBundleToMerkle(signedTransactions: string[], config: MerkleSubmitConfig): Promise<SubmitBundleResult>;
|
|
@@ -24,37 +24,59 @@ import { MerkleClient } from '../../clients/merkle.js';
|
|
|
24
24
|
* bundleBlockOffset: 5
|
|
25
25
|
* });
|
|
26
26
|
*
|
|
27
|
-
*
|
|
27
|
+
* if (result.code) {
|
|
28
|
+
* console.log('✅ Bundle提交成功:', result.bundleHash);
|
|
29
|
+
* console.log('交易哈希:', result.txHashes);
|
|
30
|
+
* } else {
|
|
31
|
+
* console.error('❌ Bundle提交失败:', result.error);
|
|
32
|
+
* }
|
|
28
33
|
* ```
|
|
29
34
|
*/
|
|
30
35
|
export async function submitBundleToMerkle(signedTransactions, config) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
try {
|
|
37
|
+
// 验证输入
|
|
38
|
+
if (!signedTransactions || signedTransactions.length === 0) {
|
|
39
|
+
return {
|
|
40
|
+
code: false,
|
|
41
|
+
error: 'signedTransactions cannot be empty'
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (!config.apiKey) {
|
|
45
|
+
return {
|
|
46
|
+
code: false,
|
|
47
|
+
error: 'apiKey is required in config'
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// 初始化Merkle客户端
|
|
51
|
+
const merkle = new MerkleClient({
|
|
52
|
+
apiKey: config.apiKey,
|
|
53
|
+
chainId: config.chainId ?? 56,
|
|
54
|
+
customRpcUrl: config.customRpcUrl
|
|
55
|
+
});
|
|
56
|
+
// 提交Bundle
|
|
57
|
+
const bundleResult = await merkle.sendBundle({
|
|
58
|
+
transactions: signedTransactions,
|
|
59
|
+
blockOffset: config.bundleBlockOffset ?? 3,
|
|
60
|
+
minBlockOffset: config.minBlockOffset ?? 3,
|
|
61
|
+
autoRetry: config.autoRetryBundle ?? false,
|
|
62
|
+
maxRetries: config.maxBundleRetries ?? 2
|
|
63
|
+
});
|
|
64
|
+
// ✅ 提交成功
|
|
65
|
+
return {
|
|
66
|
+
code: true,
|
|
67
|
+
bundleHash: bundleResult.bundleHash,
|
|
68
|
+
txHashes: bundleResult.txHashes,
|
|
69
|
+
targetBlock: bundleResult.targetBlock,
|
|
70
|
+
txCount: bundleResult.txCount
|
|
71
|
+
};
|
|
34
72
|
}
|
|
35
|
-
|
|
36
|
-
|
|
73
|
+
catch (error) {
|
|
74
|
+
// ❌ 提交失败
|
|
75
|
+
return {
|
|
76
|
+
code: false,
|
|
77
|
+
error: error?.message || String(error)
|
|
78
|
+
};
|
|
37
79
|
}
|
|
38
|
-
// 初始化Merkle客户端
|
|
39
|
-
const merkle = new MerkleClient({
|
|
40
|
-
apiKey: config.apiKey,
|
|
41
|
-
chainId: config.chainId ?? 56,
|
|
42
|
-
customRpcUrl: config.customRpcUrl
|
|
43
|
-
});
|
|
44
|
-
// 提交Bundle
|
|
45
|
-
const bundleResult = await merkle.sendBundle({
|
|
46
|
-
transactions: signedTransactions,
|
|
47
|
-
blockOffset: config.bundleBlockOffset ?? 3,
|
|
48
|
-
minBlockOffset: config.minBlockOffset ?? 3,
|
|
49
|
-
autoRetry: config.autoRetryBundle ?? false,
|
|
50
|
-
maxRetries: config.maxBundleRetries ?? 2
|
|
51
|
-
});
|
|
52
|
-
return {
|
|
53
|
-
bundleHash: bundleResult.bundleHash,
|
|
54
|
-
txHashes: bundleResult.txHashes,
|
|
55
|
-
targetBlock: bundleResult.targetBlock,
|
|
56
|
-
txCount: bundleResult.txCount
|
|
57
|
-
};
|
|
58
80
|
}
|
|
59
81
|
/**
|
|
60
82
|
* 批量提交多个Bundle到Merkle(顺序执行)
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
export type FourSignConfig = {
|
|
2
|
+
rpcUrl: string;
|
|
3
|
+
fourApiUrl?: string;
|
|
4
|
+
txType?: 0 | 2;
|
|
5
|
+
gasLimit?: number | bigint;
|
|
6
|
+
gasLimitMultiplier?: number;
|
|
7
|
+
gasPriceMultiplierPercent?: number;
|
|
8
|
+
minGasPriceGwei?: number;
|
|
9
|
+
chainId?: number;
|
|
10
|
+
prefer21000ForNative?: boolean;
|
|
11
|
+
checkBnbForErc20NoHop?: boolean;
|
|
12
|
+
profitRecipient?: string;
|
|
13
|
+
profitRateBps?: number;
|
|
14
|
+
};
|
|
1
15
|
export type FourBundleMerkleConfig = {
|
|
2
16
|
apiKey: string;
|
|
3
17
|
customRpcUrl?: string;
|
|
@@ -55,6 +69,7 @@ export type MerkleSignedResult = {
|
|
|
55
69
|
[key: string]: any;
|
|
56
70
|
};
|
|
57
71
|
};
|
|
72
|
+
/** ✅ 创建代币 + 购买参数(Merkle 版本 - 完整) */
|
|
58
73
|
export type FourCreateWithBundleBuyMerkleParams = {
|
|
59
74
|
privateKeys: string[];
|
|
60
75
|
buyAmounts: string[];
|
|
@@ -73,19 +88,47 @@ export type FourCreateWithBundleBuyMerkleParams = {
|
|
|
73
88
|
};
|
|
74
89
|
config: FourBundleMerkleConfig;
|
|
75
90
|
};
|
|
91
|
+
/** ✅ 创建代币 + 购买参数(仅签名版本 - 精简) */
|
|
92
|
+
export type FourCreateWithBundleBuySignParams = {
|
|
93
|
+
privateKeys: string[];
|
|
94
|
+
buyAmounts: string[];
|
|
95
|
+
b0Amount?: string;
|
|
96
|
+
tokenInfo: {
|
|
97
|
+
name: string;
|
|
98
|
+
symbol: string;
|
|
99
|
+
description: string;
|
|
100
|
+
imageUrl?: string;
|
|
101
|
+
imageFile?: Blob;
|
|
102
|
+
label?: 'Meme' | 'AI' | 'Defi' | 'Games' | 'Infra' | 'De-Sci' | 'Social' | 'Depin' | 'Charity' | 'Others';
|
|
103
|
+
preSale?: string;
|
|
104
|
+
webUrl?: string;
|
|
105
|
+
twitterUrl?: string;
|
|
106
|
+
telegramUrl?: string;
|
|
107
|
+
};
|
|
108
|
+
config: FourSignConfig;
|
|
109
|
+
};
|
|
76
110
|
/**
|
|
77
111
|
* ✅ 创建代币 + 购买结果(简化版)
|
|
78
112
|
* 包含 tokenAddress 用于返回创建的代币地址
|
|
79
113
|
*/
|
|
80
114
|
export type FourCreateWithBundleBuyMerkleResult = MerkleSignedResult;
|
|
115
|
+
/** ✅ 批量购买参数(Merkle 版本 - 完整) */
|
|
81
116
|
export type FourBatchBuyMerkleParams = {
|
|
82
117
|
privateKeys: string[];
|
|
83
118
|
buyAmounts: string[];
|
|
84
119
|
tokenAddress: string;
|
|
85
120
|
config: FourBundleMerkleConfig;
|
|
86
121
|
};
|
|
122
|
+
/** ✅ 批量购买参数(仅签名版本 - 精简) */
|
|
123
|
+
export type FourBatchBuySignParams = {
|
|
124
|
+
privateKeys: string[];
|
|
125
|
+
buyAmounts: string[];
|
|
126
|
+
tokenAddress: string;
|
|
127
|
+
config: FourSignConfig;
|
|
128
|
+
};
|
|
87
129
|
/** ✅ 批量购买结果(简化版) */
|
|
88
130
|
export type FourBatchBuyMerkleResult = MerkleSignedResult;
|
|
131
|
+
/** ✅ 批量卖出参数(Merkle 版本 - 完整) */
|
|
89
132
|
export type FourBatchSellMerkleParams = {
|
|
90
133
|
privateKeys: string[];
|
|
91
134
|
sellAmounts: string[];
|
|
@@ -93,6 +136,14 @@ export type FourBatchSellMerkleParams = {
|
|
|
93
136
|
minOutputAmounts?: (string | bigint)[];
|
|
94
137
|
config: FourBundleMerkleConfig;
|
|
95
138
|
};
|
|
139
|
+
/** ✅ 批量卖出参数(仅签名版本 - 精简) */
|
|
140
|
+
export type FourBatchSellSignParams = {
|
|
141
|
+
privateKeys: string[];
|
|
142
|
+
sellAmounts: string[];
|
|
143
|
+
tokenAddress: string;
|
|
144
|
+
minOutputAmounts?: (string | bigint)[];
|
|
145
|
+
config: FourSignConfig;
|
|
146
|
+
};
|
|
96
147
|
/** ✅ 批量卖出结果(简化版) */
|
|
97
148
|
export type FourBatchSellMerkleResult = MerkleSignedResult;
|
|
98
149
|
export type FourPrivateMerkleBase = {
|
|
@@ -125,6 +176,7 @@ export type FourBatchPrivateSellMerkleParams = FourPrivateMerkleBase & {
|
|
|
125
176
|
};
|
|
126
177
|
/** ✅ 批量私有交易结果(简化版) */
|
|
127
178
|
export type FourBatchPrivateMerkleResult = MerkleSignedResult;
|
|
179
|
+
/** ✅ 分发参数(Merkle 版本 - 完整) */
|
|
128
180
|
export type DisperseMerkleParams = {
|
|
129
181
|
fromPrivateKey: string;
|
|
130
182
|
recipients: string[];
|
|
@@ -142,11 +194,30 @@ export type DisperseMerkleParams = {
|
|
|
142
194
|
}>;
|
|
143
195
|
config: FourBundleMerkleConfig;
|
|
144
196
|
};
|
|
197
|
+
/** ✅ 分发参数(仅签名版本 - 精简) */
|
|
198
|
+
export type DisperseSignParams = {
|
|
199
|
+
fromPrivateKey: string;
|
|
200
|
+
recipients: string[];
|
|
201
|
+
amount?: AmountLike;
|
|
202
|
+
amounts?: AmountLike[];
|
|
203
|
+
tokenAddress?: string;
|
|
204
|
+
tokenDecimals?: number;
|
|
205
|
+
hopCount?: number | number[];
|
|
206
|
+
hopPrivateKeys?: string[][];
|
|
207
|
+
items?: Array<{
|
|
208
|
+
to: string;
|
|
209
|
+
amount: AmountLike;
|
|
210
|
+
hopCount?: number;
|
|
211
|
+
hopPrivateKeys?: string[];
|
|
212
|
+
}>;
|
|
213
|
+
config: FourSignConfig;
|
|
214
|
+
};
|
|
145
215
|
/**
|
|
146
216
|
* ✅ 分发结果(简化版)
|
|
147
217
|
* 包含 hopWallets 用于返回生成的多跳钱包私钥
|
|
148
218
|
*/
|
|
149
219
|
export type DisperseMerkleResult = MerkleSignedResult;
|
|
220
|
+
/** ✅ 归集参数(Merkle 版本 - 完整) */
|
|
150
221
|
export type SweepMerkleParams = {
|
|
151
222
|
sourcePrivateKeys: string[];
|
|
152
223
|
target: string;
|
|
@@ -168,6 +239,28 @@ export type SweepMerkleParams = {
|
|
|
168
239
|
}>;
|
|
169
240
|
config: FourBundleMerkleConfig;
|
|
170
241
|
};
|
|
242
|
+
/** ✅ 归集参数(仅签名版本 - 精简) */
|
|
243
|
+
export type SweepSignParams = {
|
|
244
|
+
sourcePrivateKeys: string[];
|
|
245
|
+
target: string;
|
|
246
|
+
ratioPct?: number;
|
|
247
|
+
ratios?: number[];
|
|
248
|
+
amount?: AmountLike;
|
|
249
|
+
amounts?: AmountLike[];
|
|
250
|
+
tokenAddress?: string;
|
|
251
|
+
tokenDecimals?: number;
|
|
252
|
+
skipIfInsufficient?: boolean;
|
|
253
|
+
hopCount?: number | number[];
|
|
254
|
+
hopPrivateKeys?: string[][];
|
|
255
|
+
sources?: Array<{
|
|
256
|
+
privateKey: string;
|
|
257
|
+
ratioPct?: number;
|
|
258
|
+
amount?: AmountLike;
|
|
259
|
+
hopCount?: number;
|
|
260
|
+
hopPrivateKeys?: string[];
|
|
261
|
+
}>;
|
|
262
|
+
config: FourSignConfig;
|
|
263
|
+
};
|
|
171
264
|
/**
|
|
172
265
|
* ✅ 归集结果(简化版)
|
|
173
266
|
* 包含 hopWallets 用于返回生成的多跳钱包私钥
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { DisperseSignParams, DisperseMerkleResult, SweepSignParams, SweepMerkleResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 分发(仅签名版本 - 不依赖 Merkle)
|
|
4
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
5
|
+
*/
|
|
6
|
+
export declare function disperseWithBundleMerkle(params: DisperseSignParams): Promise<DisperseMerkleResult>;
|
|
7
|
+
/**
|
|
8
|
+
* 归集(仅签名版本 - 不依赖 Merkle)
|
|
9
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
10
|
+
*/
|
|
11
|
+
export declare function sweepWithBundleMerkle(params: SweepSignParams): Promise<SweepMerkleResult>;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
|
-
import { MerkleClient } from '../../clients/merkle.js';
|
|
2
|
+
// import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { getOptimizedGasPrice, NonceManager } from '../../utils/bundle-helpers.js';
|
|
4
4
|
import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit } from './config.js';
|
|
5
5
|
import { getErc20DecimalsMerkle as _getErc20DecimalsMerkle, generateHopWallets as _generateHopWallets, normalizeAmounts as _normalizeAmounts, batchGetBalances as _batchGetBalances, calculateGasLimit as _calculateGasLimit, isNativeTokenAddress as _isNativeTokenAddress } from './internal.js';
|
|
6
|
+
/**
|
|
7
|
+
* 分发(仅签名版本 - 不依赖 Merkle)
|
|
8
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
9
|
+
*/
|
|
6
10
|
export async function disperseWithBundleMerkle(params) {
|
|
7
11
|
const { fromPrivateKey, recipients, amount, amounts, tokenAddress, tokenDecimals, hopCount = 0, hopPrivateKeys, items, config } = params;
|
|
8
12
|
// 快速返回空结果
|
|
@@ -14,13 +18,15 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
14
18
|
}
|
|
15
19
|
// 初始化
|
|
16
20
|
const chainIdNum = config.chainId ?? 56;
|
|
17
|
-
|
|
18
|
-
const provider =
|
|
21
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
22
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
23
|
+
chainId: chainIdNum,
|
|
24
|
+
name: 'BSC'
|
|
25
|
+
});
|
|
19
26
|
const [gasPrice, mainWallet] = await Promise.all([
|
|
20
27
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
21
28
|
Promise.resolve(new Wallet(fromPrivateKey, provider))
|
|
22
29
|
]);
|
|
23
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
24
30
|
const isNative = _isNativeTokenAddress(tokenAddress);
|
|
25
31
|
// 统一金额处理
|
|
26
32
|
const normalizedAmounts = items && items.length > 0
|
|
@@ -267,6 +273,10 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
267
273
|
} : undefined
|
|
268
274
|
};
|
|
269
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* 归集(仅签名版本 - 不依赖 Merkle)
|
|
278
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
279
|
+
*/
|
|
270
280
|
export async function sweepWithBundleMerkle(params) {
|
|
271
281
|
const { sourcePrivateKeys, target, ratioPct, ratios, amount, amounts, tokenAddress, tokenDecimals, skipIfInsufficient = true, hopCount = 0, hopPrivateKeys, sources, config } = params;
|
|
272
282
|
// 快速返回空结果
|
|
@@ -278,10 +288,12 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
278
288
|
}
|
|
279
289
|
// 初始化
|
|
280
290
|
const chainIdNum = config.chainId ?? 56;
|
|
281
|
-
|
|
282
|
-
const provider =
|
|
291
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
292
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
293
|
+
chainId: chainIdNum,
|
|
294
|
+
name: 'BSC'
|
|
295
|
+
});
|
|
283
296
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
284
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
285
297
|
const isNative = _isNativeTokenAddress(tokenAddress);
|
|
286
298
|
// 归集比例处理
|
|
287
299
|
const clamp = (n) => (typeof n === 'number' && Number.isFinite(n) ? Math.max(0, Math.min(100, Math.floor(n))) : undefined);
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FlapCreateWithBundleBuySignParams, FlapCreateWithBundleBuyMerkleResult, FlapBatchBuySignParams, FlapBatchBuyMerkleResult, FlapBatchSellSignParams, FlapBatchSellMerkleResult } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Flap Protocol: 创建代币 +
|
|
3
|
+
* Flap Protocol: 创建代币 + 捆绑购买(仅签名版本 - 不依赖 Merkle)
|
|
4
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
4
5
|
*/
|
|
5
|
-
export declare function createTokenWithBundleBuyMerkle(params:
|
|
6
|
+
export declare function createTokenWithBundleBuyMerkle(params: FlapCreateWithBundleBuySignParams): Promise<FlapCreateWithBundleBuyMerkleResult>;
|
|
6
7
|
/**
|
|
7
|
-
* Flap Protocol:
|
|
8
|
+
* Flap Protocol: 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
9
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
8
10
|
*/
|
|
9
|
-
export declare function batchBuyWithBundleMerkle(params:
|
|
11
|
+
export declare function batchBuyWithBundleMerkle(params: FlapBatchBuySignParams): Promise<FlapBatchBuyMerkleResult>;
|
|
10
12
|
/**
|
|
11
13
|
* Flap Protocol: 批量卖出(仅签名版本 - 不依赖 Merkle)
|
|
12
14
|
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
|
-
import { MerkleClient } from '../../clients/merkle.js';
|
|
2
|
+
// import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
4
4
|
import { FLAP_PORTAL_ADDRESSES, FLAP_ORIGINAL_PORTAL_ADDRESSES } from '../constants.js';
|
|
5
5
|
import { CHAIN_ID_MAP, PORTAL_ABI, getErrorMessage, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit } from './config.js';
|
|
@@ -22,7 +22,8 @@ function getGasLimit(config, defaultGas = 800000) {
|
|
|
22
22
|
return BigInt(calculatedGas);
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* Flap Protocol: 创建代币 +
|
|
25
|
+
* Flap Protocol: 创建代币 + 捆绑购买(仅签名版本 - 不依赖 Merkle)
|
|
26
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
26
27
|
*/
|
|
27
28
|
export async function createTokenWithBundleBuyMerkle(params) {
|
|
28
29
|
const { chain, privateKeys, buyAmounts, tokenInfo, quoteToken, tokenAddress, config } = params;
|
|
@@ -33,14 +34,12 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
33
34
|
throw new Error(getErrorMessage('AMOUNT_MISMATCH', buyAmounts.length, privateKeys.length - 1));
|
|
34
35
|
}
|
|
35
36
|
const chainId = CHAIN_ID_MAP[chain];
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
38
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
38
39
|
chainId: chainId,
|
|
39
|
-
|
|
40
|
+
name: chain
|
|
40
41
|
});
|
|
41
|
-
const provider = merkle.getProvider();
|
|
42
42
|
const devWallet = new Wallet(privateKeys[0], provider);
|
|
43
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
44
43
|
const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
|
|
45
44
|
const originalPortalAddr = FLAP_ORIGINAL_PORTAL_ADDRESSES[chain];
|
|
46
45
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
@@ -180,7 +179,8 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
180
179
|
};
|
|
181
180
|
}
|
|
182
181
|
/**
|
|
183
|
-
* Flap Protocol:
|
|
182
|
+
* Flap Protocol: 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
183
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
184
184
|
*/
|
|
185
185
|
export async function batchBuyWithBundleMerkle(params) {
|
|
186
186
|
const { chain, privateKeys, buyAmounts, tokenAddress, config } = params;
|
|
@@ -188,13 +188,11 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
188
188
|
throw new Error(getErrorMessage('KEY_AMOUNT_MISMATCH'));
|
|
189
189
|
}
|
|
190
190
|
const chainId = CHAIN_ID_MAP[chain];
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
192
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
193
193
|
chainId: chainId,
|
|
194
|
-
|
|
194
|
+
name: chain
|
|
195
195
|
});
|
|
196
|
-
const provider = merkle.getProvider();
|
|
197
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
198
196
|
const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
|
|
199
197
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
200
198
|
const signedTxs = [];
|
|
@@ -273,6 +271,7 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
273
271
|
*/
|
|
274
272
|
export async function batchSellWithBundleMerkle(params) {
|
|
275
273
|
const { chain, privateKeys, sellAmounts, tokenAddress, minOutputAmounts, config } = params;
|
|
274
|
+
console.log('config:', config);
|
|
276
275
|
if (privateKeys.length === 0 || sellAmounts.length !== privateKeys.length) {
|
|
277
276
|
throw new Error(getErrorMessage('SELL_KEY_AMOUNT_MISMATCH'));
|
|
278
277
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PancakeProxyBatchBuySignParams, PancakeProxyBatchBuyResult, PancakeProxyBatchSellSignParams, PancakeProxyBatchSellResult, PancakeProxyApprovalParams, PancakeProxyApprovalBatchParams, PancakeProxyApprovalBatchResult } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* 授权代币给 PancakeSwapProxy
|
|
4
4
|
*/
|
|
@@ -11,11 +11,16 @@ export declare function approvePancakeProxy(params: PancakeProxyApprovalParams):
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function approvePancakeProxyBatch(params: PancakeProxyApprovalBatchParams): Promise<PancakeProxyApprovalBatchResult>;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* PancakeSwapProxy 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
15
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
15
16
|
*/
|
|
16
|
-
export declare function pancakeProxyBatchBuyMerkle(params:
|
|
17
|
+
export declare function pancakeProxyBatchBuyMerkle(params: PancakeProxyBatchBuySignParams): Promise<PancakeProxyBatchBuyResult>;
|
|
17
18
|
/**
|
|
18
19
|
* 使用 PancakeSwapProxy 批量卖出代币(Merkle 版本)
|
|
19
20
|
* ✅ 自动检查授权,智能处理授权+卖出
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
+
/**
|
|
23
|
+
* PancakeSwapProxy 批量卖出(仅签名版本 - 不依赖 Merkle)
|
|
24
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
25
|
+
*/
|
|
26
|
+
export declare function pancakeProxyBatchSellMerkle(params: PancakeProxyBatchSellSignParams): Promise<PancakeProxyBatchSellResult>;
|
|
@@ -280,7 +280,8 @@ export async function approvePancakeProxyBatch(params) {
|
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
/**
|
|
283
|
-
*
|
|
283
|
+
* PancakeSwapProxy 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
284
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
284
285
|
*/
|
|
285
286
|
export async function pancakeProxyBatchBuyMerkle(params) {
|
|
286
287
|
const { chain, privateKeys, buyAmounts, tokenAddress, routeType, config } = params;
|
|
@@ -289,13 +290,11 @@ export async function pancakeProxyBatchBuyMerkle(params) {
|
|
|
289
290
|
}
|
|
290
291
|
const pancakeProxyAddress = ADDRESSES.BSC.PancakeProxy;
|
|
291
292
|
const chainId = CHAIN_ID_MAP[chain];
|
|
292
|
-
|
|
293
|
-
|
|
293
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
294
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
294
295
|
chainId: chainId,
|
|
295
|
-
|
|
296
|
+
name: chain
|
|
296
297
|
});
|
|
297
|
-
const provider = merkle.getProvider();
|
|
298
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
299
298
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
300
299
|
const buyers = privateKeys.map(k => new Wallet(k, provider));
|
|
301
300
|
const originalAmountsWei = buyAmounts.map(a => ethers.parseEther(a)); // BNB 固定 18 位
|
|
@@ -380,6 +379,10 @@ export async function pancakeProxyBatchBuyMerkle(params) {
|
|
|
380
379
|
* 使用 PancakeSwapProxy 批量卖出代币(Merkle 版本)
|
|
381
380
|
* ✅ 自动检查授权,智能处理授权+卖出
|
|
382
381
|
*/
|
|
382
|
+
/**
|
|
383
|
+
* PancakeSwapProxy 批量卖出(仅签名版本 - 不依赖 Merkle)
|
|
384
|
+
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
385
|
+
*/
|
|
383
386
|
export async function pancakeProxyBatchSellMerkle(params) {
|
|
384
387
|
const { chain, privateKeys, sellAmounts, tokenAddress, routeType, config } = params;
|
|
385
388
|
if (privateKeys.length === 0 || sellAmounts.length !== privateKeys.length) {
|
|
@@ -387,13 +390,11 @@ export async function pancakeProxyBatchSellMerkle(params) {
|
|
|
387
390
|
}
|
|
388
391
|
const pancakeProxyAddress = ADDRESSES.BSC.PancakeProxy;
|
|
389
392
|
const chainId = CHAIN_ID_MAP[chain];
|
|
390
|
-
|
|
391
|
-
|
|
393
|
+
// ✅ 直接使用传入的 RPC URL 创建 provider(不依赖 Merkle)
|
|
394
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
392
395
|
chainId: chainId,
|
|
393
|
-
|
|
396
|
+
name: chain
|
|
394
397
|
});
|
|
395
|
-
const provider = merkle.getProvider();
|
|
396
|
-
const blockOffset = config.bundleBlockOffset ?? 2;
|
|
397
398
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
398
399
|
const sellers = privateKeys.map(k => new Wallet(k, provider));
|
|
399
400
|
// 查询 tokenIn decimals
|
|
@@ -61,6 +61,7 @@ export type MerkleSignedResult = {
|
|
|
61
61
|
[key: string]: any;
|
|
62
62
|
};
|
|
63
63
|
};
|
|
64
|
+
/** ✅ Flap 创建代币 + 购买参数(Merkle 版本 - 完整) */
|
|
64
65
|
export type FlapCreateWithBundleBuyMerkleParams = {
|
|
65
66
|
chain: FlapChainForMerkleBundle;
|
|
66
67
|
privateKeys: string[];
|
|
@@ -81,11 +82,33 @@ export type FlapCreateWithBundleBuyMerkleParams = {
|
|
|
81
82
|
extensionID?: string;
|
|
82
83
|
extensionData?: string;
|
|
83
84
|
};
|
|
85
|
+
/** ✅ Flap 创建代币 + 购买参数(仅签名版本 - 精简) */
|
|
86
|
+
export type FlapCreateWithBundleBuySignParams = {
|
|
87
|
+
chain: FlapChainForMerkleBundle;
|
|
88
|
+
privateKeys: string[];
|
|
89
|
+
buyAmounts: string[];
|
|
90
|
+
tokenInfo: {
|
|
91
|
+
name: string;
|
|
92
|
+
symbol: string;
|
|
93
|
+
meta: string;
|
|
94
|
+
};
|
|
95
|
+
quoteToken?: string;
|
|
96
|
+
tokenAddress: string;
|
|
97
|
+
minOutputAmounts?: (string | bigint)[];
|
|
98
|
+
config: FlapSignConfig;
|
|
99
|
+
dexThresh?: number;
|
|
100
|
+
migratorType?: number;
|
|
101
|
+
taxRate?: number;
|
|
102
|
+
salt?: string;
|
|
103
|
+
extensionID?: string;
|
|
104
|
+
extensionData?: string;
|
|
105
|
+
};
|
|
84
106
|
/**
|
|
85
107
|
* ✅ Flap 创建代币 + 购买结果(简化版)
|
|
86
108
|
* 包含 tokenAddress 用于返回创建的代币地址
|
|
87
109
|
*/
|
|
88
110
|
export type FlapCreateWithBundleBuyMerkleResult = MerkleSignedResult;
|
|
111
|
+
/** ✅ Flap 批量购买参数(Merkle 版本 - 完整) */
|
|
89
112
|
export type FlapBatchBuyMerkleParams = {
|
|
90
113
|
chain: FlapChainForMerkleBundle;
|
|
91
114
|
privateKeys: string[];
|
|
@@ -94,6 +117,15 @@ export type FlapBatchBuyMerkleParams = {
|
|
|
94
117
|
minOutputAmounts?: (string | bigint)[];
|
|
95
118
|
config: FlapBundleMerkleConfig;
|
|
96
119
|
};
|
|
120
|
+
/** ✅ Flap 批量购买参数(仅签名版本 - 精简) */
|
|
121
|
+
export type FlapBatchBuySignParams = {
|
|
122
|
+
chain: FlapChainForMerkleBundle;
|
|
123
|
+
privateKeys: string[];
|
|
124
|
+
buyAmounts: string[];
|
|
125
|
+
tokenAddress: string;
|
|
126
|
+
minOutputAmounts?: (string | bigint)[];
|
|
127
|
+
config: FlapSignConfig;
|
|
128
|
+
};
|
|
97
129
|
/** ✅ Flap 批量购买结果(简化版) */
|
|
98
130
|
export type FlapBatchBuyMerkleResult = MerkleSignedResult;
|
|
99
131
|
/** ✅ Flap 批量卖出参数(Merkle 版本 - 完整) */
|
|
@@ -152,6 +184,7 @@ export type FlapBatchPrivateMerkleResult = MerkleSignedResult;
|
|
|
152
184
|
/**
|
|
153
185
|
* 使用 PancakeSwapProxy 批量购买参数
|
|
154
186
|
*/
|
|
187
|
+
/** ✅ PancakeProxy 批量购买参数(Merkle 版本 - 完整) */
|
|
155
188
|
export type PancakeProxyBatchBuyParams = {
|
|
156
189
|
chain: FlapChainForMerkleBundle;
|
|
157
190
|
privateKeys: string[];
|
|
@@ -166,11 +199,27 @@ export type PancakeProxyBatchBuyParams = {
|
|
|
166
199
|
minOutputAmounts?: (string | bigint)[];
|
|
167
200
|
config: FlapBundleMerkleConfig;
|
|
168
201
|
};
|
|
202
|
+
/** ✅ PancakeProxy 批量购买参数(仅签名版本 - 精简) */
|
|
203
|
+
export type PancakeProxyBatchBuySignParams = {
|
|
204
|
+
chain: FlapChainForMerkleBundle;
|
|
205
|
+
privateKeys: string[];
|
|
206
|
+
buyAmounts: string[];
|
|
207
|
+
tokenAddress: string;
|
|
208
|
+
routeType: 'v2' | 'v3-single' | 'v3-multi';
|
|
209
|
+
v2Path?: string[];
|
|
210
|
+
v3TokenIn?: string;
|
|
211
|
+
v3Fee?: number;
|
|
212
|
+
v3LpAddresses?: string[];
|
|
213
|
+
v3ExactTokenIn?: string;
|
|
214
|
+
minOutputAmounts?: (string | bigint)[];
|
|
215
|
+
config: FlapSignConfig;
|
|
216
|
+
};
|
|
169
217
|
/** ✅ PancakeProxy 批量购买结果(简化版) */
|
|
170
218
|
export type PancakeProxyBatchBuyResult = MerkleSignedResult;
|
|
171
219
|
/**
|
|
172
220
|
* 使用 PancakeSwapProxy 批量卖出参数
|
|
173
221
|
*/
|
|
222
|
+
/** ✅ PancakeProxy 批量卖出参数(Merkle 版本 - 完整) */
|
|
174
223
|
export type PancakeProxyBatchSellParams = {
|
|
175
224
|
chain: FlapChainForMerkleBundle;
|
|
176
225
|
privateKeys: string[];
|
|
@@ -185,6 +234,21 @@ export type PancakeProxyBatchSellParams = {
|
|
|
185
234
|
minOutputAmounts?: (string | bigint)[];
|
|
186
235
|
config: FlapBundleMerkleConfig;
|
|
187
236
|
};
|
|
237
|
+
/** ✅ PancakeProxy 批量卖出参数(仅签名版本 - 精简) */
|
|
238
|
+
export type PancakeProxyBatchSellSignParams = {
|
|
239
|
+
chain: FlapChainForMerkleBundle;
|
|
240
|
+
privateKeys: string[];
|
|
241
|
+
sellAmounts: string[];
|
|
242
|
+
tokenAddress: string;
|
|
243
|
+
routeType: 'v2' | 'v3-single' | 'v3-multi';
|
|
244
|
+
v2Path?: string[];
|
|
245
|
+
v3TokenOut?: string;
|
|
246
|
+
v3Fee?: number;
|
|
247
|
+
v3LpAddresses?: string[];
|
|
248
|
+
v3ExactTokenIn?: string;
|
|
249
|
+
minOutputAmounts?: (string | bigint)[];
|
|
250
|
+
config: FlapSignConfig;
|
|
251
|
+
};
|
|
188
252
|
/** ✅ PancakeProxy 批量卖出结果(简化版) */
|
|
189
253
|
export type PancakeProxyBatchSellResult = MerkleSignedResult;
|
|
190
254
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -25,8 +25,8 @@ export { createTokenWithBundleBuy as fourCreateTokenWithBundleBuy, batchBuyWithB
|
|
|
25
25
|
export { createTokenWithBundleBuy as flapCreateTokenWithBundleBuy, batchBuyWithBundle as flapBatchBuyWithBundle, batchSellWithBundle as flapBatchSellWithBundle, type FlapBundleConfig, type FlapChainForBundle, type FlapCreateWithBundleBuyParams, type FlapCreateWithBundleBuyResult, type FlapBatchBuyParams, type FlapBatchBuyResult, type FlapBatchSellParams, type FlapBatchSellResult } from './flap/portal-bundle.js';
|
|
26
26
|
export { fourPrivateBuy, fourPrivateSell, fourBatchPrivateBuy, fourBatchPrivateSell, type FourPrivateBuyParams, type FourPrivateSellParams, type FourBatchPrivateBuyParams, type FourBatchPrivateSellParams } from './contracts/tm-bundle.js';
|
|
27
27
|
export { flapPrivateBuy, flapPrivateSell, flapBatchPrivateBuy, flapBatchPrivateSell, type FlapPrivateBuyParams, type FlapPrivateSellParams, type FlapBatchPrivateBuyParams, type FlapBatchPrivateSellParams, type FlapBatchPrivateSellResult } from './flap/portal-bundle.js';
|
|
28
|
-
export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle, flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle, pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch, type FlapBundleMerkleConfig, type FlapSignConfig, type FlapChainForMerkleBundle, type FlapCreateWithBundleBuyMerkleParams, type FlapCreateWithBundleBuyMerkleResult, type FlapBatchBuyMerkleParams, type FlapBatchBuyMerkleResult, type FlapBatchSellSignParams, type FlapBatchSellMerkleParams, type FlapBatchSellMerkleResult, type MerkleTransactionStatus, type MerkleBundleStatus, type FlapPrivateBuyMerkleParams, type FlapPrivateSellMerkleParams, type FlapBatchPrivateBuyMerkleParams, type FlapBatchPrivateSellMerkleParams, type FlapBatchPrivateMerkleResult, type FlapPrivateTransactionResult, type PancakeProxyBatchBuyParams, type PancakeProxyBatchBuyResult, type PancakeProxyBatchSellParams, type PancakeProxyBatchSellResult, type PancakeProxyApprovalParams, type PancakeProxyApprovalBatchParams, type PancakeProxyApprovalBatchResult } from './flap/portal-bundle-merkle/index.js';
|
|
29
|
-
export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, type MerkleSubmitConfig, type SubmitBundleResult, type FourBundleMerkleConfig, type FourCreateWithBundleBuyMerkleParams, type FourCreateWithBundleBuyMerkleResult, type FourBatchBuyMerkleParams, type FourBatchBuyMerkleResult, type FourBatchSellMerkleParams, type FourBatchSellMerkleResult, type FourPrivateBuyMerkleParams, type FourPrivateSellMerkleParams, type FourBatchPrivateBuyMerkleParams, type FourBatchPrivateSellMerkleParams, type FourBatchPrivateMerkleResult, type FourPrivateTransactionResult, type DisperseMerkleParams, type DisperseMerkleResult, type SweepMerkleParams, type SweepMerkleResult, type FourPancakeProxyBatchBuyParams, type FourPancakeProxyBatchBuyResult, type FourPancakeProxyBatchSellParams, type FourPancakeProxyBatchSellResult, type FourPancakeProxyApprovalParams, type FourPancakeProxyApprovalBatchParams, type FourPancakeProxyApprovalBatchResult, type ApproveFourTokenManagerBatchParams, type ApproveFourTokenManagerBatchResult } from './contracts/tm-bundle-merkle/index.js';
|
|
28
|
+
export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle, flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle, pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch, type FlapBundleMerkleConfig, type FlapSignConfig, type FlapChainForMerkleBundle, type FlapCreateWithBundleBuySignParams, type FlapCreateWithBundleBuyMerkleParams, type FlapCreateWithBundleBuyMerkleResult, type FlapBatchBuySignParams, type FlapBatchBuyMerkleParams, type FlapBatchBuyMerkleResult, type FlapBatchSellSignParams, type FlapBatchSellMerkleParams, type FlapBatchSellMerkleResult, type MerkleTransactionStatus, type MerkleBundleStatus, type FlapPrivateBuyMerkleParams, type FlapPrivateSellMerkleParams, type FlapBatchPrivateBuyMerkleParams, type FlapBatchPrivateSellMerkleParams, type FlapBatchPrivateMerkleResult, type FlapPrivateTransactionResult, type PancakeProxyBatchBuyParams, type PancakeProxyBatchBuyResult, type PancakeProxyBatchSellParams, type PancakeProxyBatchSellResult, type PancakeProxyApprovalParams, type PancakeProxyApprovalBatchParams, type PancakeProxyApprovalBatchResult } from './flap/portal-bundle-merkle/index.js';
|
|
29
|
+
export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, type MerkleSubmitConfig, type SubmitBundleResult, type FourBundleMerkleConfig, type FourSignConfig, type FourCreateWithBundleBuySignParams, type FourBatchBuySignParams, type FourBatchSellSignParams, type DisperseSignParams as FourDisperseSignParams, type SweepSignParams as FourSweepSignParams, type FourCreateWithBundleBuyMerkleParams, type FourCreateWithBundleBuyMerkleResult, type FourBatchBuyMerkleParams, type FourBatchBuyMerkleResult, type FourBatchSellMerkleParams, type FourBatchSellMerkleResult, type FourPrivateBuyMerkleParams, type FourPrivateSellMerkleParams, type FourBatchPrivateBuyMerkleParams, type FourBatchPrivateSellMerkleParams, type FourBatchPrivateMerkleResult, type FourPrivateTransactionResult, type DisperseMerkleParams, type DisperseMerkleResult, type SweepMerkleParams, type SweepMerkleResult, type FourPancakeProxyBatchBuyParams, type FourPancakeProxyBatchBuyResult, type FourPancakeProxyBatchSellParams, type FourPancakeProxyBatchSellResult, type FourPancakeProxyApprovalParams, type FourPancakeProxyApprovalBatchParams, type FourPancakeProxyApprovalBatchResult, type ApproveFourTokenManagerBatchParams, type ApproveFourTokenManagerBatchResult } from './contracts/tm-bundle-merkle/index.js';
|
|
30
30
|
export { PinataClient, type PinataConfig } from './flap/pinata.js';
|
|
31
31
|
export { pinFileToIPFSWithJWT, pinImageByPath, pinFileToIPFSWithJWTWeb, pinDataURLWithJWTWeb, dataURLToBlob, type PinataPinResp } from './flap/pinata.js';
|
|
32
32
|
export { generateWallets, type GeneratedWallet } from './utils/wallet.js';
|
|
@@ -34,7 +34,7 @@ export { getTokenBalancesWithMulticall, type MulticallResult, type MultiTokenBal
|
|
|
34
34
|
export { validatePrivateKeys, type PrivateKeyValidation } from './utils/wallet.js';
|
|
35
35
|
export { stealthTransfer, type StealthTransferResult, type StealthTransferSimpleParams } from './utils/stealth-transfer.js';
|
|
36
36
|
export { inspectTokenLP, type LPInfo, type LPPlatform, type InspectOptions } from './utils/lp-inspect.js';
|
|
37
|
-
export { disperseWithBundle, sweepWithBundle, type DisperseParams, type SweepParams, type BundleSubmitResult } from './utils/airdrop-sweep.js';
|
|
37
|
+
export { disperseWithBundle, sweepWithBundle, type DisperseSignParams, type SweepSignParams, type SignedTransactionsResult, type DisperseParams, type SweepParams, type BundleSubmitResult } from './utils/airdrop-sweep.js';
|
|
38
38
|
export { fourBundleSwapMerkle, type FourSwapConfig, type FourBundleSwapParams, type FourSwapResult } from './contracts/tm-bundle-merkle/swap.js';
|
|
39
39
|
export { flapBundleSwapMerkle, type FlapSwapConfig, type FlapBundleSwapParams, type FlapSwapResult } from './flap/portal-bundle-merkle/swap.js';
|
|
40
40
|
export { pancakeBundleSwapMerkle, type PancakeSwapConfig, type PancakeBundleSwapParams, type PancakeSwapResult, type SwapRouteType, type V2RouteParams, type V3SingleRouteParams, type V3MultiRouteParams, type RouteParams } from './pancake/bundle-swap.js';
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import type { SoulPointSignatureMode, VNormalizationMode } from '../clients/club48.js';
|
|
2
|
+
/** ✅ Bundle 提交结果(完整版 - 包含 bundleUuid) */
|
|
2
3
|
export type BundleSubmitResult = {
|
|
3
4
|
bundleUuid: string;
|
|
4
5
|
signedTxs: string[];
|
|
5
6
|
};
|
|
7
|
+
/** ✅ 签名结果(精简版 - 仅返回签名交易) */
|
|
8
|
+
export type SignedTransactionsResult = {
|
|
9
|
+
signedTransactions: string[];
|
|
10
|
+
};
|
|
11
|
+
/** ✅ 分散参数(完整版 - 包含 Bundle 提交) */
|
|
6
12
|
export type DisperseParams = {
|
|
7
13
|
rpcUrl: string;
|
|
8
14
|
chainId: number;
|
|
@@ -20,7 +26,25 @@ export type DisperseParams = {
|
|
|
20
26
|
spPrivateKey?: string;
|
|
21
27
|
spVMode?: VNormalizationMode;
|
|
22
28
|
};
|
|
23
|
-
|
|
29
|
+
/** ✅ 分散参数(精简版 - 仅签名) */
|
|
30
|
+
export type DisperseSignParams = {
|
|
31
|
+
rpcUrl: string;
|
|
32
|
+
chainId: number;
|
|
33
|
+
fromPrivateKey: string;
|
|
34
|
+
recipients: string[];
|
|
35
|
+
amount?: string;
|
|
36
|
+
amounts?: string[];
|
|
37
|
+
tokenAddress?: string;
|
|
38
|
+
gasPriceGwei?: string;
|
|
39
|
+
transferGasLimit?: bigint;
|
|
40
|
+
nativeGasLimit?: bigint;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* 分散(仅签名版本 - 不提交 Bundle)
|
|
44
|
+
* ✅ 精简版:只负责签名交易,不提交
|
|
45
|
+
*/
|
|
46
|
+
export declare function disperseWithBundle(params: DisperseSignParams): Promise<SignedTransactionsResult>;
|
|
47
|
+
/** ✅ 归集参数(完整版 - 包含 Bundle 提交) */
|
|
24
48
|
export type SweepParams = {
|
|
25
49
|
rpcUrl: string;
|
|
26
50
|
chainId: number;
|
|
@@ -39,4 +63,22 @@ export type SweepParams = {
|
|
|
39
63
|
spPrivateKey?: string;
|
|
40
64
|
spVMode?: VNormalizationMode;
|
|
41
65
|
};
|
|
42
|
-
|
|
66
|
+
/** ✅ 归集参数(精简版 - 仅签名) */
|
|
67
|
+
export type SweepSignParams = {
|
|
68
|
+
rpcUrl: string;
|
|
69
|
+
chainId: number;
|
|
70
|
+
sourcePrivateKeys: string[];
|
|
71
|
+
target: string;
|
|
72
|
+
ratioPct?: number;
|
|
73
|
+
amount?: string;
|
|
74
|
+
tokenAddress?: string;
|
|
75
|
+
gasPriceGwei?: string;
|
|
76
|
+
transferGasLimit?: bigint;
|
|
77
|
+
nativeGasLimit?: bigint;
|
|
78
|
+
skipIfInsufficient?: boolean;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* 归集(仅签名版本 - 不提交 Bundle)
|
|
82
|
+
* ✅ 精简版:只负责签名交易,不提交
|
|
83
|
+
*/
|
|
84
|
+
export declare function sweepWithBundle(params: SweepSignParams): Promise<SignedTransactionsResult>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ethers, JsonRpcProvider } from 'ethers';
|
|
2
|
-
import { Club48Client } from '../clients/club48.js';
|
|
3
2
|
async function getErc20Decimals(provider, token) {
|
|
4
3
|
try {
|
|
5
4
|
const erc20 = new ethers.Contract(token, ['function decimals() view returns (uint8)'], provider);
|
|
@@ -12,10 +11,15 @@ async function getErc20Decimals(provider, token) {
|
|
|
12
11
|
return 18;
|
|
13
12
|
}
|
|
14
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 分散(仅签名版本 - 不提交 Bundle)
|
|
16
|
+
* ✅ 精简版:只负责签名交易,不提交
|
|
17
|
+
*/
|
|
15
18
|
export async function disperseWithBundle(params) {
|
|
16
|
-
const { rpcUrl, chainId, fromPrivateKey, recipients, amount, amounts, tokenAddress,
|
|
17
|
-
if (!recipients || recipients.length === 0)
|
|
18
|
-
return {
|
|
19
|
+
const { rpcUrl, chainId, fromPrivateKey, recipients, amount, amounts, tokenAddress, gasPriceGwei, transferGasLimit = 65000n, nativeGasLimit = 21000n } = params;
|
|
20
|
+
if (!recipients || recipients.length === 0) {
|
|
21
|
+
return { signedTransactions: [] };
|
|
22
|
+
}
|
|
19
23
|
const provider = new JsonRpcProvider(rpcUrl, chainId);
|
|
20
24
|
const wallet = new ethers.Wallet(fromPrivateKey, provider);
|
|
21
25
|
const gasPrice = gasPriceGwei && gasPriceGwei.trim().length > 0
|
|
@@ -71,14 +75,18 @@ export async function disperseWithBundle(params) {
|
|
|
71
75
|
signedTxs.push(tx);
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return { bundleUuid, signedTxs };
|
|
78
|
+
// ✅ 只返回签名交易,不提交到 Bundle
|
|
79
|
+
return { signedTransactions: signedTxs };
|
|
77
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* 归集(仅签名版本 - 不提交 Bundle)
|
|
83
|
+
* ✅ 精简版:只负责签名交易,不提交
|
|
84
|
+
*/
|
|
78
85
|
export async function sweepWithBundle(params) {
|
|
79
|
-
const { rpcUrl, chainId, sourcePrivateKeys, target, ratioPct, amount, tokenAddress,
|
|
80
|
-
if (!sourcePrivateKeys || sourcePrivateKeys.length === 0)
|
|
81
|
-
return {
|
|
86
|
+
const { rpcUrl, chainId, sourcePrivateKeys, target, ratioPct, amount, tokenAddress, gasPriceGwei, transferGasLimit = 65000n, nativeGasLimit = 21000n, skipIfInsufficient = true } = params;
|
|
87
|
+
if (!sourcePrivateKeys || sourcePrivateKeys.length === 0) {
|
|
88
|
+
return { signedTransactions: [] };
|
|
89
|
+
}
|
|
82
90
|
const provider = new JsonRpcProvider(rpcUrl, chainId);
|
|
83
91
|
const gasPrice = gasPriceGwei && gasPriceGwei.trim().length > 0
|
|
84
92
|
? ethers.parseUnits(gasPriceGwei, 'gwei')
|
|
@@ -180,7 +188,6 @@ export async function sweepWithBundle(params) {
|
|
|
180
188
|
signedTxs.push(tx);
|
|
181
189
|
}
|
|
182
190
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
return { bundleUuid, signedTxs };
|
|
191
|
+
// ✅ 只返回签名交易,不提交到 Bundle
|
|
192
|
+
return { signedTransactions: signedTxs };
|
|
186
193
|
}
|