four-flap-meme-sdk 1.3.94 → 1.3.95
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/clients/blockrazor.js +0 -1
- package/dist/contracts/tm-bundle-merkle/config.d.ts +5 -0
- package/dist/contracts/tm-bundle-merkle/config.js +10 -0
- package/dist/contracts/tm-bundle-merkle/core.js +92 -24
- package/dist/contracts/tm-bundle-merkle/internal.d.ts +1 -1
- package/dist/contracts/tm-bundle-merkle/internal.js +4 -3
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.js +103 -54
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.d.ts +0 -1
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.js +36 -6
- package/dist/contracts/tm-bundle-merkle/swap.d.ts +0 -3
- package/dist/contracts/tm-bundle-merkle/swap.js +59 -6
- package/dist/contracts/tm-bundle-merkle/utils.js +7 -7
- package/dist/flap/portal-bundle-merkle/config.d.ts +8 -0
- package/dist/flap/portal-bundle-merkle/config.js +17 -0
- package/dist/flap/portal-bundle-merkle/core.js +120 -68
- package/dist/flap/portal-bundle-merkle/encryption.d.ts +16 -0
- package/dist/flap/portal-bundle-merkle/encryption.js +146 -0
- package/dist/flap/portal-bundle-merkle/pancake-proxy.js +136 -78
- package/dist/flap/portal-bundle-merkle/swap-buy-first.d.ts +0 -2
- package/dist/flap/portal-bundle-merkle/swap-buy-first.js +49 -30
- package/dist/flap/portal-bundle-merkle/swap.d.ts +0 -2
- package/dist/flap/portal-bundle-merkle/swap.js +75 -47
- package/dist/flap/portal-bundle-merkle/types.d.ts +1 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/pancake/bundle-buy-first.d.ts +1 -1
- package/dist/pancake/bundle-buy-first.js +49 -17
- package/dist/pancake/bundle-swap.d.ts +1 -4
- package/dist/pancake/bundle-swap.js +98 -33
- package/dist/utils/erc20.d.ts +108 -2
- package/dist/utils/erc20.js +65 -17
- package/package.json +4 -39
- package/dist/sol/constants.d.ts +0 -126
- package/dist/sol/constants.js +0 -145
- package/dist/sol/dex/index.d.ts +0 -8
- package/dist/sol/dex/index.js +0 -12
- package/dist/sol/dex/meteora/client.d.ts +0 -76
- package/dist/sol/dex/meteora/client.js +0 -219
- package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +0 -61
- package/dist/sol/dex/meteora/damm-v1-bundle.js +0 -112
- package/dist/sol/dex/meteora/damm-v1.d.ts +0 -118
- package/dist/sol/dex/meteora/damm-v1.js +0 -315
- package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +0 -82
- package/dist/sol/dex/meteora/damm-v2-bundle.js +0 -242
- package/dist/sol/dex/meteora/damm-v2.d.ts +0 -172
- package/dist/sol/dex/meteora/damm-v2.js +0 -632
- package/dist/sol/dex/meteora/dbc-bundle.d.ts +0 -123
- package/dist/sol/dex/meteora/dbc-bundle.js +0 -304
- package/dist/sol/dex/meteora/dbc.d.ts +0 -192
- package/dist/sol/dex/meteora/dbc.js +0 -619
- package/dist/sol/dex/meteora/dlmm-bundle.d.ts +0 -39
- package/dist/sol/dex/meteora/dlmm-bundle.js +0 -189
- package/dist/sol/dex/meteora/dlmm.d.ts +0 -157
- package/dist/sol/dex/meteora/dlmm.js +0 -671
- package/dist/sol/dex/meteora/index.d.ts +0 -25
- package/dist/sol/dex/meteora/index.js +0 -65
- package/dist/sol/dex/meteora/types.d.ts +0 -787
- package/dist/sol/dex/meteora/types.js +0 -110
- package/dist/sol/dex/orca/index.d.ts +0 -10
- package/dist/sol/dex/orca/index.js +0 -16
- package/dist/sol/dex/orca/orca-bundle.d.ts +0 -41
- package/dist/sol/dex/orca/orca-bundle.js +0 -173
- package/dist/sol/dex/orca/orca.d.ts +0 -65
- package/dist/sol/dex/orca/orca.js +0 -474
- package/dist/sol/dex/orca/types.d.ts +0 -263
- package/dist/sol/dex/orca/types.js +0 -38
- package/dist/sol/dex/orca/wavebreak-bundle.d.ts +0 -34
- package/dist/sol/dex/orca/wavebreak-bundle.js +0 -198
- package/dist/sol/dex/orca/wavebreak-types.d.ts +0 -227
- package/dist/sol/dex/orca/wavebreak-types.js +0 -23
- package/dist/sol/dex/orca/wavebreak.d.ts +0 -78
- package/dist/sol/dex/orca/wavebreak.js +0 -497
- package/dist/sol/dex/pump/index.d.ts +0 -9
- package/dist/sol/dex/pump/index.js +0 -14
- package/dist/sol/dex/pump/pump-bundle.d.ts +0 -92
- package/dist/sol/dex/pump/pump-bundle.js +0 -383
- package/dist/sol/dex/pump/pump-swap-bundle.d.ts +0 -103
- package/dist/sol/dex/pump/pump-swap-bundle.js +0 -380
- package/dist/sol/dex/pump/pump-swap.d.ts +0 -46
- package/dist/sol/dex/pump/pump-swap.js +0 -199
- package/dist/sol/dex/pump/pump.d.ts +0 -35
- package/dist/sol/dex/pump/pump.js +0 -352
- package/dist/sol/dex/pump/types.d.ts +0 -215
- package/dist/sol/dex/pump/types.js +0 -5
- package/dist/sol/dex/raydium/index.d.ts +0 -8
- package/dist/sol/dex/raydium/index.js +0 -12
- package/dist/sol/dex/raydium/launchlab.d.ts +0 -68
- package/dist/sol/dex/raydium/launchlab.js +0 -210
- package/dist/sol/dex/raydium/raydium-bundle.d.ts +0 -64
- package/dist/sol/dex/raydium/raydium-bundle.js +0 -324
- package/dist/sol/dex/raydium/raydium.d.ts +0 -40
- package/dist/sol/dex/raydium/raydium.js +0 -366
- package/dist/sol/dex/raydium/types.d.ts +0 -240
- package/dist/sol/dex/raydium/types.js +0 -5
- package/dist/sol/index.d.ts +0 -10
- package/dist/sol/index.js +0 -16
- package/dist/sol/jito/bundle.d.ts +0 -90
- package/dist/sol/jito/bundle.js +0 -263
- package/dist/sol/jito/index.d.ts +0 -7
- package/dist/sol/jito/index.js +0 -7
- package/dist/sol/jito/tip.d.ts +0 -51
- package/dist/sol/jito/tip.js +0 -83
- package/dist/sol/jito/types.d.ts +0 -100
- package/dist/sol/jito/types.js +0 -5
- package/dist/sol/token/create-complete.d.ts +0 -115
- package/dist/sol/token/create-complete.js +0 -235
- package/dist/sol/token/create-token.d.ts +0 -57
- package/dist/sol/token/create-token.js +0 -230
- package/dist/sol/token/index.d.ts +0 -9
- package/dist/sol/token/index.js +0 -14
- package/dist/sol/token/metadata-upload.d.ts +0 -86
- package/dist/sol/token/metadata-upload.js +0 -173
- package/dist/sol/token/metadata.d.ts +0 -92
- package/dist/sol/token/metadata.js +0 -274
- package/dist/sol/token/types.d.ts +0 -153
- package/dist/sol/token/types.js +0 -5
- package/dist/sol/types.d.ts +0 -176
- package/dist/sol/types.js +0 -7
- package/dist/sol/utils/balance.d.ts +0 -160
- package/dist/sol/utils/balance.js +0 -638
- package/dist/sol/utils/connection.d.ts +0 -78
- package/dist/sol/utils/connection.js +0 -168
- package/dist/sol/utils/index.d.ts +0 -9
- package/dist/sol/utils/index.js +0 -9
- package/dist/sol/utils/lp-inspect.d.ts +0 -129
- package/dist/sol/utils/lp-inspect.js +0 -900
- package/dist/sol/utils/transfer.d.ts +0 -125
- package/dist/sol/utils/transfer.js +0 -220
- package/dist/sol/utils/wallet.d.ts +0 -107
- package/dist/sol/utils/wallet.js +0 -210
|
@@ -7,8 +7,10 @@ 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, getProfitRecipient, getProfitRateBps } from './config.js';
|
|
10
|
+
import { getTxType, getGasPriceConfig, getProfitRecipient, getProfitRateBps, getBribeAmount } from './config.js';
|
|
11
11
|
import { trySell } from '../tm.js';
|
|
12
|
+
// ✅ BlockRazor Builder EOA 地址(用于贿赂)
|
|
13
|
+
const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
|
|
12
14
|
/**
|
|
13
15
|
* 获取 Gas Limit(支持 FourAnyConfig)
|
|
14
16
|
*/
|
|
@@ -82,14 +84,19 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
82
84
|
// ✅ 优化:第三批并行 - trySell、构建交易、获取 nonces
|
|
83
85
|
const tmBuyer = new Contract(TM_ADDRESS, TM_ABI, buyer);
|
|
84
86
|
const tmSeller = new Contract(TM_ADDRESS, TM_ABI, seller);
|
|
85
|
-
|
|
86
|
-
const minBuyAmount =
|
|
87
|
+
// ✅ 已移除滑点保护:minBuyAmount 固定为 0
|
|
88
|
+
const minBuyAmount = 0n;
|
|
87
89
|
// 预先规划 nonces
|
|
88
90
|
const extractProfit = true;
|
|
89
91
|
const profitRateBps = getProfitRateBps();
|
|
92
|
+
// ✅ 获取贿赂金额
|
|
93
|
+
const bribeAmount = getBribeAmount(config);
|
|
94
|
+
const needBribeTx = bribeAmount > 0n;
|
|
90
95
|
// 计算需要的 nonce 数量
|
|
91
96
|
let buyerNonceCount = 1; // 买入交易
|
|
92
97
|
let sellerNonceCount = 1; // 卖出交易
|
|
98
|
+
if (needBribeTx)
|
|
99
|
+
sellerNonceCount++; // 贿赂交易(由卖方发送)
|
|
93
100
|
if (needApproval)
|
|
94
101
|
sellerNonceCount++; // 授权交易
|
|
95
102
|
if (extractProfit)
|
|
@@ -121,7 +128,8 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
121
128
|
]);
|
|
122
129
|
const { buyerNonces, sellerNonces } = noncesResult;
|
|
123
130
|
const estimatedSellFunds = sellResult.funds;
|
|
124
|
-
|
|
131
|
+
// ✅ 已移除滑点保护:minSellFunds 固定为 0
|
|
132
|
+
const minSellFunds = 0n;
|
|
125
133
|
const profitAmount = extractProfit ? (estimatedSellFunds * BigInt(profitRateBps)) / 10000n : 0n;
|
|
126
134
|
// 更新卖出交易的 minSellFunds
|
|
127
135
|
sellUnsigned.data = tmSeller.interface.encodeFunctionData('sellToken', [
|
|
@@ -130,10 +138,13 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
130
138
|
// 分配 nonces
|
|
131
139
|
let buyerNonce;
|
|
132
140
|
let sellerNonce;
|
|
141
|
+
let bribeNonce;
|
|
133
142
|
let approvalNonce;
|
|
134
143
|
let profitNonce;
|
|
135
144
|
if (sameAddress) {
|
|
136
145
|
let idx = 0;
|
|
146
|
+
if (needBribeTx)
|
|
147
|
+
bribeNonce = sellerNonces[idx++];
|
|
137
148
|
if (needApproval)
|
|
138
149
|
approvalNonce = sellerNonces[idx++];
|
|
139
150
|
buyerNonce = sellerNonces[idx++];
|
|
@@ -144,6 +155,8 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
144
155
|
else {
|
|
145
156
|
buyerNonce = buyerNonces[0];
|
|
146
157
|
let idx = 0;
|
|
158
|
+
if (needBribeTx)
|
|
159
|
+
bribeNonce = sellerNonces[idx++];
|
|
147
160
|
if (needApproval)
|
|
148
161
|
approvalNonce = sellerNonces[idx++];
|
|
149
162
|
sellerNonce = sellerNonces[idx++];
|
|
@@ -152,6 +165,19 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
152
165
|
}
|
|
153
166
|
// ✅ 并行签名所有交易
|
|
154
167
|
const signPromises = [];
|
|
168
|
+
// ✅ 贿赂交易放在首位
|
|
169
|
+
let bribeTx = null;
|
|
170
|
+
if (needBribeTx && bribeNonce !== undefined) {
|
|
171
|
+
signPromises.push(seller.signTransaction({
|
|
172
|
+
to: BLOCKRAZOR_BUILDER_EOA,
|
|
173
|
+
value: bribeAmount,
|
|
174
|
+
nonce: bribeNonce,
|
|
175
|
+
gasPrice,
|
|
176
|
+
gasLimit: 21000n,
|
|
177
|
+
chainId: chainIdNum,
|
|
178
|
+
type: txType
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
155
181
|
// 授权交易
|
|
156
182
|
let approvalTx = null;
|
|
157
183
|
if (needApproval && approvalNonce !== undefined) {
|
|
@@ -190,7 +216,7 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
190
216
|
type: txType,
|
|
191
217
|
value: 0n // ✅ 卖出交易不发送原生代币
|
|
192
218
|
}));
|
|
193
|
-
//
|
|
219
|
+
// ✅ 利润交易放在末尾
|
|
194
220
|
let profitTx = null;
|
|
195
221
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
196
222
|
signPromises.push(seller.signTransaction({
|
|
@@ -206,6 +232,8 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
206
232
|
const signedTxs = await Promise.all(signPromises);
|
|
207
233
|
// 解析签名结果
|
|
208
234
|
let idx = 0;
|
|
235
|
+
if (needBribeTx)
|
|
236
|
+
bribeTx = signedTxs[idx++];
|
|
209
237
|
if (needApproval)
|
|
210
238
|
approvalTx = signedTxs[idx++];
|
|
211
239
|
const signedBuy = signedTxs[idx++];
|
|
@@ -213,8 +241,10 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
213
241
|
if (extractProfit && profitAmount > 0n)
|
|
214
242
|
profitTx = signedTxs[idx];
|
|
215
243
|
nonceManager.clearTemp();
|
|
216
|
-
//
|
|
244
|
+
// ✅ 组装交易列表:贿赂 → 授权 → 买入 → 卖出 → 利润
|
|
217
245
|
const allTransactions = [];
|
|
246
|
+
if (bribeTx)
|
|
247
|
+
allTransactions.push(bribeTx);
|
|
218
248
|
if (approvalTx)
|
|
219
249
|
allTransactions.push(approvalTx);
|
|
220
250
|
allTransactions.push(signedBuy, signedSell);
|
|
@@ -29,7 +29,6 @@ export interface FourBundleSwapSignParams {
|
|
|
29
29
|
sellPercentage?: number;
|
|
30
30
|
buyerPrivateKey: string;
|
|
31
31
|
tokenAddress: string;
|
|
32
|
-
slippageTolerance?: number;
|
|
33
32
|
config: FourSwapSignConfig;
|
|
34
33
|
}
|
|
35
34
|
export interface FourBundleSwapParams {
|
|
@@ -38,7 +37,6 @@ export interface FourBundleSwapParams {
|
|
|
38
37
|
sellPercentage?: number;
|
|
39
38
|
buyerPrivateKey: string;
|
|
40
39
|
tokenAddress: string;
|
|
41
|
-
slippageTolerance?: number;
|
|
42
40
|
config: FourSwapConfig;
|
|
43
41
|
}
|
|
44
42
|
/**
|
|
@@ -69,7 +67,6 @@ export interface FourBatchSwapSignParams {
|
|
|
69
67
|
buyerPrivateKeys: string[];
|
|
70
68
|
buyerRatios?: number[];
|
|
71
69
|
tokenAddress: string;
|
|
72
|
-
slippageTolerance?: number;
|
|
73
70
|
config: FourSwapSignConfig;
|
|
74
71
|
}
|
|
75
72
|
/**
|
|
@@ -8,11 +8,14 @@ import { calculateSellAmount } from '../../utils/swap-helpers.js';
|
|
|
8
8
|
import { NonceManager, getOptimizedGasPrice, getGasLimit, getGasPriceConfig, getTxType } from '../../utils/bundle-helpers.js';
|
|
9
9
|
import { ADDRESSES, PROFIT_CONFIG } from '../../utils/constants.js';
|
|
10
10
|
import { TM_ABI, HELPER3_ABI, TM_ADDRESS } from './swap-internal.js';
|
|
11
|
+
import { getBribeAmount } from './config.js';
|
|
12
|
+
// ✅ BlockRazor Builder EOA 地址(用于贿赂)
|
|
13
|
+
const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
|
|
11
14
|
/**
|
|
12
15
|
* Four内盘捆绑换手
|
|
13
16
|
*/
|
|
14
17
|
export async function fourBundleSwapMerkle(params) {
|
|
15
|
-
const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKey, tokenAddress,
|
|
18
|
+
const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKey, tokenAddress, config } = params;
|
|
16
19
|
const chainIdNum = config.chainId ?? 56;
|
|
17
20
|
const provider = new ethers.JsonRpcProvider(config.rpcUrl, {
|
|
18
21
|
chainId: chainIdNum,
|
|
@@ -65,11 +68,16 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
65
68
|
const profitAmount = extractProfit && sellerWillGetBNB > 0n
|
|
66
69
|
? (sellerWillGetBNB * BigInt(profitRateBps)) / 10000n
|
|
67
70
|
: 0n;
|
|
71
|
+
// ✅ 获取贿赂金额
|
|
72
|
+
const bribeAmount = getBribeAmount(config);
|
|
73
|
+
const needBribeTx = bribeAmount > 0n;
|
|
68
74
|
// ✅ 优化:第三批并行 - 构建交易、获取 nonces
|
|
69
75
|
const tmSeller = new Contract(TM_ADDRESS, TM_ABI, seller);
|
|
70
76
|
const tmBuyer = new Contract(TM_ADDRESS, TM_ABI, buyer);
|
|
71
77
|
// 计算需要的 nonce 数量
|
|
72
78
|
let sellerNonceCount = 1; // 卖出交易
|
|
79
|
+
if (needBribeTx)
|
|
80
|
+
sellerNonceCount++; // 贿赂交易
|
|
73
81
|
if (needApproval)
|
|
74
82
|
sellerNonceCount++; // 授权交易
|
|
75
83
|
if (extractProfit)
|
|
@@ -96,13 +104,28 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
96
104
|
const { sellerNonces, buyerNonce } = noncesResult;
|
|
97
105
|
// 分配 nonces
|
|
98
106
|
let idx = 0;
|
|
107
|
+
let bribeNonce;
|
|
99
108
|
let approvalNonce;
|
|
109
|
+
if (needBribeTx)
|
|
110
|
+
bribeNonce = sellerNonces[idx++];
|
|
100
111
|
if (needApproval)
|
|
101
112
|
approvalNonce = sellerNonces[idx++];
|
|
102
113
|
const sellerNonce = sellerNonces[idx++];
|
|
103
114
|
const profitNonce = extractProfit ? sellerNonces[idx] : undefined;
|
|
104
115
|
// ✅ 并行签名所有交易
|
|
105
116
|
const signPromises = [];
|
|
117
|
+
// ✅ 贿赂交易放在首位
|
|
118
|
+
if (needBribeTx && bribeNonce !== undefined) {
|
|
119
|
+
signPromises.push(seller.signTransaction({
|
|
120
|
+
to: BLOCKRAZOR_BUILDER_EOA,
|
|
121
|
+
value: bribeAmount,
|
|
122
|
+
nonce: bribeNonce,
|
|
123
|
+
gasPrice,
|
|
124
|
+
gasLimit: 21000n,
|
|
125
|
+
chainId: chainIdNum,
|
|
126
|
+
type: txType
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
106
129
|
// 授权交易
|
|
107
130
|
if (needApproval && approvalNonce !== undefined) {
|
|
108
131
|
const approveInterface = new ethers.Interface(['function approve(address,uint256) returns (bool)']);
|
|
@@ -137,7 +160,7 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
137
160
|
type: txType,
|
|
138
161
|
value: buyerFunds
|
|
139
162
|
}));
|
|
140
|
-
//
|
|
163
|
+
// ✅ 利润交易放在末尾
|
|
141
164
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
142
165
|
signPromises.push(seller.signTransaction({
|
|
143
166
|
to: PROFIT_CONFIG.RECIPIENT,
|
|
@@ -152,15 +175,20 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
152
175
|
const signedTxs = await Promise.all(signPromises);
|
|
153
176
|
// 解析签名结果
|
|
154
177
|
let signIdx = 0;
|
|
178
|
+
let bribeTx = null;
|
|
155
179
|
let approvalTx = null;
|
|
180
|
+
if (needBribeTx)
|
|
181
|
+
bribeTx = signedTxs[signIdx++];
|
|
156
182
|
if (needApproval)
|
|
157
183
|
approvalTx = signedTxs[signIdx++];
|
|
158
184
|
const signedSell = signedTxs[signIdx++];
|
|
159
185
|
const signedBuy = signedTxs[signIdx++];
|
|
160
186
|
const profitTx = extractProfit && profitAmount > 0n ? signedTxs[signIdx] : null;
|
|
161
187
|
nonceManager.clearTemp();
|
|
162
|
-
//
|
|
188
|
+
// ✅ 组装交易列表:贿赂 → 授权 → 卖出 → 买入 → 利润
|
|
163
189
|
const allTransactions = [];
|
|
190
|
+
if (bribeTx)
|
|
191
|
+
allTransactions.push(bribeTx);
|
|
164
192
|
if (approvalTx)
|
|
165
193
|
allTransactions.push(approvalTx);
|
|
166
194
|
allTransactions.push(signedSell, signedBuy);
|
|
@@ -185,7 +213,7 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
185
213
|
* 限制:最多 24 个买方(服务器限制 25 笔交易,包含 1 笔利润交易)
|
|
186
214
|
*/
|
|
187
215
|
export async function fourBatchSwapMerkle(params) {
|
|
188
|
-
const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKeys, tokenAddress,
|
|
216
|
+
const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKeys, tokenAddress, config } = params;
|
|
189
217
|
// ✅ 校验买方数量(最多 24 个)
|
|
190
218
|
const MAX_BUYERS = 24;
|
|
191
219
|
if (buyerPrivateKeys.length === 0) {
|
|
@@ -258,6 +286,9 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
258
286
|
const profitAmount = totalBuyerFunds > 0n
|
|
259
287
|
? (totalBuyerFunds * BigInt(profitRateBps)) / 10000n
|
|
260
288
|
: 0n;
|
|
289
|
+
// ✅ 获取贿赂金额
|
|
290
|
+
const bribeAmount = getBribeAmount(config);
|
|
291
|
+
const needBribeTx = bribeAmount > 0n;
|
|
261
292
|
// ✅ 并行构建所有交易
|
|
262
293
|
const tmSeller = new Contract(TM_ADDRESS, TM_ABI, seller);
|
|
263
294
|
const [sellUnsigned, ...buyUnsignedList] = await Promise.all([
|
|
@@ -273,6 +304,8 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
273
304
|
// ✅ 计算 nonce
|
|
274
305
|
// seller 需要的 nonce 数量
|
|
275
306
|
let sellerNonceCount = 1; // 卖出交易
|
|
307
|
+
if (needBribeTx)
|
|
308
|
+
sellerNonceCount++; // 贿赂交易
|
|
276
309
|
if (needApproval)
|
|
277
310
|
sellerNonceCount++; // 授权交易
|
|
278
311
|
sellerNonceCount++; // 利润交易
|
|
@@ -282,7 +315,10 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
282
315
|
// 分配 seller nonces
|
|
283
316
|
const sellerNonces = Array.from({ length: sellerNonceCount }, (_, i) => initialNonces[0] + i);
|
|
284
317
|
let idx = 0;
|
|
318
|
+
let bribeNonce;
|
|
285
319
|
let approvalNonce;
|
|
320
|
+
if (needBribeTx)
|
|
321
|
+
bribeNonce = sellerNonces[idx++];
|
|
286
322
|
if (needApproval)
|
|
287
323
|
approvalNonce = sellerNonces[idx++];
|
|
288
324
|
const sellerNonce = sellerNonces[idx++];
|
|
@@ -291,6 +327,18 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
291
327
|
const buyerNonces = initialNonces.slice(1);
|
|
292
328
|
// ✅ 并行签名所有交易
|
|
293
329
|
const signPromises = [];
|
|
330
|
+
// ✅ 贿赂交易放在首位
|
|
331
|
+
if (needBribeTx && bribeNonce !== undefined) {
|
|
332
|
+
signPromises.push(seller.signTransaction({
|
|
333
|
+
to: BLOCKRAZOR_BUILDER_EOA,
|
|
334
|
+
value: bribeAmount,
|
|
335
|
+
nonce: bribeNonce,
|
|
336
|
+
gasPrice,
|
|
337
|
+
gasLimit: 21000n,
|
|
338
|
+
chainId: chainIdNum,
|
|
339
|
+
type: txType
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
294
342
|
// 授权交易
|
|
295
343
|
if (needApproval && approvalNonce !== undefined) {
|
|
296
344
|
const approveInterface = new ethers.Interface(['function approve(address,uint256) returns (bool)']);
|
|
@@ -329,7 +377,7 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
329
377
|
value: buyAmountsWei[i]
|
|
330
378
|
}));
|
|
331
379
|
});
|
|
332
|
-
//
|
|
380
|
+
// ✅ 利润交易放在末尾
|
|
333
381
|
if (profitAmount > 0n) {
|
|
334
382
|
signPromises.push(seller.signTransaction({
|
|
335
383
|
to: PROFIT_CONFIG.RECIPIENT,
|
|
@@ -344,7 +392,10 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
344
392
|
const signedTxs = await Promise.all(signPromises);
|
|
345
393
|
// 解析签名结果
|
|
346
394
|
let signIdx = 0;
|
|
395
|
+
let bribeTx = null;
|
|
347
396
|
let approvalTx = null;
|
|
397
|
+
if (needBribeTx)
|
|
398
|
+
bribeTx = signedTxs[signIdx++];
|
|
348
399
|
if (needApproval)
|
|
349
400
|
approvalTx = signedTxs[signIdx++];
|
|
350
401
|
const signedSell = signedTxs[signIdx++];
|
|
@@ -352,8 +403,10 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
352
403
|
signIdx += buyers.length;
|
|
353
404
|
const profitTx = profitAmount > 0n ? signedTxs[signIdx] : null;
|
|
354
405
|
nonceManager.clearTemp();
|
|
355
|
-
// ✅
|
|
406
|
+
// ✅ 按顺序组装交易数组:贿赂 → 授权 → 卖出 → 买入 → 利润
|
|
356
407
|
const signedTransactions = [];
|
|
408
|
+
if (bribeTx)
|
|
409
|
+
signedTransactions.push(bribeTx);
|
|
357
410
|
if (approvalTx)
|
|
358
411
|
signedTransactions.push(approvalTx);
|
|
359
412
|
signedTransactions.push(signedSell);
|
|
@@ -153,8 +153,8 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
153
153
|
signedTxs.push(...(await Promise.all(txPromises)));
|
|
154
154
|
}
|
|
155
155
|
else {
|
|
156
|
-
// ✅ ERC20:并行获取 decimals
|
|
157
|
-
const decimals = tokenDecimals ?? (await _getErc20DecimalsMerkle(provider, tokenAddress));
|
|
156
|
+
// ✅ ERC20:并行获取 decimals(传入 chainIdNum 避免 NETWORK_ERROR)
|
|
157
|
+
const decimals = tokenDecimals ?? (await _getErc20DecimalsMerkle(provider, tokenAddress, chainIdNum));
|
|
158
158
|
const iface = new ethers.Interface(['function transfer(address,uint256) returns (bool)']);
|
|
159
159
|
// 先计算所有金额和利润(同步)- ERC20 利润以代币计
|
|
160
160
|
let totalTokenProfit = 0n;
|
|
@@ -207,7 +207,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
207
207
|
// ✅ 优化:并行获取 gasPrice 和 decimals
|
|
208
208
|
const [gasPrice, decimals] = await Promise.all([
|
|
209
209
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
210
|
-
isNative ? Promise.resolve(18) : Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress))
|
|
210
|
+
isNative ? Promise.resolve(18) : Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress, chainIdNum))
|
|
211
211
|
]);
|
|
212
212
|
const iface = isNative ? null : new ethers.Interface(['function transfer(address,uint256) returns (bool)']);
|
|
213
213
|
const gasFeePerHop = finalGasLimit * gasPrice;
|
|
@@ -608,10 +608,10 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
608
608
|
}
|
|
609
609
|
}
|
|
610
610
|
else {
|
|
611
|
-
// ✅ ERC20:并行获取 gasPrice、decimals
|
|
611
|
+
// ✅ ERC20:并行获取 gasPrice、decimals、余额(传入 chainIdNum 避免 NETWORK_ERROR)
|
|
612
612
|
const [gasPrice, decimals, balances, bnbBalances] = await Promise.all([
|
|
613
613
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
614
|
-
Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress)),
|
|
614
|
+
Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress, chainIdNum)),
|
|
615
615
|
_batchGetBalances(provider, addresses, tokenAddress),
|
|
616
616
|
config.checkBnbForErc20NoHop ? _batchGetBalances(provider, addresses) : Promise.resolve([])
|
|
617
617
|
]);
|
|
@@ -760,10 +760,10 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
760
760
|
}
|
|
761
761
|
}
|
|
762
762
|
const sourceAddresses = sourceWallets.map(w => w.address);
|
|
763
|
-
// ✅ 优化:并行获取 gasPrice、decimals
|
|
763
|
+
// ✅ 优化:并行获取 gasPrice、decimals、余额(传入 chainIdNum 避免 NETWORK_ERROR)
|
|
764
764
|
const [gasPrice, decimals, balances, bnbBalances] = await Promise.all([
|
|
765
765
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
766
|
-
isNative ? Promise.resolve(18) : Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress)),
|
|
766
|
+
isNative ? Promise.resolve(18) : Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress, chainIdNum)),
|
|
767
767
|
_batchGetBalances(provider, sourceAddresses, tokenAddress),
|
|
768
768
|
isNative ? Promise.resolve([]) : _batchGetBalances(provider, sourceAddresses)
|
|
769
769
|
]);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FlapBundleMerkleConfig, FlapSignConfig, FlapChainForMerkleBundle } from './types.js';
|
|
2
2
|
export type { FlapBundleMerkleConfig, FlapSignConfig, FlapChainForMerkleBundle };
|
|
3
|
+
export declare const BLOCKRAZOR_BUILDER_EOA = "0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20";
|
|
3
4
|
export type FlapAnyConfig = FlapBundleMerkleConfig | FlapSignConfig;
|
|
4
5
|
export declare const CHAIN_ID_MAP: Record<FlapChainForMerkleBundle, number>;
|
|
5
6
|
export declare const MERKLE_SUPPORTED_CHAIN_IDS: readonly [56, 1];
|
|
@@ -70,3 +71,10 @@ export declare function calculateBatchProfit(amounts: bigint[], config?: FlapAny
|
|
|
70
71
|
totalProfit: bigint;
|
|
71
72
|
remainingAmounts: bigint[];
|
|
72
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* 获取 BlockRazor 贿赂金额(wei)
|
|
76
|
+
* ✅ 用于提高 bundle 打包优先级
|
|
77
|
+
* @param config 配置
|
|
78
|
+
* @returns 贿赂金额(wei),如果未配置则返回 0n
|
|
79
|
+
*/
|
|
80
|
+
export declare function getBribeAmount(config?: FlapAnyConfig): bigint;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { ethers } from 'ethers';
|
|
2
2
|
import { PROFIT_CONFIG } from '../../utils/constants.js';
|
|
3
|
+
// ✅ BlockRazor Builder EOA 地址(用于贿赂)
|
|
4
|
+
// 参考文档: https://blockrazor.gitbook.io/blockrazor/bsc/block-builder/send-bundle
|
|
5
|
+
export const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
|
|
3
6
|
// ✅ Chain ID 映射
|
|
4
7
|
// 注意:Merkle 捆绑服务目前只支持 BSC (56) 和 ETH (1)
|
|
5
8
|
// 其他链仅用于非捆绑的签名交易
|
|
@@ -120,3 +123,17 @@ export function calculateBatchProfit(amounts, config) {
|
|
|
120
123
|
}
|
|
121
124
|
return { totalProfit, remainingAmounts };
|
|
122
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* 获取 BlockRazor 贿赂金额(wei)
|
|
128
|
+
* ✅ 用于提高 bundle 打包优先级
|
|
129
|
+
* @param config 配置
|
|
130
|
+
* @returns 贿赂金额(wei),如果未配置则返回 0n
|
|
131
|
+
*/
|
|
132
|
+
export function getBribeAmount(config) {
|
|
133
|
+
if (!config)
|
|
134
|
+
return 0n;
|
|
135
|
+
const bribeAmount = config.bribeAmount;
|
|
136
|
+
if (!bribeAmount || bribeAmount <= 0)
|
|
137
|
+
return 0n;
|
|
138
|
+
return ethers.parseEther(String(bribeAmount));
|
|
139
|
+
}
|