four-flap-meme-sdk 1.3.93 → 1.3.94
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 +1 -0
- package/dist/contracts/tm-bundle-merkle/config.d.ts +0 -5
- package/dist/contracts/tm-bundle-merkle/config.js +0 -10
- package/dist/contracts/tm-bundle-merkle/core.js +24 -92
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.js +54 -103
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.d.ts +1 -0
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.js +6 -36
- package/dist/contracts/tm-bundle-merkle/swap.d.ts +3 -0
- package/dist/contracts/tm-bundle-merkle/swap.js +6 -59
- package/dist/flap/portal-bundle-merkle/config.d.ts +0 -8
- package/dist/flap/portal-bundle-merkle/config.js +0 -17
- package/dist/flap/portal-bundle-merkle/core.js +68 -120
- package/dist/flap/portal-bundle-merkle/pancake-proxy.js +78 -136
- package/dist/flap/portal-bundle-merkle/swap-buy-first.d.ts +2 -0
- package/dist/flap/portal-bundle-merkle/swap-buy-first.js +30 -49
- package/dist/flap/portal-bundle-merkle/swap.d.ts +2 -0
- package/dist/flap/portal-bundle-merkle/swap.js +47 -75
- package/dist/flap/portal-bundle-merkle/types.d.ts +0 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/pancake/bundle-buy-first.d.ts +1 -1
- package/dist/pancake/bundle-buy-first.js +17 -49
- package/dist/pancake/bundle-swap.d.ts +4 -1
- package/dist/pancake/bundle-swap.js +33 -98
- package/dist/sol/constants.d.ts +126 -0
- package/dist/sol/constants.js +145 -0
- package/dist/sol/dex/index.d.ts +8 -0
- package/dist/sol/dex/index.js +12 -0
- package/dist/sol/dex/meteora/client.d.ts +76 -0
- package/dist/sol/dex/meteora/client.js +219 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +61 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.js +112 -0
- package/dist/sol/dex/meteora/damm-v1.d.ts +118 -0
- package/dist/sol/dex/meteora/damm-v1.js +315 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +82 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.js +242 -0
- package/dist/sol/dex/meteora/damm-v2.d.ts +172 -0
- package/dist/sol/dex/meteora/damm-v2.js +632 -0
- package/dist/sol/dex/meteora/dbc-bundle.d.ts +123 -0
- package/dist/sol/dex/meteora/dbc-bundle.js +304 -0
- package/dist/sol/dex/meteora/dbc.d.ts +192 -0
- package/dist/sol/dex/meteora/dbc.js +619 -0
- package/dist/sol/dex/meteora/dlmm-bundle.d.ts +39 -0
- package/dist/sol/dex/meteora/dlmm-bundle.js +189 -0
- package/dist/sol/dex/meteora/dlmm.d.ts +157 -0
- package/dist/sol/dex/meteora/dlmm.js +671 -0
- package/dist/sol/dex/meteora/index.d.ts +25 -0
- package/dist/sol/dex/meteora/index.js +65 -0
- package/dist/sol/dex/meteora/types.d.ts +787 -0
- package/dist/sol/dex/meteora/types.js +110 -0
- package/dist/sol/dex/orca/index.d.ts +10 -0
- package/dist/sol/dex/orca/index.js +16 -0
- package/dist/sol/dex/orca/orca-bundle.d.ts +41 -0
- package/dist/sol/dex/orca/orca-bundle.js +173 -0
- package/dist/sol/dex/orca/orca.d.ts +65 -0
- package/dist/sol/dex/orca/orca.js +474 -0
- package/dist/sol/dex/orca/types.d.ts +263 -0
- package/dist/sol/dex/orca/types.js +38 -0
- package/dist/sol/dex/orca/wavebreak-bundle.d.ts +34 -0
- package/dist/sol/dex/orca/wavebreak-bundle.js +198 -0
- package/dist/sol/dex/orca/wavebreak-types.d.ts +227 -0
- package/dist/sol/dex/orca/wavebreak-types.js +23 -0
- package/dist/sol/dex/orca/wavebreak.d.ts +78 -0
- package/dist/sol/dex/orca/wavebreak.js +497 -0
- package/dist/sol/dex/pump/index.d.ts +9 -0
- package/dist/sol/dex/pump/index.js +14 -0
- package/dist/sol/dex/pump/pump-bundle.d.ts +92 -0
- package/dist/sol/dex/pump/pump-bundle.js +383 -0
- package/dist/sol/dex/pump/pump-swap-bundle.d.ts +103 -0
- package/dist/sol/dex/pump/pump-swap-bundle.js +380 -0
- package/dist/sol/dex/pump/pump-swap.d.ts +46 -0
- package/dist/sol/dex/pump/pump-swap.js +199 -0
- package/dist/sol/dex/pump/pump.d.ts +35 -0
- package/dist/sol/dex/pump/pump.js +352 -0
- package/dist/sol/dex/pump/types.d.ts +215 -0
- package/dist/sol/dex/pump/types.js +5 -0
- package/dist/sol/dex/raydium/index.d.ts +8 -0
- package/dist/sol/dex/raydium/index.js +12 -0
- package/dist/sol/dex/raydium/launchlab.d.ts +68 -0
- package/dist/sol/dex/raydium/launchlab.js +210 -0
- package/dist/sol/dex/raydium/raydium-bundle.d.ts +64 -0
- package/dist/sol/dex/raydium/raydium-bundle.js +324 -0
- package/dist/sol/dex/raydium/raydium.d.ts +40 -0
- package/dist/sol/dex/raydium/raydium.js +366 -0
- package/dist/sol/dex/raydium/types.d.ts +240 -0
- package/dist/sol/dex/raydium/types.js +5 -0
- package/dist/sol/index.d.ts +10 -0
- package/dist/sol/index.js +16 -0
- package/dist/sol/jito/bundle.d.ts +90 -0
- package/dist/sol/jito/bundle.js +263 -0
- package/dist/sol/jito/index.d.ts +7 -0
- package/dist/sol/jito/index.js +7 -0
- package/dist/sol/jito/tip.d.ts +51 -0
- package/dist/sol/jito/tip.js +83 -0
- package/dist/sol/jito/types.d.ts +100 -0
- package/dist/sol/jito/types.js +5 -0
- package/dist/sol/token/create-complete.d.ts +115 -0
- package/dist/sol/token/create-complete.js +235 -0
- package/dist/sol/token/create-token.d.ts +57 -0
- package/dist/sol/token/create-token.js +230 -0
- package/dist/sol/token/index.d.ts +9 -0
- package/dist/sol/token/index.js +14 -0
- package/dist/sol/token/metadata-upload.d.ts +86 -0
- package/dist/sol/token/metadata-upload.js +173 -0
- package/dist/sol/token/metadata.d.ts +92 -0
- package/dist/sol/token/metadata.js +274 -0
- package/dist/sol/token/types.d.ts +153 -0
- package/dist/sol/token/types.js +5 -0
- package/dist/sol/types.d.ts +176 -0
- package/dist/sol/types.js +7 -0
- package/dist/sol/utils/balance.d.ts +160 -0
- package/dist/sol/utils/balance.js +638 -0
- package/dist/sol/utils/connection.d.ts +78 -0
- package/dist/sol/utils/connection.js +168 -0
- package/dist/sol/utils/index.d.ts +9 -0
- package/dist/sol/utils/index.js +9 -0
- package/dist/sol/utils/lp-inspect.d.ts +129 -0
- package/dist/sol/utils/lp-inspect.js +900 -0
- package/dist/sol/utils/transfer.d.ts +125 -0
- package/dist/sol/utils/transfer.js +220 -0
- package/dist/sol/utils/wallet.d.ts +107 -0
- package/dist/sol/utils/wallet.js +210 -0
- package/dist/utils/erc20.d.ts +2 -108
- package/dist/utils/erc20.js +17 -65
- package/package.json +39 -4
- package/dist/flap/portal-bundle-merkle/encryption.d.ts +0 -16
- package/dist/flap/portal-bundle-merkle/encryption.js +0 -146
|
@@ -151,6 +151,7 @@ export class BlockRazorClient {
|
|
|
151
151
|
const gasPrice = tx.gasPrice || 0n;
|
|
152
152
|
const minGasPrice = ethers.parseUnits(String(MIN_GAS_PRICE_GWEI), 'gwei');
|
|
153
153
|
if (gasPrice < minGasPrice) {
|
|
154
|
+
console.warn(`⚠️ 交易 Gas Price (${ethers.formatUnits(gasPrice, 'gwei')} Gwei) 低于最低要求 (${MIN_GAS_PRICE_GWEI} Gwei)`);
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
catch {
|
|
@@ -64,8 +64,3 @@ export declare function calculateBatchProfit(amounts: bigint[], config?: FourAny
|
|
|
64
64
|
totalProfit: bigint;
|
|
65
65
|
remainingAmounts: bigint[];
|
|
66
66
|
};
|
|
67
|
-
/**
|
|
68
|
-
* 获取贿赂金额(Wei)
|
|
69
|
-
* ✅ 从配置中读取贿赂金额,转换为 Wei
|
|
70
|
-
*/
|
|
71
|
-
export declare function getBribeAmount(config?: FourAnyConfig): bigint;
|
|
@@ -103,13 +103,3 @@ export function calculateBatchProfit(amounts, config) {
|
|
|
103
103
|
}
|
|
104
104
|
return { totalProfit, remainingAmounts };
|
|
105
105
|
}
|
|
106
|
-
/**
|
|
107
|
-
* 获取贿赂金额(Wei)
|
|
108
|
-
* ✅ 从配置中读取贿赂金额,转换为 Wei
|
|
109
|
-
*/
|
|
110
|
-
export function getBribeAmount(config) {
|
|
111
|
-
if (!config || !config.bribeAmount || config.bribeAmount <= 0) {
|
|
112
|
-
return 0n;
|
|
113
|
-
}
|
|
114
|
-
return ethers.parseEther(String(config.bribeAmount));
|
|
115
|
-
}
|
|
@@ -2,9 +2,7 @@ import { ethers, Wallet, Contract, Interface } 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, getProfitRecipient
|
|
6
|
-
// ✅ BlockRazor Builder EOA 地址(用于贿赂)
|
|
7
|
-
const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
|
|
5
|
+
import { getErrorMessage, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, getProfitRecipient } from './config.js';
|
|
8
6
|
import { batchCheckAllowances } from '../../utils/erc20.js';
|
|
9
7
|
import { trySell } from '../tm.js';
|
|
10
8
|
import Helper3Abi from '../../abis/TokenManagerHelper3.json' with { type: 'json' };
|
|
@@ -89,6 +87,7 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
89
87
|
const txType = getTxType(config);
|
|
90
88
|
const signedTxs = [];
|
|
91
89
|
const tmCreateAddr = ADDRESSES.BSC.TokenManagerOriginal;
|
|
90
|
+
const tmBuyAddr = ADDRESSES.BSC.TokenManagerOriginal;
|
|
92
91
|
// ✅ 单笔交易: 和 Four.meme 官网一样
|
|
93
92
|
// 计算利润
|
|
94
93
|
const extractProfit = shouldExtractProfit(config);
|
|
@@ -104,9 +103,6 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
104
103
|
actualBuyFunds = originalBuyAmount;
|
|
105
104
|
profitAmount = 0n;
|
|
106
105
|
}
|
|
107
|
-
// ✅ 获取贿赂金额
|
|
108
|
-
const bribeAmount = getBribeAmount(config);
|
|
109
|
-
const needBribeTx = bribeAmount > 0n;
|
|
110
106
|
const b0AmountWei = ethers.parseEther(params.b0Amount ?? '0');
|
|
111
107
|
const preSaleWei = tokenInfo.preSale ? ethers.parseEther(tokenInfo.preSale) : 0n;
|
|
112
108
|
// ✅ 关键: value = 创建费用 + b0Amount + preSale + 买入金额
|
|
@@ -115,21 +111,6 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
115
111
|
const tmCreate = new ethers.Contract(tmCreateAddr, TM2_ABI, devWallet);
|
|
116
112
|
const createTxUnsigned = await tmCreate.createToken.populateTransaction(createResp.createArg, createResp.signature, { value: valueWei } // ✅ 包含买入金额
|
|
117
113
|
);
|
|
118
|
-
// ✅ 贿赂交易放在首位(由 devWallet 发送)
|
|
119
|
-
let bribeNonce;
|
|
120
|
-
if (needBribeTx) {
|
|
121
|
-
bribeNonce = await nonceManager.getNextNonce(devWallet);
|
|
122
|
-
const bribeTx = await devWallet.signTransaction({
|
|
123
|
-
to: BLOCKRAZOR_BUILDER_EOA,
|
|
124
|
-
value: bribeAmount,
|
|
125
|
-
nonce: bribeNonce,
|
|
126
|
-
gasPrice,
|
|
127
|
-
gasLimit: 21000n,
|
|
128
|
-
chainId,
|
|
129
|
-
type: txType
|
|
130
|
-
});
|
|
131
|
-
signedTxs.push(bribeTx);
|
|
132
|
-
}
|
|
133
114
|
const createTxRequest = {
|
|
134
115
|
...createTxUnsigned,
|
|
135
116
|
from: devWallet.address,
|
|
@@ -141,7 +122,7 @@ export async function createTokenWithBundleBuyMerkle(params) {
|
|
|
141
122
|
value: valueWei
|
|
142
123
|
};
|
|
143
124
|
signedTxs.push(await devWallet.signTransaction(createTxRequest));
|
|
144
|
-
// ✅
|
|
125
|
+
// ✅ 添加利润转账交易
|
|
145
126
|
if (extractProfit && profitAmount > 0n) {
|
|
146
127
|
const profitNonce = await nonceManager.getNextNonce(devWallet);
|
|
147
128
|
const profitTx = await devWallet.signTransaction({
|
|
@@ -276,27 +257,6 @@ async function executeBuyFlow(options) {
|
|
|
276
257
|
const extractProfit = shouldExtractProfit(config);
|
|
277
258
|
const analysis = analyzeBuyFunds(buyAmounts, config, extractProfit);
|
|
278
259
|
const finalGasLimit = getGasLimit(config);
|
|
279
|
-
// ✅ 获取贿赂金额
|
|
280
|
-
const bribeAmount = getBribeAmount(config);
|
|
281
|
-
const needBribeTx = bribeAmount > 0n;
|
|
282
|
-
const payer = profitMode.type === 'aggregated' ? (profitMode.payer ?? wallets[0]) : wallets[0];
|
|
283
|
-
// ✅ 贿赂交易放在首位
|
|
284
|
-
const signedTxs = [];
|
|
285
|
-
let bribeNonceOffset = 0;
|
|
286
|
-
if (needBribeTx) {
|
|
287
|
-
const bribeNonce = await nonceManager.getNextNonce(payer);
|
|
288
|
-
const bribeTx = await payer.signTransaction({
|
|
289
|
-
to: BLOCKRAZOR_BUILDER_EOA,
|
|
290
|
-
value: bribeAmount,
|
|
291
|
-
nonce: bribeNonce,
|
|
292
|
-
gasPrice,
|
|
293
|
-
gasLimit: 21000n,
|
|
294
|
-
chainId,
|
|
295
|
-
type: txType
|
|
296
|
-
});
|
|
297
|
-
signedTxs.push(bribeTx);
|
|
298
|
-
bribeNonceOffset = 1; // payer 的买入交易 nonce 需要偏移
|
|
299
|
-
}
|
|
300
260
|
// ✅ 优化:并行执行 populateBuyTransactions 和批量获取 nonces(JSON-RPC 批量请求)
|
|
301
261
|
const [unsignedBuys, nonces] = await Promise.all([
|
|
302
262
|
populateBuyTransactions({
|
|
@@ -307,24 +267,27 @@ async function executeBuyFlow(options) {
|
|
|
307
267
|
}),
|
|
308
268
|
nonceManager.getNextNoncesForWallets(wallets) // ✅ 批量获取 nonce
|
|
309
269
|
]);
|
|
310
|
-
// ✅
|
|
311
|
-
|
|
312
|
-
|
|
270
|
+
// ✅ 如果需要利润转账,预先获取 payer 的下一个 nonce
|
|
271
|
+
let profitNonce;
|
|
272
|
+
if (extractProfit && analysis.totalProfit > 0n && profitMode.type === 'aggregated') {
|
|
273
|
+
const payer = profitMode.payer ?? wallets[0];
|
|
274
|
+
profitNonce = await nonceManager.getNextNonce(payer);
|
|
275
|
+
}
|
|
313
276
|
// ✅ 并行签名所有买入交易
|
|
314
277
|
const signedBuys = await Promise.all(unsignedBuys.map((unsigned, index) => wallets[index].signTransaction({
|
|
315
278
|
...unsigned,
|
|
316
279
|
from: wallets[index].address,
|
|
317
|
-
nonce:
|
|
280
|
+
nonce: nonces[index],
|
|
318
281
|
gasLimit: finalGasLimit,
|
|
319
282
|
gasPrice,
|
|
320
283
|
chainId,
|
|
321
284
|
type: txType,
|
|
322
285
|
value: analysis.fundsList[index]
|
|
323
286
|
})));
|
|
324
|
-
signedTxs
|
|
325
|
-
// ✅
|
|
326
|
-
if (extractProfit &&
|
|
327
|
-
const
|
|
287
|
+
const signedTxs = [...signedBuys];
|
|
288
|
+
// ✅ 添加利润转账交易(使用预先获取的 nonce)
|
|
289
|
+
if (extractProfit && profitNonce !== undefined && profitMode.type === 'aggregated') {
|
|
290
|
+
const payer = profitMode.payer ?? wallets[0];
|
|
328
291
|
const profitTx = await payer.signTransaction({
|
|
329
292
|
to: getProfitRecipient(),
|
|
330
293
|
value: analysis.totalProfit,
|
|
@@ -344,9 +307,6 @@ async function executeSellFlow(options) {
|
|
|
344
307
|
const amountsWei = sellAmounts.map((amount) => ethers.parseUnits(amount, 18));
|
|
345
308
|
const finalGasLimit = getGasLimit(config);
|
|
346
309
|
const extractProfit = shouldExtractProfit(config);
|
|
347
|
-
// ✅ 获取贿赂金额
|
|
348
|
-
const bribeAmount = getBribeAmount(config);
|
|
349
|
-
const needBribeTx = bribeAmount > 0n;
|
|
350
310
|
// ✅ 优化:并行执行 resolveSellOutputs、ensureSellerBalances、ensureSellAllowances 和批量获取 nonces
|
|
351
311
|
const [sellOutputs, , , nonces] = await Promise.all([
|
|
352
312
|
resolveSellOutputs({
|
|
@@ -366,29 +326,6 @@ async function executeSellFlow(options) {
|
|
|
366
326
|
}),
|
|
367
327
|
nonceManager.getNextNoncesForWallets(wallets) // ✅ 批量获取 nonce(JSON-RPC 批量请求)
|
|
368
328
|
]);
|
|
369
|
-
// ✅ 找出收益最多的钱包作为 payer(贿赂和利润都由它发送)
|
|
370
|
-
const { totalProfit, payer } = summarizeSellProfits(sellOutputs.quotedOutputs, wallets, config);
|
|
371
|
-
const payerWallet = payer ?? wallets[0];
|
|
372
|
-
const payerIndex = wallets.findIndex(w => w.address.toLowerCase() === payerWallet.address.toLowerCase());
|
|
373
|
-
// ✅ 贿赂交易放在首位
|
|
374
|
-
const signedTxs = [];
|
|
375
|
-
let bribeNonceOffset = 0;
|
|
376
|
-
if (needBribeTx) {
|
|
377
|
-
const bribeNonce = nonces[payerIndex];
|
|
378
|
-
const bribeTx = await payerWallet.signTransaction({
|
|
379
|
-
to: BLOCKRAZOR_BUILDER_EOA,
|
|
380
|
-
value: bribeAmount,
|
|
381
|
-
nonce: bribeNonce,
|
|
382
|
-
gasPrice,
|
|
383
|
-
gasLimit: 21000n,
|
|
384
|
-
chainId,
|
|
385
|
-
type: txType
|
|
386
|
-
});
|
|
387
|
-
signedTxs.push(bribeTx);
|
|
388
|
-
bribeNonceOffset = 1;
|
|
389
|
-
}
|
|
390
|
-
// ✅ 调整 payer 的 nonce(如果有贿赂交易,需要偏移)
|
|
391
|
-
const adjustedNonces = nonces.map((n, i) => i === payerIndex ? n + bribeNonceOffset : n);
|
|
392
329
|
// ✅ 构建未签名交易
|
|
393
330
|
const unsignedSells = await populateSellTransactions({
|
|
394
331
|
sellers: wallets,
|
|
@@ -401,24 +338,23 @@ async function executeSellFlow(options) {
|
|
|
401
338
|
const signedSells = await Promise.all(unsignedSells.map((unsigned, index) => wallets[index].signTransaction({
|
|
402
339
|
...unsigned,
|
|
403
340
|
from: wallets[index].address,
|
|
404
|
-
nonce:
|
|
341
|
+
nonce: nonces[index],
|
|
405
342
|
gasLimit: finalGasLimit,
|
|
406
343
|
gasPrice,
|
|
407
344
|
chainId,
|
|
408
345
|
type: txType
|
|
409
346
|
})));
|
|
410
|
-
signedTxs
|
|
411
|
-
|
|
347
|
+
const signedTxs = [...signedSells];
|
|
348
|
+
const { totalProfit, payer } = summarizeSellProfits(sellOutputs.quotedOutputs, wallets, config);
|
|
412
349
|
await appendAggregatedProfitTransfer({
|
|
413
350
|
extractProfit,
|
|
414
351
|
totalProfit,
|
|
415
|
-
payer
|
|
352
|
+
payer,
|
|
416
353
|
nonceManager,
|
|
417
354
|
gasPrice,
|
|
418
355
|
chainId,
|
|
419
356
|
txType,
|
|
420
|
-
signedTxs
|
|
421
|
-
baseNonce: adjustedNonces[payerIndex] + 1 // ✅ 传入基础 nonce
|
|
357
|
+
signedTxs
|
|
422
358
|
});
|
|
423
359
|
return { signedTxs };
|
|
424
360
|
}
|
|
@@ -476,8 +412,7 @@ async function resolveSellOutputs(params) {
|
|
|
476
412
|
try {
|
|
477
413
|
const result = await trySell('BSC', rpcUrl, tokenAddress, amountsWei[0]);
|
|
478
414
|
const quotedOutputs = [result.funds];
|
|
479
|
-
|
|
480
|
-
const minOuts = [0n];
|
|
415
|
+
const minOuts = quotedOutputs.map((quote) => (quote * 95n) / 100n);
|
|
481
416
|
return { minOuts, quotedOutputs };
|
|
482
417
|
}
|
|
483
418
|
catch {
|
|
@@ -510,8 +445,7 @@ async function resolveSellOutputs(params) {
|
|
|
510
445
|
}
|
|
511
446
|
return 0n;
|
|
512
447
|
});
|
|
513
|
-
|
|
514
|
-
const minOuts = quotedOutputs.map(() => 0n);
|
|
448
|
+
const minOuts = quotedOutputs.map((quote) => (quote * 95n) / 100n);
|
|
515
449
|
return { minOuts, quotedOutputs };
|
|
516
450
|
}
|
|
517
451
|
catch {
|
|
@@ -525,8 +459,7 @@ async function resolveSellOutputs(params) {
|
|
|
525
459
|
return 0n;
|
|
526
460
|
}
|
|
527
461
|
}));
|
|
528
|
-
|
|
529
|
-
const minOuts = quotedOutputs.map(() => 0n);
|
|
462
|
+
const minOuts = quotedOutputs.map((quote) => (quote * 95n) / 100n);
|
|
530
463
|
return { minOuts, quotedOutputs };
|
|
531
464
|
}
|
|
532
465
|
}
|
|
@@ -576,12 +509,11 @@ function summarizeSellProfits(quotedOutputs, sellers, config) {
|
|
|
576
509
|
return { totalProfit, payer };
|
|
577
510
|
}
|
|
578
511
|
async function appendAggregatedProfitTransfer(params) {
|
|
579
|
-
const { extractProfit, totalProfit, payer, nonceManager, gasPrice, chainId, txType, signedTxs
|
|
512
|
+
const { extractProfit, totalProfit, payer, nonceManager, gasPrice, chainId, txType, signedTxs } = params;
|
|
580
513
|
if (!extractProfit || totalProfit <= 0n || !payer) {
|
|
581
514
|
return;
|
|
582
515
|
}
|
|
583
|
-
|
|
584
|
-
const profitNonce = baseNonce ?? await nonceManager.getNextNonce(payer);
|
|
516
|
+
const profitNonce = await nonceManager.getNextNonce(payer);
|
|
585
517
|
const profitTx = await payer.signTransaction({
|
|
586
518
|
to: getProfitRecipient(),
|
|
587
519
|
value: totalProfit,
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { ethers, Wallet, JsonRpcProvider, Contract, Interface } from 'ethers';
|
|
2
2
|
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
3
3
|
import { ADDRESSES } from '../../utils/constants.js';
|
|
4
|
-
import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient
|
|
4
|
+
import { getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient } from './config.js';
|
|
5
5
|
import { batchCheckAllowances } from '../../utils/erc20.js';
|
|
6
|
-
// ✅ BlockRazor Builder EOA 地址(用于贿赂)
|
|
7
|
-
const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
|
|
8
6
|
const MULTICALL3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11';
|
|
9
7
|
const MULTICALL3_ABI = [
|
|
10
8
|
'function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) external payable returns (tuple(bool success, bytes returnData)[])'
|
|
@@ -305,22 +303,15 @@ export async function fourPancakeProxyBatchBuyMerkle(params) {
|
|
|
305
303
|
const actualAmountsWei = remainingAmounts; // 扣除利润后用于购买的金额
|
|
306
304
|
const finalGasLimit = getGasLimit(config);
|
|
307
305
|
const nonceManager = new NonceManager(provider);
|
|
308
|
-
// ✅ 获取贿赂金额
|
|
309
|
-
const bribeAmount = getBribeAmount(config);
|
|
310
|
-
const needBribeTx = bribeAmount > 0n;
|
|
311
306
|
// ✅ 优化:并行获取 gasPrice 和 tokenDecimals
|
|
312
307
|
const [gasPrice, tokenDecimals] = await Promise.all([
|
|
313
308
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
314
309
|
getTokenDecimals(tokenAddress, provider)
|
|
315
310
|
]);
|
|
316
311
|
// ✅ 修复:先计算需要的 nonce 数量,再统一获取
|
|
317
|
-
// buyers[0] 可能需要
|
|
312
|
+
// buyers[0] 可能需要 2 个 nonce(买入 + 利润转账)
|
|
318
313
|
const needProfitTx = extractProfit && totalProfit > 0n;
|
|
319
|
-
|
|
320
|
-
if (needBribeTx)
|
|
321
|
-
buyer0NeedCount++; // 贿赂交易
|
|
322
|
-
if (needProfitTx)
|
|
323
|
-
buyer0NeedCount++; // 利润交易
|
|
314
|
+
const buyer0NeedCount = needProfitTx ? 2 : 1;
|
|
324
315
|
// 获取 buyers[0] 的连续 nonces
|
|
325
316
|
const buyer0Nonces = await nonceManager.getNextNonceBatch(buyers[0], buyer0NeedCount);
|
|
326
317
|
// 获取其他 buyers 的 nonces(如果有)
|
|
@@ -328,13 +319,9 @@ export async function fourPancakeProxyBatchBuyMerkle(params) {
|
|
|
328
319
|
if (buyers.length > 1) {
|
|
329
320
|
otherNonces = await nonceManager.getNextNoncesForWallets(buyers.slice(1));
|
|
330
321
|
}
|
|
331
|
-
// 分配 nonces
|
|
332
|
-
let buyer0NonceIdx = 0;
|
|
333
|
-
const bribeNonce = needBribeTx ? buyer0Nonces[buyer0NonceIdx++] : undefined;
|
|
334
|
-
const buyer0BuyNonce = buyer0Nonces[buyer0NonceIdx++];
|
|
335
|
-
const profitNonce = needProfitTx ? buyer0Nonces[buyer0NonceIdx] : undefined;
|
|
336
322
|
// 组装最终的 nonces 数组
|
|
337
|
-
const nonces = [
|
|
323
|
+
const nonces = [buyer0Nonces[0], ...otherNonces];
|
|
324
|
+
const profitNonce = needProfitTx ? buyer0Nonces[1] : undefined;
|
|
338
325
|
// 计算 minOutputAmounts
|
|
339
326
|
let minOuts;
|
|
340
327
|
if (params.minOutputAmounts && params.minOutputAmounts.length === buyers.length) {
|
|
@@ -369,22 +356,8 @@ export async function fourPancakeProxyBatchBuyMerkle(params) {
|
|
|
369
356
|
else {
|
|
370
357
|
throw new Error(`Unsupported routeType: ${routeType}`);
|
|
371
358
|
}
|
|
372
|
-
// ✅ 贿赂交易放在首位
|
|
373
|
-
const signedTxs = [];
|
|
374
|
-
if (needBribeTx && bribeNonce !== undefined) {
|
|
375
|
-
const bribeTx = await buyers[0].signTransaction({
|
|
376
|
-
to: BLOCKRAZOR_BUILDER_EOA,
|
|
377
|
-
value: bribeAmount,
|
|
378
|
-
nonce: bribeNonce,
|
|
379
|
-
gasPrice,
|
|
380
|
-
gasLimit: 21000n,
|
|
381
|
-
chainId: 56,
|
|
382
|
-
type: txType
|
|
383
|
-
});
|
|
384
|
-
signedTxs.push(bribeTx);
|
|
385
|
-
}
|
|
386
359
|
// ✅ 并行签名所有买入交易
|
|
387
|
-
const
|
|
360
|
+
const signedTxs = await Promise.all(unsignedBuys.map((unsigned, i) => buyers[i].signTransaction({
|
|
388
361
|
...unsigned,
|
|
389
362
|
from: buyers[i].address,
|
|
390
363
|
nonce: nonces[i],
|
|
@@ -394,8 +367,7 @@ export async function fourPancakeProxyBatchBuyMerkle(params) {
|
|
|
394
367
|
type: txType,
|
|
395
368
|
value: unsigned.value // ✅ 显式保留 value(BNB 金额 + 手续费)
|
|
396
369
|
})));
|
|
397
|
-
|
|
398
|
-
// ✅ 添加利润转账(放在末尾,使用预先获取的 nonce)
|
|
370
|
+
// ✅ 添加利润转账(使用预先获取的 nonce)
|
|
399
371
|
if (extractProfit && totalProfit > 0n && profitNonce !== undefined) {
|
|
400
372
|
const profitTx = await buyers[0].signTransaction({
|
|
401
373
|
to: getProfitRecipient(),
|
|
@@ -437,9 +409,6 @@ export async function fourPancakeProxyBatchSellMerkle(params) {
|
|
|
437
409
|
const finalGasLimit = getGasLimit(config);
|
|
438
410
|
const nonceManager = new NonceManager(provider);
|
|
439
411
|
const extractProfit = shouldExtractProfit(config);
|
|
440
|
-
// ✅ 获取贿赂金额
|
|
441
|
-
const bribeAmount = getBribeAmount(config);
|
|
442
|
-
const needBribeTx = bribeAmount > 0n;
|
|
443
412
|
// ✅ 优化:并行获取 gasPrice、tokenDecimals 和 allowances
|
|
444
413
|
const [gasPrice, tokenDecimals, allowances] = await Promise.all([
|
|
445
414
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
@@ -460,40 +429,48 @@ export async function fourPancakeProxyBatchSellMerkle(params) {
|
|
|
460
429
|
if (needApprovalIndexes.length > 0) {
|
|
461
430
|
throw new Error(`需要授权: ${needApprovalIndexes.length} 个钱包尚未授权。请先完成授权后再卖出。`);
|
|
462
431
|
}
|
|
463
|
-
// ✅
|
|
432
|
+
// ✅ 自动获取报价或使用用户提供的 minOutputAmounts
|
|
433
|
+
let minOuts;
|
|
464
434
|
let quotedOutputs;
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
else if (routeType === 'v3-single') {
|
|
470
|
-
// V3 单跳:并行调用(V3 Quoter 是 non-view 函数,不支持 Multicall3)
|
|
471
|
-
quotedOutputs = await Promise.all(amountsWei.map(async (amount) => {
|
|
472
|
-
try {
|
|
473
|
-
const quoter = new Contract(PANCAKE_V3_QUOTER_ADDRESS, PANCAKE_V3_QUOTER_ABI, provider);
|
|
474
|
-
const result = await quoter.quoteExactInputSingle.staticCall({
|
|
475
|
-
tokenIn: tokenAddress,
|
|
476
|
-
tokenOut: params.v3TokenOut,
|
|
477
|
-
amountIn: amount,
|
|
478
|
-
fee: params.v3Fee,
|
|
479
|
-
sqrtPriceLimitX96: 0
|
|
480
|
-
});
|
|
481
|
-
return result[0];
|
|
482
|
-
}
|
|
483
|
-
catch {
|
|
484
|
-
return 0n;
|
|
485
|
-
}
|
|
486
|
-
}));
|
|
487
|
-
}
|
|
488
|
-
else if (routeType === 'v3-multi' && params.v2Path && params.v2Path.length >= 2) {
|
|
489
|
-
// V3 多跳:使用 V2 备选路由
|
|
490
|
-
quotedOutputs = await batchGetV2Quotes(provider, amountsWei, params.v2Path);
|
|
435
|
+
if (params.minOutputAmounts && params.minOutputAmounts.length === sellers.length) {
|
|
436
|
+
// 用户提供了 minOutputAmounts,跳过报价查询
|
|
437
|
+
minOuts = params.minOutputAmounts.map(m => typeof m === 'string' ? ethers.parseEther(m) : m);
|
|
438
|
+
quotedOutputs = minOuts.map(m => m * 100n / 95n); // 反推预期收益
|
|
491
439
|
}
|
|
492
440
|
else {
|
|
493
|
-
|
|
441
|
+
// ✅ 使用 Multicall3 批量获取报价(仅 V2 路由支持)
|
|
442
|
+
if (routeType === 'v2' && params.v2Path && params.v2Path.length >= 2) {
|
|
443
|
+
quotedOutputs = await batchGetV2Quotes(provider, amountsWei, params.v2Path);
|
|
444
|
+
}
|
|
445
|
+
else if (routeType === 'v3-single') {
|
|
446
|
+
// V3 单跳:并行调用(V3 Quoter 是 non-view 函数,不支持 Multicall3)
|
|
447
|
+
quotedOutputs = await Promise.all(amountsWei.map(async (amount) => {
|
|
448
|
+
try {
|
|
449
|
+
const quoter = new Contract(PANCAKE_V3_QUOTER_ADDRESS, PANCAKE_V3_QUOTER_ABI, provider);
|
|
450
|
+
const result = await quoter.quoteExactInputSingle.staticCall({
|
|
451
|
+
tokenIn: tokenAddress,
|
|
452
|
+
tokenOut: params.v3TokenOut,
|
|
453
|
+
amountIn: amount,
|
|
454
|
+
fee: params.v3Fee,
|
|
455
|
+
sqrtPriceLimitX96: 0
|
|
456
|
+
});
|
|
457
|
+
return result[0];
|
|
458
|
+
}
|
|
459
|
+
catch {
|
|
460
|
+
return 0n;
|
|
461
|
+
}
|
|
462
|
+
}));
|
|
463
|
+
}
|
|
464
|
+
else if (routeType === 'v3-multi' && params.v2Path && params.v2Path.length >= 2) {
|
|
465
|
+
// V3 多跳:使用 V2 备选路由
|
|
466
|
+
quotedOutputs = await batchGetV2Quotes(provider, amountsWei, params.v2Path);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
quotedOutputs = new Array(amountsWei.length).fill(0n);
|
|
470
|
+
}
|
|
471
|
+
// ✅ minOuts = 0,不设置滑点限制(大额交易更稳定)
|
|
472
|
+
minOuts = quotedOutputs.map(() => 0n);
|
|
494
473
|
}
|
|
495
|
-
// ✅ 已移除滑点保护:minOuts 固定为 0
|
|
496
|
-
const minOuts = new Array(sellers.length).fill(0n);
|
|
497
474
|
// ✅ 计算利润并找出收益最多的钱包
|
|
498
475
|
let totalProfit = 0n;
|
|
499
476
|
let maxRevenueIndex = 0;
|
|
@@ -512,43 +489,32 @@ export async function fourPancakeProxyBatchSellMerkle(params) {
|
|
|
512
489
|
}
|
|
513
490
|
// ✅ 修复:先计算需要的 nonce 数量,再统一获取
|
|
514
491
|
const needProfitTx = extractProfit && totalProfit > 0n && maxRevenue > 0n;
|
|
515
|
-
// 分配 nonces:收益最多的钱包可能需要
|
|
492
|
+
// 分配 nonces:收益最多的钱包可能需要 2 个 nonce(卖出 + 利润转账)
|
|
516
493
|
let nonces;
|
|
517
|
-
let bribeNonce;
|
|
518
494
|
let profitNonce;
|
|
519
|
-
if (
|
|
520
|
-
//
|
|
521
|
-
|
|
522
|
-
if (needBribeTx)
|
|
523
|
-
maxRevenueNonceCount++; // 贿赂交易
|
|
524
|
-
if (needProfitTx)
|
|
525
|
-
maxRevenueNonceCount++; // 利润交易
|
|
526
|
-
// 收益最多的钱包需要连续 nonce
|
|
527
|
-
const maxRevenueNonces = await nonceManager.getNextNonceBatch(sellers[maxRevenueIndex], maxRevenueNonceCount);
|
|
495
|
+
if (needProfitTx) {
|
|
496
|
+
// 收益最多的钱包需要 2 个连续 nonce
|
|
497
|
+
const maxRevenueNonces = await nonceManager.getNextNonceBatch(sellers[maxRevenueIndex], 2);
|
|
528
498
|
// 其他钱包各需要 1 个 nonce
|
|
529
499
|
const otherSellers = sellers.filter((_, i) => i !== maxRevenueIndex);
|
|
530
500
|
const otherNonces = otherSellers.length > 0
|
|
531
501
|
? await nonceManager.getNextNoncesForWallets(otherSellers)
|
|
532
502
|
: [];
|
|
533
|
-
// 分配收益最多钱包的 nonces
|
|
534
|
-
let maxRevenueNonceIdx = 0;
|
|
535
|
-
bribeNonce = needBribeTx ? maxRevenueNonces[maxRevenueNonceIdx++] : undefined;
|
|
536
|
-
const maxRevenueSellNonce = maxRevenueNonces[maxRevenueNonceIdx++];
|
|
537
|
-
profitNonce = needProfitTx ? maxRevenueNonces[maxRevenueNonceIdx] : undefined;
|
|
538
503
|
// 组装最终的 nonces 数组(保持原顺序)
|
|
539
504
|
nonces = [];
|
|
540
505
|
let otherIdx = 0;
|
|
541
506
|
for (let i = 0; i < sellers.length; i++) {
|
|
542
507
|
if (i === maxRevenueIndex) {
|
|
543
|
-
nonces.push(
|
|
508
|
+
nonces.push(maxRevenueNonces[0]); // 卖出交易用第一个 nonce
|
|
544
509
|
}
|
|
545
510
|
else {
|
|
546
511
|
nonces.push(otherNonces[otherIdx++]);
|
|
547
512
|
}
|
|
548
513
|
}
|
|
514
|
+
profitNonce = maxRevenueNonces[1]; // 利润交易用第二个 nonce
|
|
549
515
|
}
|
|
550
516
|
else {
|
|
551
|
-
//
|
|
517
|
+
// 不需要利润交易,所有钱包各 1 个 nonce
|
|
552
518
|
nonces = await nonceManager.getNextNoncesForWallets(sellers);
|
|
553
519
|
}
|
|
554
520
|
// 卖出不需要发送 BNB,只需要 flatFee
|
|
@@ -577,22 +543,8 @@ export async function fourPancakeProxyBatchSellMerkle(params) {
|
|
|
577
543
|
else {
|
|
578
544
|
throw new Error(`Unsupported routeType: ${routeType}`);
|
|
579
545
|
}
|
|
580
|
-
// ✅ 贿赂交易放在首位
|
|
581
|
-
const signedTxs = [];
|
|
582
|
-
if (needBribeTx && bribeNonce !== undefined) {
|
|
583
|
-
const bribeTx = await sellers[maxRevenueIndex].signTransaction({
|
|
584
|
-
to: BLOCKRAZOR_BUILDER_EOA,
|
|
585
|
-
value: bribeAmount,
|
|
586
|
-
nonce: bribeNonce,
|
|
587
|
-
gasPrice,
|
|
588
|
-
gasLimit: 21000n,
|
|
589
|
-
chainId: 56,
|
|
590
|
-
type: txType
|
|
591
|
-
});
|
|
592
|
-
signedTxs.push(bribeTx);
|
|
593
|
-
}
|
|
594
546
|
// ✅ 并行签名所有卖出交易
|
|
595
|
-
const
|
|
547
|
+
const signedTxs = await Promise.all(unsignedSells.map((unsigned, i) => sellers[i].signTransaction({
|
|
596
548
|
...unsigned,
|
|
597
549
|
from: sellers[i].address,
|
|
598
550
|
nonce: nonces[i],
|
|
@@ -602,8 +554,7 @@ export async function fourPancakeProxyBatchSellMerkle(params) {
|
|
|
602
554
|
type: txType,
|
|
603
555
|
value: unsigned.value // ✅ 显式保留 value(手续费)
|
|
604
556
|
})));
|
|
605
|
-
|
|
606
|
-
// ✅ 添加利润转账(放在末尾,使用预先获取的 nonce)
|
|
557
|
+
// ✅ 添加利润转账(使用预先获取的 nonce)
|
|
607
558
|
if (extractProfit && totalProfit > 0n && profitNonce !== undefined) {
|
|
608
559
|
const profitTx = await sellers[maxRevenueIndex].signTransaction({
|
|
609
560
|
to: getProfitRecipient(),
|
|
@@ -7,6 +7,7 @@ import { CommonBundleConfig } from '../../utils/bundle-helpers.js';
|
|
|
7
7
|
import { FourSignConfig } from './types.js';
|
|
8
8
|
export interface FourBuyFirstSignConfig extends FourSignConfig {
|
|
9
9
|
reserveGasBNB?: number;
|
|
10
|
+
slippageBps?: number;
|
|
10
11
|
}
|
|
11
12
|
export interface FourBuyFirstConfig extends CommonBundleConfig {
|
|
12
13
|
apiKey: string;
|
|
@@ -7,10 +7,8 @@ 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
|
|
10
|
+
import { getTxType, getGasPriceConfig, getProfitRecipient, getProfitRateBps } from './config.js';
|
|
11
11
|
import { trySell } from '../tm.js';
|
|
12
|
-
// ✅ BlockRazor Builder EOA 地址(用于贿赂)
|
|
13
|
-
const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
|
|
14
12
|
/**
|
|
15
13
|
* 获取 Gas Limit(支持 FourAnyConfig)
|
|
16
14
|
*/
|
|
@@ -84,19 +82,14 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
84
82
|
// ✅ 优化:第三批并行 - trySell、构建交易、获取 nonces
|
|
85
83
|
const tmBuyer = new Contract(TM_ADDRESS, TM_ABI, buyer);
|
|
86
84
|
const tmSeller = new Contract(TM_ADDRESS, TM_ABI, seller);
|
|
87
|
-
|
|
88
|
-
const minBuyAmount =
|
|
85
|
+
const slippageBps = config.slippageBps ?? 100;
|
|
86
|
+
const minBuyAmount = (estimatedTokenAmount * BigInt(10000 - slippageBps)) / 10000n;
|
|
89
87
|
// 预先规划 nonces
|
|
90
88
|
const extractProfit = true;
|
|
91
89
|
const profitRateBps = getProfitRateBps();
|
|
92
|
-
// ✅ 获取贿赂金额
|
|
93
|
-
const bribeAmount = getBribeAmount(config);
|
|
94
|
-
const needBribeTx = bribeAmount > 0n;
|
|
95
90
|
// 计算需要的 nonce 数量
|
|
96
91
|
let buyerNonceCount = 1; // 买入交易
|
|
97
92
|
let sellerNonceCount = 1; // 卖出交易
|
|
98
|
-
if (needBribeTx)
|
|
99
|
-
sellerNonceCount++; // 贿赂交易(由卖方发送)
|
|
100
93
|
if (needApproval)
|
|
101
94
|
sellerNonceCount++; // 授权交易
|
|
102
95
|
if (extractProfit)
|
|
@@ -128,8 +121,7 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
128
121
|
]);
|
|
129
122
|
const { buyerNonces, sellerNonces } = noncesResult;
|
|
130
123
|
const estimatedSellFunds = sellResult.funds;
|
|
131
|
-
|
|
132
|
-
const minSellFunds = 0n;
|
|
124
|
+
const minSellFunds = (estimatedSellFunds * BigInt(10000 - slippageBps)) / 10000n;
|
|
133
125
|
const profitAmount = extractProfit ? (estimatedSellFunds * BigInt(profitRateBps)) / 10000n : 0n;
|
|
134
126
|
// 更新卖出交易的 minSellFunds
|
|
135
127
|
sellUnsigned.data = tmSeller.interface.encodeFunctionData('sellToken', [
|
|
@@ -138,13 +130,10 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
138
130
|
// 分配 nonces
|
|
139
131
|
let buyerNonce;
|
|
140
132
|
let sellerNonce;
|
|
141
|
-
let bribeNonce;
|
|
142
133
|
let approvalNonce;
|
|
143
134
|
let profitNonce;
|
|
144
135
|
if (sameAddress) {
|
|
145
136
|
let idx = 0;
|
|
146
|
-
if (needBribeTx)
|
|
147
|
-
bribeNonce = sellerNonces[idx++];
|
|
148
137
|
if (needApproval)
|
|
149
138
|
approvalNonce = sellerNonces[idx++];
|
|
150
139
|
buyerNonce = sellerNonces[idx++];
|
|
@@ -155,8 +144,6 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
155
144
|
else {
|
|
156
145
|
buyerNonce = buyerNonces[0];
|
|
157
146
|
let idx = 0;
|
|
158
|
-
if (needBribeTx)
|
|
159
|
-
bribeNonce = sellerNonces[idx++];
|
|
160
147
|
if (needApproval)
|
|
161
148
|
approvalNonce = sellerNonces[idx++];
|
|
162
149
|
sellerNonce = sellerNonces[idx++];
|
|
@@ -165,19 +152,6 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
165
152
|
}
|
|
166
153
|
// ✅ 并行签名所有交易
|
|
167
154
|
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
|
-
}
|
|
181
155
|
// 授权交易
|
|
182
156
|
let approvalTx = null;
|
|
183
157
|
if (needApproval && approvalNonce !== undefined) {
|
|
@@ -216,7 +190,7 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
216
190
|
type: txType,
|
|
217
191
|
value: 0n // ✅ 卖出交易不发送原生代币
|
|
218
192
|
}));
|
|
219
|
-
//
|
|
193
|
+
// 利润交易
|
|
220
194
|
let profitTx = null;
|
|
221
195
|
if (extractProfit && profitAmount > 0n && profitNonce !== undefined) {
|
|
222
196
|
signPromises.push(seller.signTransaction({
|
|
@@ -232,8 +206,6 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
232
206
|
const signedTxs = await Promise.all(signPromises);
|
|
233
207
|
// 解析签名结果
|
|
234
208
|
let idx = 0;
|
|
235
|
-
if (needBribeTx)
|
|
236
|
-
bribeTx = signedTxs[idx++];
|
|
237
209
|
if (needApproval)
|
|
238
210
|
approvalTx = signedTxs[idx++];
|
|
239
211
|
const signedBuy = signedTxs[idx++];
|
|
@@ -241,10 +213,8 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
241
213
|
if (extractProfit && profitAmount > 0n)
|
|
242
214
|
profitTx = signedTxs[idx];
|
|
243
215
|
nonceManager.clearTemp();
|
|
244
|
-
//
|
|
216
|
+
// 组装交易列表
|
|
245
217
|
const allTransactions = [];
|
|
246
|
-
if (bribeTx)
|
|
247
|
-
allTransactions.push(bribeTx);
|
|
248
218
|
if (approvalTx)
|
|
249
219
|
allTransactions.push(approvalTx);
|
|
250
220
|
allTransactions.push(signedBuy, signedSell);
|