four-flap-meme-sdk 4.0.8 → 4.0.9
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/bundle/four-meme/swap/batch.js +4 -3
- package/dist/bundle/four-meme/swap/bundle.js +5 -3
- package/dist/bundle/four-meme/swap/quick-batch.js +3 -3
- package/dist/bundle/four-meme/swap-buy-first/multi-wallet.js +3 -6
- package/dist/bundle/four-meme/swap-buy-first/single.js +5 -6
- package/dist/chains/bsc/pancake/bundle-buy-first-multi-wallet.js +10 -14
- package/dist/chains/bsc/pancake/bundle-buy-first.js +10 -15
- package/dist/chains/bsc/pancake/quote.d.ts +1 -1
- package/dist/chains/bsc/pancake/quote.js +3 -4
- package/dist/chains/eni/platforms/daoaas/portal-direct-submit.js +4 -4
- package/dist/chains/xlayer/eip7702/bundle-swap-multi.js +4 -4
- package/dist/chains/xlayer/eip7702/profit.d.ts +6 -12
- package/dist/chains/xlayer/eip7702/profit.js +15 -16
- package/dist/chains/xlayer/eip7702/volume-bundle.js +5 -5
- package/dist/chains/xlayer/eip7702/volume-wash.js +4 -4
- package/dist/chains/xlayer/eoa/quote.d.ts +1 -1
- package/dist/chains/xlayer/eoa/quote.js +3 -4
- package/dist/core/constants/index.d.ts +2 -2
- package/dist/core/constants/index.js +2 -2
- package/dist/core/constants/profit.d.ts +6 -1
- package/dist/core/constants/profit.js +11 -1
- package/dist/core/constants/profit.test.d.ts +1 -0
- package/dist/core/constants/profit.test.js +18 -0
- package/dist/core/constants/quote.d.ts +2 -0
- package/dist/core/constants/quote.js +13 -0
- package/dist/core/quote/quote-helpers.d.ts +11 -0
- package/dist/core/quote/quote-helpers.js +42 -1
- package/dist/domains/flap/portal-bundle-merkle/core-helpers.js +3 -35
- package/dist/domains/flap/portal-bundle-merkle/swap-batch.js +9 -6
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first-multi-wallet.js +10 -12
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first-quote.js +3 -24
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first.js +10 -14
- package/dist/domains/flap/portal-bundle-merkle/swap-helpers.js +3 -23
- package/dist/domains/flap/portal-bundle-merkle/swap-planning.d.ts +1 -1
- package/dist/domains/flap/portal-bundle-merkle/swap-planning.js +3 -8
- package/dist/domains/flap/portal-bundle-merkle/swap-quick-batch.js +4 -4
- package/dist/domains/flap/portal-bundle-merkle/swap-single.js +9 -8
- package/dist/exports/root-foundations.d.ts +1 -1
- package/dist/exports/root-foundations.js +1 -1
- package/dist/utils/constants.d.ts +1 -1
- package/dist/utils/constants.js +1 -1
- package/package.json +1 -1
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Four.meme 内盘批量换手(Merkle Bundle)— 一卖多买流程
|
|
3
3
|
*/
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
|
-
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAllowanceAndBalances,
|
|
5
|
+
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAllowanceAndBalances, needsTmTokenApproval, planSellerNonces, signTmMaxApprovalTx, } from '../swap-sign-helpers.js';
|
|
6
6
|
import { signBribeTransaction } from '../../../core/sign-context-helpers.js';
|
|
7
7
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, getOptimizedGasPrice, getGasPriceConfig, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
9
9
|
import { getBribeAmount, getProfitRecipient } from '../../config-helpers.js';
|
|
10
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
10
11
|
import { TM_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
11
12
|
/**
|
|
12
13
|
* Four 内盘批量换手(一卖多买)
|
|
@@ -58,8 +59,8 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
58
59
|
// 检查是否需要授权
|
|
59
60
|
const needApproval = needsTmTokenApproval(currentAllowance, decimals);
|
|
60
61
|
// 利润配置
|
|
61
|
-
const
|
|
62
|
-
const profitAmount = totalBuyerFunds > 0n ? (totalBuyerFunds
|
|
62
|
+
const buySum = buyAmountsWei.reduce((a, b) => a + b, 0n);
|
|
63
|
+
const profitAmount = totalBuyerFunds > 0n ? calculateBundleSwapRoundTripProfit(buySum, totalBuyerFunds) : 0n;
|
|
63
64
|
// ✅ 获取贿赂金额
|
|
64
65
|
const bribeAmount = getBribeAmount(config);
|
|
65
66
|
const needBribeTx = bribeAmount > 0n;
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Four.meme 内盘捆绑换手(Merkle Bundle)— 单卖单买流程
|
|
3
3
|
*/
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
|
-
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAndAllowance,
|
|
5
|
+
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAndAllowance, needsTmTokenApproval, planSellerNonces, signTmMaxApprovalTx, } from '../swap-sign-helpers.js';
|
|
6
6
|
import { signBribeTransaction } from '../../../core/sign-context-helpers.js';
|
|
7
7
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, getOptimizedGasPrice, getGasPriceConfig, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
9
9
|
import { getBribeAmount, getProfitRecipient } from '../../config-helpers.js';
|
|
10
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
10
11
|
import { TM_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
11
12
|
/**
|
|
12
13
|
* Four内盘捆绑换手
|
|
@@ -41,8 +42,9 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
41
42
|
const needApproval = needsTmTokenApproval(currentAllowance, decimals);
|
|
42
43
|
// 利润配置
|
|
43
44
|
const extractProfit = true;
|
|
44
|
-
const
|
|
45
|
-
|
|
45
|
+
const profitAmount = extractProfit && sellerWillGetBNB > 0n
|
|
46
|
+
? calculateBundleSwapRoundTripProfit(buyerFunds, sellerWillGetBNB)
|
|
47
|
+
: 0n;
|
|
46
48
|
// ✅ 获取贿赂金额
|
|
47
49
|
const bribeAmount = getBribeAmount(config);
|
|
48
50
|
const needBribeTx = bribeAmount > 0n;
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Four.meme 内盘快捷批量换手(Merkle Bundle)— 资金利用率模式流程
|
|
3
3
|
*/
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
|
-
import { createFourSwapGasContext,
|
|
5
|
+
import { createFourSwapGasContext, quoteFourSwapSellFunds, } from '../swap-sign-helpers.js';
|
|
6
6
|
import { generateDisperseHopPaths, buildNativeHopChain, NATIVE_TRANSFER_GAS_LIMIT } from '../swap-hop-helpers.js';
|
|
7
7
|
import { signBribeTransaction } from '../../../core/sign-context-helpers.js';
|
|
8
8
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
9
9
|
import { NonceManager, getOptimizedGasPrice, getGasPriceConfig, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
10
10
|
import { getBribeAmount, getProfitRecipient } from '../../config-helpers.js';
|
|
11
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
11
12
|
import { TM_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
12
13
|
/**
|
|
13
14
|
* Four 内盘快捷批量换手(资金利用率模式)
|
|
@@ -51,8 +52,7 @@ export async function fourQuickBatchSwapMerkle(params) {
|
|
|
51
52
|
const { amount: sellAmountWei, decimals } = sellAmountResult;
|
|
52
53
|
const estimatedBNBOut = await quoteFourSwapSellFunds(provider, tokenAddress, sellAmountWei);
|
|
53
54
|
// ✅ 计算利润(根据 userType 动态调整)
|
|
54
|
-
const
|
|
55
|
-
const profitAmount = estimatedBNBOut > 0n ? (estimatedBNBOut * BigInt(profitRateBps)) / 10000n : 0n;
|
|
55
|
+
const profitAmount = estimatedBNBOut > 0n ? calculateBundleSwapRoundTripProfit(estimatedBNBOut, estimatedBNBOut) : 0n;
|
|
56
56
|
const distributableAmount = estimatedBNBOut - profitAmount;
|
|
57
57
|
// ✅ 计算每个买方分到的金额
|
|
58
58
|
let transferAmountsWei;
|
|
@@ -5,12 +5,12 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
5
5
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
6
6
|
import { createSignProvider } from '../../../core/sign-context-helpers.js';
|
|
7
7
|
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
8
|
-
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS } from '../../../core/constants/index.js';
|
|
8
|
+
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
9
9
|
import { TM_ABI, HELPER3_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
10
10
|
import { getTxType, getGasPriceConfig, getProfitRecipient, getBribeAmount } from '../../config-helpers.js';
|
|
11
11
|
import { trySell } from '../../../domains/four/contracts/tm.js';
|
|
12
12
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
13
|
-
import {
|
|
13
|
+
import { validateSwapCounts } from './helpers.js';
|
|
14
14
|
/**
|
|
15
15
|
* ✅ Four 多钱包捆绑换手
|
|
16
16
|
* - 多个买方钱包执行买入(每个钱包1笔)
|
|
@@ -28,9 +28,6 @@ export async function fourBundleBuyFirstMultiWallet(params) {
|
|
|
28
28
|
throw new Error('卖方钱包数量不能为0');
|
|
29
29
|
// 验证总交易数不超过限制
|
|
30
30
|
validateSwapCounts(buyCount, sellCount);
|
|
31
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
32
|
-
const totalTxCount = buyCount + sellCount;
|
|
33
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
34
31
|
const chainIdNum = config.chainId ?? CHAINS.BSC.chainId;
|
|
35
32
|
const provider = createSignProvider(config.rpcUrl, chainIdNum, 'BSC');
|
|
36
33
|
const nonceManager = new NonceManager(provider);
|
|
@@ -85,7 +82,7 @@ export async function fourBundleBuyFirstMultiWallet(params) {
|
|
|
85
82
|
noncesMap.set(wallet.address.toLowerCase(), noncesArray[i]);
|
|
86
83
|
});
|
|
87
84
|
const estimatedSellFunds = sellResult.funds;
|
|
88
|
-
const profitAmount = (estimatedSellFunds
|
|
85
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalFundsWei, estimatedSellFunds > 0n ? estimatedSellFunds : totalFundsWei);
|
|
89
86
|
// ✅ 第三批并行:构建并签名所有交易
|
|
90
87
|
const allTransactions = [];
|
|
91
88
|
const tm = new Contract(TM_ADDRESS, TM_ABI, provider);
|
|
@@ -7,12 +7,12 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
7
7
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
8
8
|
import { createSignProvider } from '../../../core/sign-context-helpers.js';
|
|
9
9
|
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
10
|
-
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS } from '../../../core/constants/index.js';
|
|
10
|
+
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
11
11
|
import { TM_ABI, HELPER3_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
12
12
|
import { getTxType, getGasPriceConfig, getProfitRecipient, getBribeAmount } from '../../config-helpers.js';
|
|
13
13
|
import { trySell } from '../../../domains/four/contracts/tm.js';
|
|
14
14
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
15
|
-
import {
|
|
15
|
+
import { validateSwapCounts } from './helpers.js';
|
|
16
16
|
import { fourBundleBuyFirstMultiWallet } from './multi-wallet.js';
|
|
17
17
|
export async function fourBundleBuyFirstMerkle(params) {
|
|
18
18
|
const { buyerPrivateKey, buyerPrivateKeys, buyerFunds, buyerFundsPercentage, sellerPrivateKey, sellerPrivateKeys, tokenAddress, config, buyCount: _buyCount, sellCount: _sellCount, } = params;
|
|
@@ -35,9 +35,6 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
35
35
|
throw new Error('单钱包模式需要提供 buyerPrivateKey 和 sellerPrivateKey');
|
|
36
36
|
}
|
|
37
37
|
validateSwapCounts(buyCount, sellCount);
|
|
38
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
39
|
-
const totalTxCount = buyCount + sellCount;
|
|
40
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
41
38
|
const chainIdNum = config.chainId ?? CHAINS.BSC.chainId;
|
|
42
39
|
const provider = createSignProvider(config.rpcUrl, chainIdNum, 'BSC');
|
|
43
40
|
const buyer = new Wallet(buyerPrivateKey, provider);
|
|
@@ -117,7 +114,9 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
117
114
|
Promise.all(sellUnsignedPromises),
|
|
118
115
|
]);
|
|
119
116
|
const estimatedSellFunds = sellResult.funds;
|
|
120
|
-
const profitAmount = extractProfit
|
|
117
|
+
const profitAmount = extractProfit
|
|
118
|
+
? calculateBundleSwapRoundTripProfit(buyerFundsWei, estimatedSellFunds > 0n ? estimatedSellFunds : buyerFundsWei)
|
|
119
|
+
: 0n;
|
|
121
120
|
// ✅ 贿赂交易放在首位
|
|
122
121
|
let bribeTx = null;
|
|
123
122
|
if (needBribeTx && multiNoncePlan.bribeNonce !== undefined) {
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
import { ethers, Wallet } from 'ethers';
|
|
5
5
|
import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
6
6
|
import { NonceManager, getDeadline } from '../../../utils/bundle-helpers.js';
|
|
7
|
-
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS } from '../../../core/constants/index.js';
|
|
8
|
-
import {
|
|
7
|
+
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
8
|
+
import { quoteRoundTripProfitToNative } from '../../../core/quote/quote-helpers.js';
|
|
9
9
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
10
10
|
import { createPancakeContext, getGasPrice, quoteTokenOutput } from './bundle-buy-first-quote.js';
|
|
11
|
-
import {
|
|
11
|
+
import { validateSwapCounts } from './bundle-buy-first-plan.js';
|
|
12
12
|
import { buildSingleBuyTx, buildSingleSellTx } from './bundle-buy-first-build.js';
|
|
13
13
|
import { buildProfitTransaction } from './bundle-buy-first-profit.js';
|
|
14
14
|
/**
|
|
@@ -29,9 +29,6 @@ export async function pancakeBundleBuyFirstMultiWallet(params) {
|
|
|
29
29
|
throw new Error('卖方钱包数量不能为0');
|
|
30
30
|
// 验证总交易数不超过限制
|
|
31
31
|
validateSwapCounts(buyCount, sellCount);
|
|
32
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
33
|
-
const totalTxCount = buyCount + sellCount;
|
|
34
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
35
32
|
// ✅ 判断是否使用原生代币
|
|
36
33
|
const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
|
|
37
34
|
const context = createPancakeContext(config);
|
|
@@ -91,16 +88,15 @@ export async function pancakeBundleBuyFirstMultiWallet(params) {
|
|
|
91
88
|
}
|
|
92
89
|
// ✅ 将代币平均分配给卖方
|
|
93
90
|
const sellAmountsWei = splitAmount(actualTokenOut, sellCount);
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (
|
|
91
|
+
// 买合计万三 + 卖合计万三。ERC-20 先把买入合计折成 BNB 再计提,避免 ANTFUN 微额报价为 0
|
|
92
|
+
let profitAmount = 0n;
|
|
93
|
+
if (useNativeToken) {
|
|
94
|
+
profitAmount = calculateBundleSwapRoundTripProfit(totalFundsWei, totalFundsWei);
|
|
95
|
+
}
|
|
96
|
+
else if (quoteToken && totalFundsWei > 0n) {
|
|
100
97
|
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
101
98
|
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
102
|
-
profitAmount = await
|
|
103
|
-
// ERC20→BNB 转换完成
|
|
99
|
+
profitAmount = await quoteRoundTripProfitToNative(context.provider, quoteToken, totalFundsWei, totalFundsWei, 'BSC', version, fee, config.v2RouterAddress);
|
|
104
100
|
}
|
|
105
101
|
// ✅ 第三批并行:构建并签名所有交易
|
|
106
102
|
const allTransactions = [];
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
import { ethers, Wallet } from 'ethers';
|
|
5
5
|
import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
6
6
|
import { NonceManager } from '../../../utils/bundle-helpers.js';
|
|
7
|
-
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS } from '../../../core/constants/index.js';
|
|
8
|
-
import {
|
|
9
|
-
import { buildMultiRouteTransactions, buildProfitTransaction, calculateBuyerFunds, createPancakeContext, getGasPrice,
|
|
7
|
+
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
8
|
+
import { quoteRoundTripProfitToNative } from '../../../core/quote/quote-helpers.js';
|
|
9
|
+
import { buildMultiRouteTransactions, buildProfitTransaction, calculateBuyerFunds, createPancakeContext, getGasPrice, pancakeBundleBuyFirstMultiWallet, planMultiNonces, quoteTokenOutput, splitAmount, validateFinalBalances, validateSwapCounts, } from './bundle-buy-first-helpers.js';
|
|
10
10
|
export async function pancakeBundleBuyFirstMerkle(params) {
|
|
11
11
|
const { buyerPrivateKey, buyerPrivateKeys, sellerPrivateKey, sellerPrivateKeys, routeParams, buyerFunds, buyerFundsPercentage, config, quoteToken, quoteTokenDecimals = 18, buyCount: _buyCount, sellCount: _sellCount, taxRateBps = 0, // ✅ 税率(基点),用于计算实际可卖出代币数量
|
|
12
12
|
} = params;
|
|
@@ -34,9 +34,6 @@ export async function pancakeBundleBuyFirstMerkle(params) {
|
|
|
34
34
|
throw new Error('单钱包模式需要提供 buyerPrivateKey 和 sellerPrivateKey');
|
|
35
35
|
}
|
|
36
36
|
validateSwapCounts(buyCount, sellCount);
|
|
37
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
38
|
-
const totalTxCount = buyCount + sellCount;
|
|
39
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
40
37
|
// ✅ 判断是否使用原生代币(BNB)或 ERC20 代币(如 USDT)
|
|
41
38
|
const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
|
|
42
39
|
const context = createPancakeContext(config);
|
|
@@ -83,17 +80,15 @@ export async function pancakeBundleBuyFirstMerkle(params) {
|
|
|
83
80
|
const gasPrice = await getGasPrice(context.provider, config);
|
|
84
81
|
const txType = config.txType ?? 0;
|
|
85
82
|
const nonceManager = new NonceManager(context.provider);
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!useNativeToken && tokenProfitAmount > 0n && quoteToken) {
|
|
83
|
+
// 买合计万三 + 卖合计万三。ERC-20 先把买入合计折成 BNB 再计提,避免 ANTFUN 微额报价为 0
|
|
84
|
+
let profitAmount = 0n;
|
|
85
|
+
if (useNativeToken) {
|
|
86
|
+
profitAmount = calculateBundleSwapRoundTripProfit(buyerFundsInfo.buyerFundsWei, buyerFundsInfo.buyerFundsWei);
|
|
87
|
+
}
|
|
88
|
+
else if (quoteToken && buyerFundsInfo.buyerFundsWei > 0n) {
|
|
93
89
|
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
94
90
|
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
95
|
-
profitAmount = await
|
|
96
|
-
// ERC20→BNB 转换完成
|
|
91
|
+
profitAmount = await quoteRoundTripProfitToNative(context.provider, quoteToken, buyerFundsInfo.buyerFundsWei, buyerFundsInfo.buyerFundsWei, 'BSC', version, fee, config.v2RouterAddress);
|
|
97
92
|
}
|
|
98
93
|
// ✅ 获取贿赂金额
|
|
99
94
|
const bribeAmount = config.bribeAmount && config.bribeAmount > 0 ? ethers.parseEther(String(config.bribeAmount)) : 0n;
|
|
@@ -5,7 +5,7 @@ export declare function quoteSellOutput({ routeParams, sellAmountWei, provider,
|
|
|
5
5
|
* 根据 userType 计算利润率
|
|
6
6
|
*/
|
|
7
7
|
export declare function getProfitRateBps(_userType?: UserType): number;
|
|
8
|
-
export declare function calculateProfitAmount(estimatedBNBOut: bigint,
|
|
8
|
+
export declare function calculateProfitAmount(estimatedBNBOut: bigint, _userType?: UserType): bigint;
|
|
9
9
|
/**
|
|
10
10
|
* ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
|
|
11
11
|
* 用于将 ERC20 利润转换为 BNB
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ADDRESSES, getProfitRateBps as getSharedProfitRateBps } from '../../../core/constants/index.js';
|
|
1
|
+
import { ADDRESSES, getProfitRateBps as getSharedProfitRateBps, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
2
2
|
import { quoteV2, quoteV3 } from '../../../core/quote/quote-helpers.js';
|
|
3
3
|
import { WBNB_ADDRESS, } from './bundle-swap-types.js';
|
|
4
4
|
export async function quoteSellOutput({ routeParams, sellAmountWei, provider, v2RouterAddress, }) {
|
|
@@ -44,12 +44,11 @@ export async function quoteSellOutput({ routeParams, sellAmountWei, provider, v2
|
|
|
44
44
|
export function getProfitRateBps(_userType) {
|
|
45
45
|
return getSharedProfitRateBps('bundleSwap');
|
|
46
46
|
}
|
|
47
|
-
export function calculateProfitAmount(estimatedBNBOut,
|
|
47
|
+
export function calculateProfitAmount(estimatedBNBOut, _userType) {
|
|
48
48
|
if (estimatedBNBOut <= 0n) {
|
|
49
49
|
return 0n;
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
return (estimatedBNBOut * BigInt(rateBps)) / 10000n;
|
|
51
|
+
return calculateBundleSwapRoundTripProfit(estimatedBNBOut, estimatedBNBOut);
|
|
53
52
|
}
|
|
54
53
|
/**
|
|
55
54
|
* ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { Wallet, JsonRpcProvider } from 'ethers';
|
|
8
8
|
import { ENI_CHAIN_ID, ENI_RPC_URL, DAOAAS_PORTAL, NATIVE_TRANSFER_GAS_LIMIT } from '../../constants.js';
|
|
9
9
|
import { encodeBuyCall, encodeSellCall, applySlippage, DaoaasPortalQuery } from './portal.js';
|
|
10
|
-
import { getProfitRecipient, getProfitRateBps, calculateProfitAmount } from '../../../../core/constants/profit.js';
|
|
10
|
+
import { getProfitRecipient, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, } from '../../../../core/constants/profit.js';
|
|
11
11
|
import { directBuy, directSell, directBatchBuy, directBatchSell } from './portal-direct-tx.js';
|
|
12
12
|
import { buildProfitTransfer } from './portal-direct-profit.js';
|
|
13
13
|
const NORMAL_PROFIT_BPS = getProfitRateBps('normal');
|
|
@@ -301,7 +301,7 @@ export async function directQuickSwapForSubmit(params) {
|
|
|
301
301
|
const hopGasFee = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
302
302
|
const totalFlow = params.buyAmounts.reduce((sum, a) => sum + a, 0n);
|
|
303
303
|
const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
304
|
-
const profitAmount =
|
|
304
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalFlow, totalFlow) + profitTxGasCost;
|
|
305
305
|
const profitGasPerBuyer = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
306
306
|
for (let i = 0; i < params.buyerKeys.length; i++) {
|
|
307
307
|
const buyerAddress = new Wallet(params.buyerKeys[i]).address;
|
|
@@ -366,10 +366,10 @@ export async function directQuickSwapForSubmit(params) {
|
|
|
366
366
|
gasPrice: maxFeePerGas,
|
|
367
367
|
});
|
|
368
368
|
const allTxs = [...sellResult.transactions, ...distributeTxs, ...buyResult.transactions];
|
|
369
|
-
// 4)
|
|
369
|
+
// 4) 利润:买合计万三 + 卖合计万三(金额对齐时万六),与钱包数无关
|
|
370
370
|
const totalFlow = params.buyAmounts.reduce((sum, amount) => sum + amount, 0n);
|
|
371
371
|
const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
372
|
-
const profitAmount =
|
|
372
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalFlow, totalFlow) + profitTxGasCost;
|
|
373
373
|
const payerIndex = pickMaxAmountIndex(params.buyAmounts);
|
|
374
374
|
const payerKey = params.buyerKeys[payerIndex] || primarySellerKey;
|
|
375
375
|
const payerAddress = new Wallet(payerKey).address.toLowerCase();
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 只生成签名,由调用方决定如何提交
|
|
8
8
|
*/
|
|
9
9
|
import { ethers } from 'ethers';
|
|
10
|
-
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync,
|
|
10
|
+
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync, getProfitRecipient, } from './utils.js';
|
|
11
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
11
12
|
import { UNIFIED_DELEGATE_ADDRESS, UNIFIED_DELEGATE_ABI, FLAP_PORTAL_ABI, ERC20_ABI, V3_FEE_TIERS, } from './constants.js';
|
|
12
13
|
import { getDefaultRouter, truncateDecimals, buildBuyCallInternal, buildSellCallWithAmountInternal, } from './bundle-swap-helpers.js';
|
|
13
14
|
/**
|
|
@@ -74,9 +75,8 @@ export async function bundleMultiSwap(params) {
|
|
|
74
75
|
// 计算买入金额
|
|
75
76
|
const totalBuyAmountWei = ethers.parseEther(truncateDecimals(totalBuyAmount));
|
|
76
77
|
const buyAmountPerWallet = totalBuyAmountWei / BigInt(buyerWallets.length);
|
|
77
|
-
//
|
|
78
|
-
const
|
|
79
|
-
const profitAmount = calculateProfitAmountByTxCount(totalBuyAmountWei, totalTxCount, userType);
|
|
78
|
+
// 买合计万三 + 卖合计万三(金额对齐时万六),与钱包数无关
|
|
79
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalBuyAmountWei, totalBuyAmountWei);
|
|
80
80
|
const profitRecipient = getProfitRecipient(config);
|
|
81
81
|
// ========================================
|
|
82
82
|
// 并行获取数据
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import type { EIP7702Config } from './types.js';
|
|
2
2
|
export type UserType = 'v0' | 'v1' | 'default';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* - v0: 8 bps
|
|
6
|
-
* - v1: 10 bps
|
|
7
|
-
*
|
|
4
|
+
* 根据用户类型获取利润率(单边:发币/买卖/捆绑购买)
|
|
5
|
+
* - v0 / default: 8 bps
|
|
6
|
+
* - v1: 10 bps
|
|
7
|
+
* 刷量/换手不要走这里,用 calculateBundleSwapRoundTripProfit
|
|
8
8
|
*/
|
|
9
|
-
export declare function getProfitRateBps(
|
|
9
|
+
export declare function getProfitRateBps(userType?: UserType): number;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* 双边/换手单腿(仅兼容旧调用)。新换手路径用 round-trip 万六。
|
|
12
12
|
*/
|
|
13
13
|
export declare function getProfitRateBpsDouble(_userType?: UserType): number;
|
|
14
14
|
/**
|
|
15
15
|
* 计算利润金额(旧版兼容)
|
|
16
16
|
*/
|
|
17
17
|
export declare function calculateProfitAmount(totalFlowWei: bigint, isSwapMode?: boolean): bigint;
|
|
18
|
-
/**
|
|
19
|
-
* 计算利润金额(基于用户类型)
|
|
20
|
-
* @param totalFlowWei 总资金流水
|
|
21
|
-
* @param userType 用户类型
|
|
22
|
-
* @param isDoubleMode 是否双边模式(换手模式)
|
|
23
|
-
*/
|
|
24
18
|
export declare function calculateProfitAmountByUserType(totalFlowWei: bigint, userType?: UserType, isDoubleMode?: boolean): bigint;
|
|
25
19
|
/**
|
|
26
20
|
* 根据交易数量计算利润金额
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { getProfitRateBps as getSharedProfitRateBps, getProfitRecipient as pickRandomProfitRecipient, } from '../../../core/constants/index.js';
|
|
1
|
+
import { getProfitRateBps as getSharedProfitRateBps, getProfitRecipient as pickRandomProfitRecipient, calculateBundleSwapRoundTripProfit, } from '../../../core/constants/index.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* - v0: 8 bps
|
|
5
|
-
* - v1: 10 bps
|
|
6
|
-
*
|
|
3
|
+
* 根据用户类型获取利润率(单边:发币/买卖/捆绑购买)
|
|
4
|
+
* - v0 / default: 8 bps
|
|
5
|
+
* - v1: 10 bps
|
|
6
|
+
* 刷量/换手不要走这里,用 calculateBundleSwapRoundTripProfit
|
|
7
7
|
*/
|
|
8
|
-
export function getProfitRateBps(
|
|
9
|
-
|
|
8
|
+
export function getProfitRateBps(userType) {
|
|
9
|
+
if (userType === 'v1')
|
|
10
|
+
return getSharedProfitRateBps('v1Single');
|
|
11
|
+
return getSharedProfitRateBps('v0Single');
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
|
-
*
|
|
14
|
+
* 双边/换手单腿(仅兼容旧调用)。新换手路径用 round-trip 万六。
|
|
13
15
|
*/
|
|
14
16
|
export function getProfitRateBpsDouble(_userType) {
|
|
15
17
|
return getSharedProfitRateBps('bundleSwap');
|
|
@@ -19,19 +21,16 @@ export function getProfitRateBpsDouble(_userType) {
|
|
|
19
21
|
*/
|
|
20
22
|
export function calculateProfitAmount(totalFlowWei, isSwapMode = false) {
|
|
21
23
|
const rateBps = getSharedProfitRateBps(isSwapMode ? 'bundleSwap' : 'normal');
|
|
24
|
+
if (isSwapMode)
|
|
25
|
+
return calculateBundleSwapRoundTripProfit(totalFlowWei, totalFlowWei);
|
|
22
26
|
return (totalFlowWei * BigInt(rateBps)) / 10000n;
|
|
23
27
|
}
|
|
24
|
-
/**
|
|
25
|
-
* 计算利润金额(基于用户类型)
|
|
26
|
-
* @param totalFlowWei 总资金流水
|
|
27
|
-
* @param userType 用户类型
|
|
28
|
-
* @param isDoubleMode 是否双边模式(换手模式)
|
|
29
|
-
*/
|
|
30
28
|
export function calculateProfitAmountByUserType(totalFlowWei, userType, isDoubleMode = false) {
|
|
31
29
|
if (totalFlowWei <= 0n)
|
|
32
30
|
return 0n;
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
if (isDoubleMode)
|
|
32
|
+
return calculateBundleSwapRoundTripProfit(totalFlowWei, totalFlowWei);
|
|
33
|
+
return (totalFlowWei * BigInt(getProfitRateBps(userType))) / 10000n;
|
|
35
34
|
}
|
|
36
35
|
/**
|
|
37
36
|
* 根据交易数量计算利润金额
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { ethers } from 'ethers';
|
|
8
8
|
import { truncateDecimals } from './volume-helpers.js';
|
|
9
|
-
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync,
|
|
9
|
+
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync, getProfitRecipient, } from './utils.js';
|
|
10
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
10
11
|
import { UNIFIED_DELEGATE_ADDRESS, UNIFIED_DELEGATE_ABI, FLAP_PORTAL_ABI, FLAP_PORTAL_ADDRESS, POTATOSWAP_V2_ROUTER, WOKB_ADDRESS, V3_FEE_TIERS, ERC20_ABI, V2_ROUTER_ABI, } from './constants.js';
|
|
11
12
|
import { getDefaultRouter, buildBuyCall, buildSellCall, buildSellCallWithAmount } from './volume-internal.js';
|
|
12
13
|
/**
|
|
@@ -15,7 +16,7 @@ import { getDefaultRouter, buildBuyCall, buildSellCall, buildSellCallWithAmount
|
|
|
15
16
|
* 核心逻辑:[利润刮取] + [买入Ops...] + [卖出Ops...]
|
|
16
17
|
*/
|
|
17
18
|
export async function bundleVolume(params) {
|
|
18
|
-
const { mainPrivateKey, buyerPrivateKeys, buyAmounts, sellerPrivateKeys, sellAmounts, sellPercent = 100, tokenAddress, tokenDecimals = 18, poolType = 'V3', routerAddress, fee = V3_FEE_TIERS.MEDIUM, userType = 'v0', //
|
|
19
|
+
const { mainPrivateKey, buyerPrivateKeys, buyAmounts, sellerPrivateKeys, sellAmounts, sellPercent = 100, tokenAddress, tokenDecimals = 18, poolType = 'V3', routerAddress, fee = V3_FEE_TIERS.MEDIUM, userType: _userType = 'v0', // 档位已统一为 bundleSwap 两腿万六
|
|
19
20
|
config, } = params;
|
|
20
21
|
// ✅ 验证私钥格式的辅助函数
|
|
21
22
|
const isValidPrivateKey = (pk) => {
|
|
@@ -66,9 +67,8 @@ export async function bundleVolume(params) {
|
|
|
66
67
|
// 计算买入金额(使用验证后的金额数组)
|
|
67
68
|
const buyAmountsWei = validBuyAmounts.map((amt) => ethers.parseEther(truncateDecimals(amt)));
|
|
68
69
|
const totalBuyAmount = buyAmountsWei.reduce((sum, amt) => sum + amt, 0n);
|
|
69
|
-
//
|
|
70
|
-
const
|
|
71
|
-
const profitAmount = calculateProfitAmountByTxCount(totalBuyAmount, totalTxCount, userType);
|
|
70
|
+
// 买合计万三 + 卖合计万三(买卖总额对齐时为万六),与钱包数无关
|
|
71
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalBuyAmount, totalBuyAmount);
|
|
72
72
|
const profitRecipient = getProfitRecipient(config);
|
|
73
73
|
// ========================================
|
|
74
74
|
// 并行获取数据
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { ethers, Contract } from 'ethers';
|
|
8
8
|
import { truncateDecimals } from './volume-helpers.js';
|
|
9
|
-
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync,
|
|
9
|
+
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync, getProfitRecipient, } from './utils.js';
|
|
10
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
10
11
|
import { UNIFIED_DELEGATE_ADDRESS, UNIFIED_DELEGATE_ABI, FLAP_PORTAL_ABI, FLAP_PORTAL_ADDRESS, WOKB_ADDRESS, V3_FEE_TIERS, } from './constants.js';
|
|
11
12
|
import { quoteV2, quoteV3 } from '../../../core/quote/quote-helpers.js';
|
|
12
13
|
import { getDefaultRouter, buildBuyCall, buildSellCall, buildSellCallWithAmount } from './volume-internal.js';
|
|
13
14
|
export async function washVolume(params) {
|
|
14
|
-
const { mainPrivateKey, privateKeys, tokenAddress, tokenDecimals = 18, buyAmountPerWallet, sellPercent = 100, poolType = 'V3', routerAddress, fee = V3_FEE_TIERS.MEDIUM, userType = 'v0', //
|
|
15
|
+
const { mainPrivateKey, privateKeys, tokenAddress, tokenDecimals = 18, buyAmountPerWallet, sellPercent = 100, poolType = 'V3', routerAddress, fee = V3_FEE_TIERS.MEDIUM, userType: _userType = 'v0', // 档位已统一为 bundleSwap 两腿万六
|
|
15
16
|
config, } = params;
|
|
16
17
|
if (!mainPrivateKey) {
|
|
17
18
|
throw new Error('必须提供 mainPrivateKey(Payer 钱包私钥)');
|
|
@@ -46,8 +47,7 @@ export async function washVolume(params) {
|
|
|
46
47
|
// 计算金额(无币刷量:每个钱包 1买 + 1卖 = 2笔交易)
|
|
47
48
|
const buyAmountWei = ethers.parseEther(truncateDecimals(buyAmountPerWallet));
|
|
48
49
|
const totalBuyAmount = buyAmountWei * BigInt(wallets.length);
|
|
49
|
-
const
|
|
50
|
-
const profitAmount = calculateProfitAmountByTxCount(totalBuyAmount, totalTxCount, userType);
|
|
50
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalBuyAmount, totalBuyAmount);
|
|
51
51
|
const profitRecipient = getProfitRecipient(config);
|
|
52
52
|
// ========================================
|
|
53
53
|
// 合并所有钱包(去重)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JsonRpcProvider } from 'ethers';
|
|
2
2
|
import { type RouteParams, type UserType } from './eoa-bundle-swap-types.js';
|
|
3
3
|
export declare function getProfitRateBps(_userType?: UserType): number;
|
|
4
|
-
export declare function calculateProfitAmount(estimatedOutput: bigint,
|
|
4
|
+
export declare function calculateProfitAmount(estimatedOutput: bigint, _userType?: UserType): bigint;
|
|
5
5
|
export declare function quoteSellOutput(provider: JsonRpcProvider, routeParams: RouteParams, sellAmountWei: bigint): Promise<bigint>;
|
|
6
6
|
export declare function getERC20ToOkbQuote(provider: JsonRpcProvider, tokenAddress: string, tokenAmount: bigint, version?: 'v2' | 'v3', fee?: number): Promise<bigint>;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { CHAINS, getProfitRateBps as getSharedProfitRateBps } from '../../../core/constants/index.js';
|
|
1
|
+
import { CHAINS, getProfitRateBps as getSharedProfitRateBps, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
2
2
|
import { quoteV2, quoteV3 } from '../../../core/quote/quote-helpers.js';
|
|
3
3
|
import { WOKB_ADDRESS, } from './eoa-bundle-swap-types.js';
|
|
4
4
|
const XLAYER_CHAIN_NAME = CHAINS.XLAYER.name;
|
|
5
5
|
export function getProfitRateBps(_userType) {
|
|
6
6
|
return getSharedProfitRateBps('bundleSwap');
|
|
7
7
|
}
|
|
8
|
-
export function calculateProfitAmount(estimatedOutput,
|
|
8
|
+
export function calculateProfitAmount(estimatedOutput, _userType) {
|
|
9
9
|
if (estimatedOutput <= 0n)
|
|
10
10
|
return 0n;
|
|
11
|
-
|
|
12
|
-
return (estimatedOutput * BigInt(rateBps)) / 10000n;
|
|
11
|
+
return calculateBundleSwapRoundTripProfit(estimatedOutput, estimatedOutput);
|
|
13
12
|
}
|
|
14
13
|
// ==================== 报价函数 ====================
|
|
15
14
|
export async function quoteSellOutput(provider, routeParams, sellAmountWei) {
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, getConfirmationTimeout, type ChainKey, type ChainConfig, } from './chains.js';
|
|
12
12
|
export { GAS_LIMITS, GAS_CONFIG, V3_FEE_TIERS, calculateGasLimit, getTransferGasLimit, type GasLimitKey, type V3FeeTier, } from './gas.js';
|
|
13
|
-
export { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, type QuoteConfigChain } from './quote.js';
|
|
13
|
+
export { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, getQuoteChainKey, type QuoteConfigChain } from './quote.js';
|
|
14
14
|
/** Flap 链标识(与 `FlapPortal` 一致,供子路径 `./constants` 使用) */
|
|
15
15
|
export type { FlapChain } from '../../domains/flap/portal.js';
|
|
16
16
|
export { ZERO_ADDRESS, ZERO_BYTES32, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders, type ChainAddresses, type AddressKey, } from './addresses.js';
|
|
17
|
-
export { PROFIT_CONFIG, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateProfitHopGasCost, type ProfitRateKey, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, } from './profit.js';
|
|
17
|
+
export { PROFIT_CONFIG, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, type ProfitRateKey, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, } from './profit.js';
|
|
@@ -16,7 +16,7 @@ export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isK
|
|
|
16
16
|
// Gas 常量
|
|
17
17
|
// ============================================================================
|
|
18
18
|
export { GAS_LIMITS, GAS_CONFIG, V3_FEE_TIERS, calculateGasLimit, getTransferGasLimit, } from './gas.js';
|
|
19
|
-
export { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS } from './quote.js';
|
|
19
|
+
export { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, getQuoteChainKey } from './quote.js';
|
|
20
20
|
// ============================================================================
|
|
21
21
|
// 合约地址
|
|
22
22
|
// ============================================================================
|
|
@@ -24,6 +24,6 @@ export { ZERO_ADDRESS, ZERO_BYTES32, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddre
|
|
|
24
24
|
// ============================================================================
|
|
25
25
|
// 利润配置
|
|
26
26
|
// ============================================================================
|
|
27
|
-
export { PROFIT_CONFIG, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateProfitHopGasCost,
|
|
27
|
+
export { PROFIT_CONFIG, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost,
|
|
28
28
|
// ✅ 钱包转账按地址收费
|
|
29
29
|
TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, } from './profit.js';
|
|
@@ -11,7 +11,7 @@ export declare const PROFIT_CONFIG: {
|
|
|
11
11
|
RATES: {
|
|
12
12
|
/** 普通模式:30 bps = 0.3%(代币交易 / 拉盘砸盘) */
|
|
13
13
|
NORMAL: number;
|
|
14
|
-
/** 捆绑换手 /
|
|
14
|
+
/** 捆绑换手 / 刷量单腿:3 bps = 0.03%;买合计 + 卖合计 = 万六 */
|
|
15
15
|
BUNDLE_SWAP: number;
|
|
16
16
|
/** V0 用户单边:8 bps = 0.08% */
|
|
17
17
|
V0_SINGLE: number;
|
|
@@ -50,6 +50,11 @@ export declare function getProfitRateBps(mode: 'normal' | 'bundleSwap' | 'v0Sing
|
|
|
50
50
|
* @param rateBps 利润比例(基点)
|
|
51
51
|
*/
|
|
52
52
|
export declare function calculateProfitAmount(amount: bigint, rateBps: number): bigint;
|
|
53
|
+
/**
|
|
54
|
+
* 刷量 / 换手:买的合计收万三,卖的合计(同计价)再收万三。
|
|
55
|
+
* 与钱包数量无关;两腿金额接近时合计万六。
|
|
56
|
+
*/
|
|
57
|
+
export declare function calculateBundleSwapRoundTripProfit(buyQuoteWei: bigint, sellQuoteWei: bigint): bigint;
|
|
53
58
|
/**
|
|
54
59
|
* 计算利润多跳所需的 Gas 费用
|
|
55
60
|
* @param gasPrice Gas 价格
|
|
@@ -23,7 +23,7 @@ export const PROFIT_CONFIG = {
|
|
|
23
23
|
RATES: {
|
|
24
24
|
/** 普通模式:30 bps = 0.3%(代币交易 / 拉盘砸盘) */
|
|
25
25
|
NORMAL: 30,
|
|
26
|
-
/** 捆绑换手 /
|
|
26
|
+
/** 捆绑换手 / 刷量单腿:3 bps = 0.03%;买合计 + 卖合计 = 万六 */
|
|
27
27
|
BUNDLE_SWAP: 3,
|
|
28
28
|
/** V0 用户单边:8 bps = 0.08% */
|
|
29
29
|
V0_SINGLE: 8,
|
|
@@ -88,6 +88,16 @@ export function getProfitRateBps(mode) {
|
|
|
88
88
|
export function calculateProfitAmount(amount, rateBps) {
|
|
89
89
|
return (amount * BigInt(rateBps)) / 10000n;
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* 刷量 / 换手:买的合计收万三,卖的合计(同计价)再收万三。
|
|
93
|
+
* 与钱包数量无关;两腿金额接近时合计万六。
|
|
94
|
+
*/
|
|
95
|
+
export function calculateBundleSwapRoundTripProfit(buyQuoteWei, sellQuoteWei) {
|
|
96
|
+
const rate = getProfitRateBps('bundleSwap');
|
|
97
|
+
const buy = buyQuoteWei > 0n ? buyQuoteWei : 0n;
|
|
98
|
+
const sell = sellQuoteWei > 0n ? sellQuoteWei : 0n;
|
|
99
|
+
return calculateProfitAmount(buy, rate) + calculateProfitAmount(sell, rate);
|
|
100
|
+
}
|
|
91
101
|
/**
|
|
92
102
|
* 计算利润多跳所需的 Gas 费用
|
|
93
103
|
* @param gasPrice Gas 价格
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { calculateBundleSwapRoundTripProfit, calculateProfitAmount, getProfitRateBps, } from './profit.js';
|
|
3
|
+
describe('bundle swap round-trip profit', () => {
|
|
4
|
+
it('charges 3 bps on buy sum and 3 bps on sell sum, not per wallet', () => {
|
|
5
|
+
const buy = 1000000n;
|
|
6
|
+
const sell = 1000000n;
|
|
7
|
+
expect(getProfitRateBps('bundleSwap')).toBe(3);
|
|
8
|
+
expect(calculateBundleSwapRoundTripProfit(buy, sell)).toBe(600n);
|
|
9
|
+
expect(calculateBundleSwapRoundTripProfit(buy, sell)).toBe(calculateProfitAmount(buy, 3) + calculateProfitAmount(sell, 3));
|
|
10
|
+
});
|
|
11
|
+
it('uses actual buy/sell totals when they differ', () => {
|
|
12
|
+
expect(calculateBundleSwapRoundTripProfit(1000000n, 500000n)).toBe(300n + 150n);
|
|
13
|
+
});
|
|
14
|
+
it('ignores non-positive legs', () => {
|
|
15
|
+
expect(calculateBundleSwapRoundTripProfit(1000000n, 0n)).toBe(300n);
|
|
16
|
+
expect(calculateBundleSwapRoundTripProfit(0n, 1000000n)).toBe(300n);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -28,3 +28,5 @@ export declare const QUOTE_CONFIG: {
|
|
|
28
28
|
/** V3 报价尝试费率列表(与 `gas.V3_FEE_TIERS` 命名对象区分) */
|
|
29
29
|
export declare const QUOTE_V3_FEE_TIERS: readonly [100, 500, 2500, 10000];
|
|
30
30
|
export type QuoteConfigChain = keyof typeof QUOTE_CONFIG;
|
|
31
|
+
/** chainId → QUOTE_CONFIG 键;Flap 旧接口传数字 chainId,不能直接当 'BSC' 用 */
|
|
32
|
+
export declare function getQuoteChainKey(chainId: number): QuoteConfigChain | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CHAINS } from './chains.js';
|
|
1
2
|
/** DEX 报价链配置(V2 Router / V3 Quoter / 包装原生币 / 稳定币) */
|
|
2
3
|
export const QUOTE_CONFIG = {
|
|
3
4
|
BSC: {
|
|
@@ -35,3 +36,15 @@ export const QUOTE_CONFIG = {
|
|
|
35
36
|
};
|
|
36
37
|
/** V3 报价尝试费率列表(与 `gas.V3_FEE_TIERS` 命名对象区分) */
|
|
37
38
|
export const QUOTE_V3_FEE_TIERS = [100, 500, 2500, 10000];
|
|
39
|
+
/** chainId → QUOTE_CONFIG 键;Flap 旧接口传数字 chainId,不能直接当 'BSC' 用 */
|
|
40
|
+
export function getQuoteChainKey(chainId) {
|
|
41
|
+
if (chainId === CHAINS.BSC.chainId)
|
|
42
|
+
return 'BSC';
|
|
43
|
+
if (chainId === CHAINS.MONAD.chainId)
|
|
44
|
+
return 'MONAD';
|
|
45
|
+
if (chainId === CHAINS.XLAYER.chainId)
|
|
46
|
+
return 'XLAYER';
|
|
47
|
+
if (chainId === CHAINS.ENI.chainId)
|
|
48
|
+
return 'ENI';
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
@@ -55,6 +55,17 @@ export declare function quote(params: QuoteParams): Promise<QuoteResult>;
|
|
|
55
55
|
* @returns 等值的原生代币数量(wei),失败返回 0n
|
|
56
56
|
*/
|
|
57
57
|
export declare function getTokenToNativeQuote(provider: JsonRpcProvider, tokenAddress: string, tokenAmount: bigint, chain: string, version?: 'v2' | 'v3', fee?: number, routerOverride?: string): Promise<bigint>;
|
|
58
|
+
/**
|
|
59
|
+
* Flap 等旧接口传 chainId 数字;转成 QUOTE_CONFIG 键后再走多跳报价。
|
|
60
|
+
* ANTFUN 往往没有 ANTFUN→WBNB 直连池,只走直连会报 0,刷量看起来没收万六。
|
|
61
|
+
*/
|
|
62
|
+
export declare function getTokenToNativeQuoteByChainId(provider: JsonRpcProvider, tokenAddress: string, tokenAmount: bigint, chainId: number): Promise<bigint>;
|
|
63
|
+
/**
|
|
64
|
+
* 刷量/换手 ERC-20 计价:先把买/卖合计折成原生币,再各收万三。
|
|
65
|
+
* 不要先抽 6bps 计价币再报价,ANTFUN 等微额路径会报 0,看起来没收万六。
|
|
66
|
+
*/
|
|
67
|
+
export declare function quoteRoundTripProfitToNative(provider: JsonRpcProvider, quoteToken: string, buyQuoteWei: bigint, sellQuoteWei: bigint, chain: string, version?: 'v2' | 'v3', fee?: number, routerOverride?: string): Promise<bigint>;
|
|
68
|
+
export declare function quoteRoundTripProfitToNativeByChainId(provider: JsonRpcProvider, quoteToken: string, buyQuoteWei: bigint, sellQuoteWei: bigint, chainId: number): Promise<bigint>;
|
|
58
69
|
/**
|
|
59
70
|
* 获取原生代币 → ERC20 代币的报价
|
|
60
71
|
*
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Contract } from 'ethers';
|
|
10
10
|
import { V2_ROUTER_QUOTE_ABI, V3_QUOTER_ABI } from '../../abis/common.js';
|
|
11
|
-
import {
|
|
11
|
+
import { calculateBundleSwapRoundTripProfit } from '../constants/profit.js';
|
|
12
|
+
import { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, getQuoteChainKey } from '../constants/quote.js';
|
|
12
13
|
const V2_ROUTER_ABI = V2_ROUTER_QUOTE_ABI;
|
|
13
14
|
export { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS };
|
|
14
15
|
/**
|
|
@@ -232,6 +233,46 @@ export async function getTokenToNativeQuote(provider, tokenAddress, tokenAmount,
|
|
|
232
233
|
});
|
|
233
234
|
return result.amountOut;
|
|
234
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Flap 等旧接口传 chainId 数字;转成 QUOTE_CONFIG 键后再走多跳报价。
|
|
238
|
+
* ANTFUN 往往没有 ANTFUN→WBNB 直连池,只走直连会报 0,刷量看起来没收万六。
|
|
239
|
+
*/
|
|
240
|
+
export async function getTokenToNativeQuoteByChainId(provider, tokenAddress, tokenAmount, chainId) {
|
|
241
|
+
const chain = getQuoteChainKey(chainId);
|
|
242
|
+
if (!chain)
|
|
243
|
+
return 0n;
|
|
244
|
+
try {
|
|
245
|
+
return await getTokenToNativeQuote(provider, tokenAddress, tokenAmount, chain);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return 0n;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 刷量/换手 ERC-20 计价:先把买/卖合计折成原生币,再各收万三。
|
|
253
|
+
* 不要先抽 6bps 计价币再报价,ANTFUN 等微额路径会报 0,看起来没收万六。
|
|
254
|
+
*/
|
|
255
|
+
export async function quoteRoundTripProfitToNative(provider, quoteToken, buyQuoteWei, sellQuoteWei, chain, version = 'v2', fee, routerOverride) {
|
|
256
|
+
const quoteLeg = async (amount) => {
|
|
257
|
+
if (amount <= 0n)
|
|
258
|
+
return 0n;
|
|
259
|
+
return getTokenToNativeQuote(provider, quoteToken, amount, chain, version, fee, routerOverride);
|
|
260
|
+
};
|
|
261
|
+
const buyNative = await quoteLeg(buyQuoteWei);
|
|
262
|
+
const sellNative = sellQuoteWei === buyQuoteWei ? buyNative : await quoteLeg(sellQuoteWei);
|
|
263
|
+
const profit = calculateBundleSwapRoundTripProfit(buyNative, sellNative);
|
|
264
|
+
if (profit <= 0n && (buyQuoteWei > 0n || sellQuoteWei > 0n)) {
|
|
265
|
+
throw new Error('计价币利润折成原生币报价为 0,请检查计价币流动性后重试');
|
|
266
|
+
}
|
|
267
|
+
return profit;
|
|
268
|
+
}
|
|
269
|
+
export async function quoteRoundTripProfitToNativeByChainId(provider, quoteToken, buyQuoteWei, sellQuoteWei, chainId) {
|
|
270
|
+
const chain = getQuoteChainKey(chainId);
|
|
271
|
+
if (!chain) {
|
|
272
|
+
throw new Error('当前链不支持把计价币利润折成原生币');
|
|
273
|
+
}
|
|
274
|
+
return quoteRoundTripProfitToNative(provider, quoteToken, buyQuoteWei, sellQuoteWei, chain);
|
|
275
|
+
}
|
|
235
276
|
/**
|
|
236
277
|
* 获取原生代币 → ERC20 代币的报价
|
|
237
278
|
*
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ethers, Contract, Wallet, Interface, } from 'ethers';
|
|
2
|
-
import { ADDRESSES,
|
|
2
|
+
import { ADDRESSES, } from '../../../core/constants/index.js';
|
|
3
3
|
import { MULTICALL3_ABI, V2_ROUTER_QUOTE_ABI, } from '../../../core/shared-abis/common.js';
|
|
4
4
|
import { getGasLimit, } from '../../../core/gas/bundle-gas.js';
|
|
5
5
|
import { getOptimizedGasPrice, } from '../../../utils/bundle-helpers.js';
|
|
6
|
+
import { getTokenToNativeQuoteByChainId } from '../../../core/quote/quote-helpers.js';
|
|
6
7
|
import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, calculateProfit, getProfitRecipient, } from './config.js';
|
|
7
8
|
import { normalizeTaxLaunchConfig, } from '../portal-create-token.js';
|
|
8
9
|
import { MigratorType } from '../portal.js';
|
|
@@ -30,40 +31,7 @@ export const ROUTER_ABI = V2_ROUTER_QUOTE_ABI;
|
|
|
30
31
|
* @returns 等值的原生代币数量(wei),失败返回 0n
|
|
31
32
|
*/
|
|
32
33
|
export async function getTokenToNativeQuote(provider, tokenAddress, tokenAmount, chainId) {
|
|
33
|
-
|
|
34
|
-
return 0n;
|
|
35
|
-
try {
|
|
36
|
-
if (chainId === CHAINS.BSC.chainId) {
|
|
37
|
-
// BSC: 使用 PancakeSwap V2 Router
|
|
38
|
-
const router = new Contract(BSC_PANCAKE_V2_ROUTER, ROUTER_ABI, provider);
|
|
39
|
-
const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, BSC_WBNB]);
|
|
40
|
-
return amounts[1];
|
|
41
|
-
}
|
|
42
|
-
if (chainId === CHAINS.MONAD.chainId) {
|
|
43
|
-
// ✅ Monad: 使用 PancakeSwap V2 Router
|
|
44
|
-
const router = new Contract(MONAD_PANCAKE_V2_ROUTER, ROUTER_ABI, provider);
|
|
45
|
-
const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, MONAD_WMON]);
|
|
46
|
-
return amounts[1];
|
|
47
|
-
}
|
|
48
|
-
if (chainId === CHAINS.XLAYER.chainId) {
|
|
49
|
-
// ✅ XLAYER: 使用 PotatoSwap V2 Router(USDT0 → WOKB)
|
|
50
|
-
const router = new Contract(XLAYER_POTATOSWAP_V2_ROUTER, ROUTER_ABI, provider);
|
|
51
|
-
const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, XLAYER_WOKB]);
|
|
52
|
-
return amounts[1];
|
|
53
|
-
}
|
|
54
|
-
if (chainId === CHAINS.BASE.chainId) {
|
|
55
|
-
// ✅ Base: 目前大部分 Flap 交易使用 ETH(原生代币),ERC20 报价暂不支持
|
|
56
|
-
// Base 主力 DEX 是 Uniswap V3,V2 Router 流动性有限,暂返回 0
|
|
57
|
-
// TODO: 后续可接入 Uniswap V3 QuoterV2 进行精确报价
|
|
58
|
-
return 0n;
|
|
59
|
-
}
|
|
60
|
-
// 其他链暂不支持报价,返回 0
|
|
61
|
-
return 0n;
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
// 报价失败返回 0(可能是流动性不足或路径不存在)
|
|
65
|
-
return 0n;
|
|
66
|
-
}
|
|
34
|
+
return getTokenToNativeQuoteByChainId(provider, tokenAddress, tokenAmount, chainId);
|
|
67
35
|
}
|
|
68
36
|
// ==================== 内部辅助函数(从 core.ts 抽取)====================
|
|
69
37
|
export function validateQuoteTokenDecimals(decimals, source) {
|
|
@@ -6,9 +6,10 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
6
6
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
7
7
|
import { NonceManager, getOptimizedGasPrice } from '../../../utils/bundle-helpers.js';
|
|
8
8
|
import { ZERO_ADDRESS } from '../../../core/constants/index.js';
|
|
9
|
+
import { quoteRoundTripProfitToNativeByChainId } from '../../../core/quote/quote-helpers.js';
|
|
9
10
|
import { getGasPriceConfig, getTxType, getBribeAmount, BLOCKRAZOR_BUILDER_EOA, PORTAL_ABI, } from './config.js';
|
|
10
11
|
import { buildTransactionRequest } from '../../../core/tx/build-request.js';
|
|
11
|
-
import { BRIBE_GAS_LIMIT, ERC20_BALANCE_OF_ABI,
|
|
12
|
+
import { BRIBE_GAS_LIMIT, ERC20_BALANCE_OF_ABI, } from './swap-helpers.js';
|
|
12
13
|
import { buildApprovalTransaction, buildProfitTransaction, calculateProfitAmount, createChainContext, quoteSellOutput, } from './swap-planning.js';
|
|
13
14
|
/**
|
|
14
15
|
* Flap 内盘批量换手(一卖多买)
|
|
@@ -99,11 +100,13 @@ export async function flapBatchSwapMerkle(params) {
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
}));
|
|
102
|
-
// ✅
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
// ✅ 计算利润。ERC-20 先把卖出合计折成原生币再计提万六,避免 ANTFUN 微额报价为 0
|
|
104
|
+
let nativeProfitAmount = 0n;
|
|
105
|
+
if (useNativeToken) {
|
|
106
|
+
nativeProfitAmount = calculateProfitAmount(quote.quotedNative, config.userType);
|
|
107
|
+
}
|
|
108
|
+
else if (quote.quotedNative > 0n && quoteToken) {
|
|
109
|
+
nativeProfitAmount = await quoteRoundTripProfitToNativeByChainId(chainContext.provider, quoteToken, quote.quotedNative, quote.quotedNative, chainContext.chainId);
|
|
107
110
|
}
|
|
108
111
|
// ✅ 并行构建所有买入交易
|
|
109
112
|
const portalSeller = new Contract(chainContext.portalAddress, PORTAL_ABI, seller);
|
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
5
|
import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
6
6
|
import { NonceManager, getOptimizedGasPrice } from '../../../utils/bundle-helpers.js';
|
|
7
|
-
import { ZERO_ADDRESS, GAS_LIMITS } from '../../../core/constants/index.js';
|
|
7
|
+
import { ZERO_ADDRESS, GAS_LIMITS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
8
|
+
import { quoteRoundTripProfitToNativeByChainId } from '../../../core/quote/quote-helpers.js';
|
|
8
9
|
import { ERC20_BALANCE_ABI } from '../../../core/shared-abis/common.js';
|
|
9
10
|
import { BLOCKRAZOR_BUILDER_EOA, PORTAL_ABI, getBribeAmount, getGasPriceConfig, getTxType, } from './config.js';
|
|
10
11
|
import { buildTransactionRequest } from '../../../core/tx/build-request.js';
|
|
11
12
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
12
13
|
import { createChainContext } from './swap-buy-first-chain.js';
|
|
13
|
-
import { quoteBuyerOutput, estimateSellFunds
|
|
14
|
-
import {
|
|
14
|
+
import { quoteBuyerOutput, estimateSellFunds } from './swap-buy-first-quote.js';
|
|
15
|
+
import { validateSwapCounts } from './swap-buy-first-plan.js';
|
|
15
16
|
import { buildProfitTransaction } from './swap-buy-first-profit.js';
|
|
16
17
|
/**
|
|
17
18
|
* ✅ Flap 多钱包捆绑换手
|
|
@@ -30,9 +31,6 @@ export async function flapBundleBuyFirstMultiWallet(params) {
|
|
|
30
31
|
throw new Error('卖方钱包数量不能为0');
|
|
31
32
|
// 验证总交易数不超过限制
|
|
32
33
|
validateSwapCounts(buyCount, sellCount);
|
|
33
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
34
|
-
const totalTxCount = buyCount + sellCount;
|
|
35
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
36
34
|
const chainContext = createChainContext(chain, config.rpcUrl);
|
|
37
35
|
const nonceManager = new NonceManager(chainContext.provider);
|
|
38
36
|
// 创建所有钱包实例
|
|
@@ -93,12 +91,12 @@ export async function flapBundleBuyFirstMultiWallet(params) {
|
|
|
93
91
|
// ✅ 第二批并行:估算利润 + ERC20 转原生代币报价(如需要)
|
|
94
92
|
const portal = new Contract(chainContext.portalAddress, PORTAL_ABI, chainContext.provider);
|
|
95
93
|
const estimatedSellFunds = await estimateSellFunds(portal, tokenAddress, quoteResult.sellAmountWei, outputToken);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
nativeProfitAmount = await
|
|
94
|
+
let nativeProfitAmount = 0n;
|
|
95
|
+
if (useNativeToken) {
|
|
96
|
+
nativeProfitAmount = calculateBundleSwapRoundTripProfit(totalFundsWei, estimatedSellFunds > 0n ? estimatedSellFunds : totalFundsWei);
|
|
97
|
+
}
|
|
98
|
+
else if (totalFundsWei > 0n) {
|
|
99
|
+
nativeProfitAmount = await quoteRoundTripProfitToNativeByChainId(chainContext.provider, inputToken, totalFundsWei, totalFundsWei, chainContext.chainId);
|
|
102
100
|
}
|
|
103
101
|
// ✅ 第三批并行:构建并签名所有交易
|
|
104
102
|
const allTransactions = [];
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Flap BuyFirst 报价/资金/余额 helper(从 swap-buy-first-helpers.ts 抽取)
|
|
3
3
|
*/
|
|
4
4
|
import { ethers, Contract } from 'ethers';
|
|
5
|
-
import {
|
|
5
|
+
import { ZERO_ADDRESS } from '../../../core/constants/index.js';
|
|
6
6
|
import { ERC20_BALANCE_ABI } from '../../../core/shared-abis/common.js';
|
|
7
7
|
import { getErrorMessageFromUnknown } from '../../../core/index.js';
|
|
8
8
|
import { PORTAL_ABI } from './config.js';
|
|
9
|
-
import {
|
|
9
|
+
import { getTokenToNativeQuoteByChainId } from '../../../core/quote/quote-helpers.js';
|
|
10
10
|
/**
|
|
11
11
|
* 获取 ERC20 代币 → 原生代币的报价
|
|
12
12
|
* @param provider - Provider 实例
|
|
@@ -16,28 +16,7 @@ import { BSC_PANCAKE_V2_ROUTER, BSC_WBNB, MONAD_PANCAKE_V2_ROUTER, MONAD_WMON, R
|
|
|
16
16
|
* @returns 等值的原生代币数量(wei),失败返回 0n
|
|
17
17
|
*/
|
|
18
18
|
export async function getTokenToNativeQuote(provider, tokenAddress, tokenAmount, chainId) {
|
|
19
|
-
|
|
20
|
-
return 0n;
|
|
21
|
-
try {
|
|
22
|
-
if (chainId === CHAINS.BSC.chainId) {
|
|
23
|
-
// BSC: 使用 PancakeSwap V2 Router
|
|
24
|
-
const router = new Contract(BSC_PANCAKE_V2_ROUTER, ROUTER_ABI, provider);
|
|
25
|
-
const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, BSC_WBNB]);
|
|
26
|
-
return amounts[1];
|
|
27
|
-
}
|
|
28
|
-
if (chainId === CHAINS.MONAD.chainId) {
|
|
29
|
-
// ✅ Monad: 使用 PancakeSwap V2 Router
|
|
30
|
-
const router = new Contract(MONAD_PANCAKE_V2_ROUTER, ROUTER_ABI, provider);
|
|
31
|
-
const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, MONAD_WMON]);
|
|
32
|
-
return amounts[1];
|
|
33
|
-
}
|
|
34
|
-
// ✅ Base (8453) / XLayer (196) 等链暂不支持 V2 报价,返回 0
|
|
35
|
-
return 0n;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
// 报价失败返回 0(可能是流动性不足或路径不存在)
|
|
39
|
-
return 0n;
|
|
40
|
-
}
|
|
19
|
+
return getTokenToNativeQuoteByChainId(provider, tokenAddress, tokenAmount, chainId);
|
|
41
20
|
}
|
|
42
21
|
// ✅ 使用公共模块中的 ERC20_BALANCE_ABI
|
|
43
22
|
const ERC20_BALANCE_OF_ABI = ERC20_BALANCE_ABI;
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
5
|
import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
6
6
|
import { NonceManager, getOptimizedGasPrice, } from '../../../utils/bundle-helpers.js';
|
|
7
|
-
import {
|
|
8
|
-
import { GAS_LIMITS } from '../../../core/constants/index.js';
|
|
7
|
+
import { quoteRoundTripProfitToNativeByChainId } from '../../../core/quote/quote-helpers.js';
|
|
8
|
+
import { ZERO_ADDRESS, GAS_LIMITS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
9
9
|
import { getGasPriceConfig, getTxType, getBribeAmount, BLOCKRAZOR_BUILDER_EOA, PORTAL_ABI, } from './config.js';
|
|
10
10
|
import { buildTransactionRequest } from '../../../core/tx/build-request.js';
|
|
11
11
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
12
|
-
import {
|
|
12
|
+
import { validateSwapCounts, calculateBuyerFunds, quoteBuyerOutput, ensureSellerBalance, estimateSellFunds, planMultiNonces, buildProfitTransaction, createChainContext, flapBundleBuyFirstMultiWallet, } from './swap-buy-first-helpers.js';
|
|
13
13
|
export async function flapBundleBuyFirstMerkle(params) {
|
|
14
14
|
const { chain, buyerPrivateKey, buyerPrivateKeys, sellerPrivateKey, sellerPrivateKeys, tokenAddress, buyerFunds, buyerFundsPercentage, config, quoteToken, quoteTokenDecimals, buyCount: _buyCount, sellCount: _sellCount, } = params;
|
|
15
15
|
// ✅ 判断是否为多钱包模式
|
|
@@ -34,9 +34,6 @@ export async function flapBundleBuyFirstMerkle(params) {
|
|
|
34
34
|
throw new Error('单钱包模式需要提供 buyerPrivateKey 和 sellerPrivateKey');
|
|
35
35
|
}
|
|
36
36
|
validateSwapCounts(buyCount, sellCount);
|
|
37
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
38
|
-
const totalTxCount = buyCount + sellCount;
|
|
39
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
40
37
|
const chainContext = createChainContext(chain, config.rpcUrl);
|
|
41
38
|
const buyer = new Wallet(buyerPrivateKey, chainContext.provider);
|
|
42
39
|
const seller = new Wallet(sellerPrivateKey, chainContext.provider);
|
|
@@ -123,14 +120,13 @@ export async function flapBundleBuyFirstMerkle(params) {
|
|
|
123
120
|
sameAddress,
|
|
124
121
|
nonceManager,
|
|
125
122
|
});
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
nativeProfitAmount = await getTokenToNativeQuote(chainContext.provider, inputToken, tokenProfitAmount, chainContext.chainId);
|
|
123
|
+
// 买合计万三 + 卖合计万三。ERC-20 先把买入合计折成原生币再计提,避免 ANTFUN 微额报价为 0
|
|
124
|
+
let nativeProfitAmount = 0n;
|
|
125
|
+
if (useNativeToken) {
|
|
126
|
+
nativeProfitAmount = calculateBundleSwapRoundTripProfit(buyerFundsWei, estimatedSellFunds > 0n ? estimatedSellFunds : buyerFundsWei);
|
|
127
|
+
}
|
|
128
|
+
else if (buyerFundsWei > 0n) {
|
|
129
|
+
nativeProfitAmount = await quoteRoundTripProfitToNativeByChainId(chainContext.provider, inputToken, buyerFundsWei, buyerFundsWei, chainContext.chainId);
|
|
134
130
|
}
|
|
135
131
|
// ✅ 构建多笔买入交易
|
|
136
132
|
const buyTxs = buyUnsignedArray.map((unsigned, i) => buildTransactionRequest(unsigned, {
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 功能:钱包A卖出代币 → 钱包B买入相同数量 → 原子执行
|
|
5
5
|
*/
|
|
6
|
-
import { ethers,
|
|
6
|
+
import { ethers, Wallet } from 'ethers';
|
|
7
7
|
import { ADDRESSES } from '../../../core/constants/index.js';
|
|
8
8
|
import { V2_ROUTER_QUOTE_ABI, ERC20_BALANCE_ABI, ERC20_ABI } from '../../../core/shared-abis/common.js';
|
|
9
9
|
import { generateWallets } from '../../../utils/wallet.js';
|
|
10
10
|
import { GAS_LIMITS, CHAINS } from '../../../core/constants/index.js';
|
|
11
|
+
import { getTokenToNativeQuoteByChainId } from '../../../core/quote/quote-helpers.js';
|
|
11
12
|
// ==================== 多跳转账常量(使用统一常量) ====================
|
|
12
13
|
export const NATIVE_TRANSFER_GAS_LIMIT = GAS_LIMITS.NATIVE_TRANSFER;
|
|
13
14
|
export const ERC20_TRANSFER_GAS_LIMIT_HOP = GAS_LIMITS.ERC20_TRANSFER;
|
|
@@ -197,28 +198,7 @@ export const MONAD_WMON = ADDRESSES.MONAD.WMON;
|
|
|
197
198
|
* @returns 等值的原生代币数量(wei),失败返回 0n
|
|
198
199
|
*/
|
|
199
200
|
export async function getTokenToNativeQuote(provider, tokenAddress, tokenAmount, chainId) {
|
|
200
|
-
|
|
201
|
-
return 0n;
|
|
202
|
-
try {
|
|
203
|
-
if (chainId === CHAINS.BSC.chainId) {
|
|
204
|
-
// BSC: 使用 PancakeSwap V2 Router
|
|
205
|
-
const router = new Contract(BSC_PANCAKE_V2_ROUTER, ROUTER_ABI, provider);
|
|
206
|
-
const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, BSC_WBNB]);
|
|
207
|
-
return amounts[1];
|
|
208
|
-
}
|
|
209
|
-
if (chainId === CHAINS.MONAD.chainId) {
|
|
210
|
-
// ✅ Monad: 使用 PancakeSwap V2 Router
|
|
211
|
-
const router = new Contract(MONAD_PANCAKE_V2_ROUTER, ROUTER_ABI, provider);
|
|
212
|
-
const amounts = await router.getAmountsOut(tokenAmount, [tokenAddress, MONAD_WMON]);
|
|
213
|
-
return amounts[1];
|
|
214
|
-
}
|
|
215
|
-
// ✅ Base (8453) / XLayer (196) 等链暂不支持 V2 报价,返回 0
|
|
216
|
-
return 0n;
|
|
217
|
-
}
|
|
218
|
-
catch {
|
|
219
|
-
// 报价失败返回 0(可能是流动性不足或路径不存在)
|
|
220
|
-
return 0n;
|
|
221
|
-
}
|
|
201
|
+
return getTokenToNativeQuoteByChainId(provider, tokenAddress, tokenAmount, chainId);
|
|
222
202
|
}
|
|
223
203
|
/**
|
|
224
204
|
* 获取链ID
|
|
@@ -66,5 +66,5 @@ interface ProfitTxResult {
|
|
|
66
66
|
hopWallets: GeneratedWallet[];
|
|
67
67
|
}
|
|
68
68
|
export declare function buildProfitTransaction({ provider, seller, profitAmount, profitNonce, gasPrice, chainId, txType, }: ProfitTxArgs): Promise<ProfitTxResult | null>;
|
|
69
|
-
export declare function calculateProfitAmount(quotedNative: bigint,
|
|
69
|
+
export declare function calculateProfitAmount(quotedNative: bigint, _userType?: UserType): bigint;
|
|
70
70
|
export {};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { ethers, Contract } from 'ethers';
|
|
2
2
|
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
3
3
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
4
|
-
import { ZERO_ADDRESS } from '../../../core/constants/index.js';
|
|
4
|
+
import { ZERO_ADDRESS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
5
5
|
import { ERC20_ALLOWANCE_ABI } from '../../../core/shared-abis/common.js';
|
|
6
6
|
import { getGasPriceConfig, getTxType, getProfitRecipient, PORTAL_ABI } from './config.js';
|
|
7
|
-
import { getProfitRateBps as getSharedProfitRateBps } from '../../../core/constants/index.js';
|
|
8
7
|
import { getErrorMessageFromUnknown } from '../../../core/index.js';
|
|
9
8
|
import { createSignProvider } from '../../../bundle/sign-context-helpers.js';
|
|
10
9
|
import { APPROVE_INTERFACE, ERC20_BALANCE_OF_ABI, getChainId, getNativeTokenName, } from './swap-helpers.js';
|
|
@@ -161,15 +160,11 @@ export async function buildProfitTransaction({ provider, seller, profitAmount, p
|
|
|
161
160
|
hopWallets: profitHopResult.hopWallets,
|
|
162
161
|
};
|
|
163
162
|
}
|
|
164
|
-
function
|
|
165
|
-
return getSharedProfitRateBps('bundleSwap');
|
|
166
|
-
}
|
|
167
|
-
export function calculateProfitAmount(quotedNative, userType) {
|
|
163
|
+
export function calculateProfitAmount(quotedNative, _userType) {
|
|
168
164
|
if (quotedNative <= 0n) {
|
|
169
165
|
return 0n;
|
|
170
166
|
}
|
|
171
|
-
|
|
172
|
-
return (quotedNative * BigInt(rateBps)) / 10000n;
|
|
167
|
+
return calculateBundleSwapRoundTripProfit(quotedNative, quotedNative);
|
|
173
168
|
}
|
|
174
169
|
function countTruthy(values) {
|
|
175
170
|
return values.filter(Boolean).length;
|
|
@@ -6,11 +6,12 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
6
6
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
7
7
|
import { NonceManager, getOptimizedGasPrice, PROFIT_HOP_COUNT } from '../../../utils/bundle-helpers.js';
|
|
8
8
|
import { ZERO_ADDRESS } from '../../../core/constants/index.js';
|
|
9
|
+
import { quoteRoundTripProfitToNativeByChainId } from '../../../core/quote/quote-helpers.js';
|
|
9
10
|
import { ERC20_ABI } from '../../../core/shared-abis/common.js';
|
|
10
11
|
import { getGasPriceConfig, getTxType, getBribeAmount, BLOCKRAZOR_BUILDER_EOA, PORTAL_ABI, } from './config.js';
|
|
11
12
|
import { buildTransactionRequest } from '../../../core/tx/build-request.js';
|
|
12
13
|
import { GAS_LIMITS } from '../../../core/constants/index.js';
|
|
13
|
-
import { BRIBE_GAS_LIMIT, NATIVE_TRANSFER_GAS_LIMIT, buildBNBHopChainForERC20, buildERC20HopChain, buildNativeHopChain, generateDisperseHopPaths,
|
|
14
|
+
import { BRIBE_GAS_LIMIT, NATIVE_TRANSFER_GAS_LIMIT, buildBNBHopChainForERC20, buildERC20HopChain, buildNativeHopChain, generateDisperseHopPaths, } from './swap-helpers.js';
|
|
14
15
|
import { buildProfitTransaction, calculateProfitAmount, createChainContext, quoteSellOutput, } from './swap-planning.js';
|
|
15
16
|
/**
|
|
16
17
|
* Flap 内盘快捷批量换手(资金利用率模式)
|
|
@@ -91,9 +92,8 @@ export async function flapQuickBatchSwapMerkle(params) {
|
|
|
91
92
|
// ✅ 计算利润(根据 userType 动态调整)
|
|
92
93
|
const tokenProfitAmount = calculateProfitAmount(estimatedOutput, config.userType);
|
|
93
94
|
let nativeProfitAmount = tokenProfitAmount;
|
|
94
|
-
if (!useNativeToken &&
|
|
95
|
-
|
|
96
|
-
nativeProfitAmount = await getTokenToNativeQuote(chainContext.provider, quoteToken, tokenProfitAmount, chainContext.chainId);
|
|
95
|
+
if (!useNativeToken && estimatedOutput > 0n && quoteToken) {
|
|
96
|
+
nativeProfitAmount = await quoteRoundTripProfitToNativeByChainId(chainContext.provider, quoteToken, estimatedOutput, estimatedOutput, chainContext.chainId);
|
|
97
97
|
}
|
|
98
98
|
const distributableAmount = useNativeToken ? estimatedOutput - tokenProfitAmount : estimatedOutput; // ERC20 模式利润从原生代币扣
|
|
99
99
|
// ✅ 计算每个买方分到的金额
|
|
@@ -6,9 +6,10 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
6
6
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
7
7
|
import { NonceManager, getOptimizedGasPrice } from '../../../utils/bundle-helpers.js';
|
|
8
8
|
import { ZERO_ADDRESS } from '../../../core/constants/index.js';
|
|
9
|
+
import { quoteRoundTripProfitToNativeByChainId } from '../../../core/quote/quote-helpers.js';
|
|
9
10
|
import { getGasPriceConfig, getTxType, getBribeAmount, BLOCKRAZOR_BUILDER_EOA, PORTAL_ABI, } from './config.js';
|
|
10
11
|
import { buildTransactionRequest } from '../../../core/tx/build-request.js';
|
|
11
|
-
import { BRIBE_GAS_LIMIT,
|
|
12
|
+
import { BRIBE_GAS_LIMIT, } from './swap-helpers.js';
|
|
12
13
|
import { buildApprovalTransaction, buildNoncePlan, buildProfitTransaction, calculateBuyerNeed, calculateProfitAmount, createChainContext, planNonces, quoteSellOutput, validateBalances, } from './swap-planning.js';
|
|
13
14
|
export async function flapBundleSwapMerkle(params) {
|
|
14
15
|
const { chain, sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKey, tokenAddress, config, quoteToken, quoteTokenDecimals, startNonces, // ✅ 可选:前端预获取的 nonces
|
|
@@ -62,13 +63,13 @@ export async function flapBundleSwapMerkle(params) {
|
|
|
62
63
|
quoteTokenDecimals,
|
|
63
64
|
provider: chainContext.provider,
|
|
64
65
|
});
|
|
65
|
-
// ✅
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
nativeProfitAmount = await
|
|
66
|
+
// ✅ 计算利润。ERC-20 先把卖出合计折成原生币再计提万六,避免 ANTFUN 微额报价为 0
|
|
67
|
+
let nativeProfitAmount = 0n;
|
|
68
|
+
if (useNativeToken) {
|
|
69
|
+
nativeProfitAmount = calculateProfitAmount(quote.quotedNative, config.userType);
|
|
70
|
+
}
|
|
71
|
+
else if (quote.quotedNative > 0n && quoteToken) {
|
|
72
|
+
nativeProfitAmount = await quoteRoundTripProfitToNativeByChainId(chainContext.provider, quoteToken, quote.quotedNative, quote.quotedNative, chainContext.chainId);
|
|
72
73
|
}
|
|
73
74
|
// ✅ 获取贿赂金额
|
|
74
75
|
const bribeAmount = getBribeAmount(config);
|
|
@@ -8,7 +8,7 @@ export * as chains from '../chains/index.js';
|
|
|
8
8
|
export * as Abis from '../abis/index.js';
|
|
9
9
|
export { getErrorMessageFromUnknown, normalizeUnknownError, noopSdkLogger, consoleSdkLogger, buildTransactionRequest, type NormalizedErrorShape, type SdkLogger, type Aggregate3CallResult, type EnsureAllowanceResult, type EnsureAllowanceBatchItemResult, type BuildTxRequestParams, type HoldersMakerChain, type HoldersMakerTradeType, type BaseTokenType, type HoldersMakerConfig, type HoldersMakerParams, type TransactionLayer, type BatchResult, type BatchResult as HoldersMakerBatchResult, type HoldersMakerResult, type DexConfig, type ChainDexConfig, type PoolPairInfo, type V3PoolInfo, type DexPoolInfo, type BestPoolInfo, type LPPlatform, type LPInfo, type InspectOptions, type BundleSubmitResult, type SignedTransactionsResult, type DisperseParams, type AirdropDisperseSignParams, type SweepParams, type AirdropSweepSignParams, type PrivateSaleSignConfig, type PrivateSaleTransferParams, type BatchPrivateSaleParams, type PrivateSaleResult, type ApproveTokenBatchParams, type ApproveTokenBatchRawParams, type ApproveTokenBatchResult, type ApproveTokenBatchSignResult, type SupportedChain, type QuoteParams, type QuoteResult, } from '../core/index.js';
|
|
10
10
|
export { ERC20_ABI, ERC20_BALANCE_ABI, ERC20_ALLOWANCE_ABI, MULTICALL3_ABI, V2_ROUTER_ABI, V2_ROUTER_QUOTE_ABI, V3_ROUTER02_ABI, V3_ROUTER_LEGACY_ABI, V3_QUOTER_ABI, V2_FACTORY_ABI, V2_PAIR_ABI, V3_FACTORY_ABI, V3_POOL_ABI, FLAP_PORTAL_ABI, TM2_ABI, HELPER3_ABI, } from '../abis/common.js';
|
|
11
|
-
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ADDRESSES, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateProfitHopGasCost, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
|
|
11
|
+
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ADDRESSES, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
|
|
12
12
|
export { buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../utils/bundle-helpers.js';
|
|
13
13
|
export { isExclusiveOnChain, isExclusiveOffChain } from '../utils/mpcExclusive.js';
|
|
14
14
|
export { ensureSellApprovalV1, checkSellApprovalV1, ensureSellApprovalV2, checkSellApprovalV2, ensureSellApproval, checkSellApproval, ensureFlapSellApproval, checkFlapSellApproval, ensureFlapSellApprovalBatch, checkFlapSellApprovalBatch, checkAllowance, approveToken, checkAllowanceBatch, approveTokenBatch, checkAllowanceRaw, approveTokenRaw, checkAllowanceBatchRaw, approveTokenBatchRaw, } from '../core/erc20/index.js';
|
|
@@ -29,7 +29,7 @@ GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit,
|
|
|
29
29
|
// 合约地址
|
|
30
30
|
ADDRESSES, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders,
|
|
31
31
|
// 利润配置
|
|
32
|
-
getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateProfitHopGasCost, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS,
|
|
32
|
+
getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS,
|
|
33
33
|
// DEX 报价配置
|
|
34
34
|
QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
|
|
35
35
|
export { buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../utils/bundle-helpers.js';
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
* v2:不再导出 `CHAIN` / `DEFAULT_DEADLINE_MINUTES` / `PROFIT_CONFIG` / 报价 `V3_FEE_TIERS`。
|
|
8
8
|
*/
|
|
9
|
-
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
|
|
9
|
+
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
|
package/dist/utils/constants.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
* v2:不再导出 `CHAIN` / `DEFAULT_DEADLINE_MINUTES` / `PROFIT_CONFIG` / 报价 `V3_FEE_TIERS`。
|
|
8
8
|
*/
|
|
9
|
-
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
|
|
9
|
+
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
|