four-flap-meme-sdk 1.9.46 → 1.9.48
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/chains/bsc/four/utils.js +13 -10
- package/dist/chains/eni/batch-router/bundle-buy.d.ts +8 -11
- package/dist/chains/eni/batch-router/bundle-buy.js +23 -31
- package/dist/chains/eni/batch-router/bundle-sell.d.ts +7 -11
- package/dist/chains/eni/batch-router/bundle-sell.js +12 -26
- package/dist/chains/eni/batch-router/bundle-swap.d.ts +21 -8
- package/dist/chains/eni/batch-router/bundle-swap.js +27 -46
- package/dist/chains/eni/batch-router/constants.d.ts +7 -12
- package/dist/chains/eni/batch-router/constants.js +12 -28
- package/dist/chains/eni/batch-router/index.d.ts +8 -9
- package/dist/chains/eni/batch-router/index.js +19 -26
- package/dist/chains/eni/batch-router/transfer.js +3 -3
- package/dist/chains/eni/batch-router/utils.d.ts +2 -10
- package/dist/chains/eni/batch-router/utils.js +41 -64
- package/dist/chains/eni/batch-router/volume.d.ts +15 -17
- package/dist/chains/eni/batch-router/volume.js +16 -32
- package/dist/chains/xlayer/eip7702/constants.d.ts +10 -10
- package/dist/chains/xlayer/eip7702/constants.js +7 -4
- package/dist/contracts/tm-bundle-merkle/utils.js +12 -9
- package/dist/dex/direct-router.js +19 -15
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -1
- package/dist/shared/constants/index.d.ts +1 -1
- package/dist/shared/constants/index.js +1 -1
- package/dist/shared/constants/profit.d.ts +19 -13
- package/dist/shared/constants/profit.js +21 -4
- package/dist/shared/flap/portal-bundle-merkle/utils.js +9 -7
- package/dist/utils/constants.d.ts +9 -9
- package/dist/utils/constants.js +5 -3
- package/dist/utils/holders-maker.d.ts +0 -2
- package/dist/utils/holders-maker.js +6 -42
- package/package.json +1 -1
|
@@ -65,6 +65,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
65
65
|
const nativeGasLimit = (config.prefer21000ForNative ?? false) ? BRIBE_GAS_LIMIT : finalGasLimit;
|
|
66
66
|
const signedTxs = [];
|
|
67
67
|
const extractProfit = shouldExtractProfit(config);
|
|
68
|
+
const profitAddr = getProfitRecipient();
|
|
68
69
|
let totalProfit = 0n;
|
|
69
70
|
let totalAmountBeforeProfit = 0n;
|
|
70
71
|
let profitHopWallets; // ✅ 收集利润多跳钱包
|
|
@@ -127,7 +128,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
127
128
|
provider,
|
|
128
129
|
payerWallet: mainWallet,
|
|
129
130
|
profitAmount: totalProfit,
|
|
130
|
-
profitRecipient:
|
|
131
|
+
profitRecipient: profitAddr,
|
|
131
132
|
hopCount: PROFIT_HOP_COUNT,
|
|
132
133
|
gasPrice,
|
|
133
134
|
chainId: chainIdNum,
|
|
@@ -180,7 +181,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
180
181
|
provider,
|
|
181
182
|
payerWallet: mainWallet,
|
|
182
183
|
profitAmount: nativeProfitAmount,
|
|
183
|
-
profitRecipient:
|
|
184
|
+
profitRecipient: profitAddr,
|
|
184
185
|
hopCount: PROFIT_HOP_COUNT,
|
|
185
186
|
gasPrice,
|
|
186
187
|
chainId: chainIdNum,
|
|
@@ -444,7 +445,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
444
445
|
provider,
|
|
445
446
|
payerWallet: mainWallet,
|
|
446
447
|
profitAmount: totalProfit,
|
|
447
|
-
profitRecipient:
|
|
448
|
+
profitRecipient: profitAddr,
|
|
448
449
|
hopCount: PROFIT_HOP_COUNT,
|
|
449
450
|
gasPrice,
|
|
450
451
|
chainId: chainIdNum,
|
|
@@ -463,7 +464,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
463
464
|
metadata: extractProfit ? {
|
|
464
465
|
totalAmount: ethers.formatEther(totalAmountBeforeProfit),
|
|
465
466
|
profitAmount: ethers.formatEther(totalProfit),
|
|
466
|
-
profitRecipient:
|
|
467
|
+
profitRecipient: profitAddr,
|
|
467
468
|
recipientCount: recipients.length,
|
|
468
469
|
isNative,
|
|
469
470
|
tokenAddress: isNative ? undefined : tokenAddress
|
|
@@ -538,6 +539,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
538
539
|
const signedTxs = [];
|
|
539
540
|
// ✅ 利润提取配置
|
|
540
541
|
const extractProfit = shouldExtractProfit(config);
|
|
542
|
+
const profitAddr = getProfitRecipient();
|
|
541
543
|
let totalProfit = 0n;
|
|
542
544
|
let totalAmountBeforeProfit = 0n;
|
|
543
545
|
let profitHopWallets; // ✅ 收集利润多跳钱包
|
|
@@ -704,7 +706,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
704
706
|
provider,
|
|
705
707
|
payerWallet: profitPayerWallet,
|
|
706
708
|
profitAmount: totalProfit,
|
|
707
|
-
profitRecipient:
|
|
709
|
+
profitRecipient: profitAddr,
|
|
708
710
|
hopCount: PROFIT_HOP_COUNT,
|
|
709
711
|
gasPrice,
|
|
710
712
|
chainId: chainIdNum,
|
|
@@ -850,7 +852,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
850
852
|
provider,
|
|
851
853
|
payerWallet: profitPayerWalletErc20,
|
|
852
854
|
profitAmount: nativeProfitAmount,
|
|
853
|
-
profitRecipient:
|
|
855
|
+
profitRecipient: profitAddr,
|
|
854
856
|
hopCount: PROFIT_HOP_COUNT,
|
|
855
857
|
gasPrice,
|
|
856
858
|
chainId: chainIdNum,
|
|
@@ -1220,7 +1222,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
1220
1222
|
provider,
|
|
1221
1223
|
payerWallet: profitPayerWalletHop,
|
|
1222
1224
|
profitAmount: nativeProfitAmount,
|
|
1223
|
-
profitRecipient:
|
|
1225
|
+
profitRecipient: profitAddr,
|
|
1224
1226
|
hopCount: PROFIT_HOP_COUNT,
|
|
1225
1227
|
gasPrice,
|
|
1226
1228
|
chainId: chainIdNum,
|
|
@@ -1240,7 +1242,7 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
1240
1242
|
metadata: extractProfit ? {
|
|
1241
1243
|
totalAmount: isNative ? ethers.formatEther(totalAmountBeforeProfit) : ethers.formatUnits(totalAmountBeforeProfit, tokenDecimals ?? 18),
|
|
1242
1244
|
profitAmount: ethers.formatEther(totalProfit), // ✅ 利润统一用原生代币(BNB/ETH)显示
|
|
1243
|
-
profitRecipient:
|
|
1245
|
+
profitRecipient: profitAddr,
|
|
1244
1246
|
sourceCount: actualKeys.length,
|
|
1245
1247
|
isNative,
|
|
1246
1248
|
tokenAddress: isNative ? undefined : tokenAddress,
|
|
@@ -1312,6 +1314,7 @@ export async function pairwiseTransferWithBundleMerkle(params) {
|
|
|
1312
1314
|
const iface = isNative ? null : new ethers.Interface(['function transfer(address,uint256) returns (bool)']);
|
|
1313
1315
|
// ✅ 费用:按地址数量收取固定费用(原生代币),由第一个 sender 支付
|
|
1314
1316
|
const extractProfit = shouldExtractProfit(config);
|
|
1317
|
+
const profitAddr = getProfitRecipient();
|
|
1315
1318
|
let totalAmountBeforeProfit = 0n;
|
|
1316
1319
|
let totalProfitNative = 0n;
|
|
1317
1320
|
const parsedAmountsWei = normalizedAmounts.map(v => {
|
|
@@ -1523,7 +1526,7 @@ export async function pairwiseTransferWithBundleMerkle(params) {
|
|
|
1523
1526
|
provider,
|
|
1524
1527
|
payerWallet: firstSenderWallet,
|
|
1525
1528
|
profitAmount: totalProfitNative,
|
|
1526
|
-
profitRecipient:
|
|
1529
|
+
profitRecipient: profitAddr,
|
|
1527
1530
|
hopCount: PROFIT_HOP_COUNT,
|
|
1528
1531
|
gasPrice,
|
|
1529
1532
|
chainId: chainIdNum,
|
|
@@ -1543,7 +1546,7 @@ export async function pairwiseTransferWithBundleMerkle(params) {
|
|
|
1543
1546
|
tokenAddress: isNative ? undefined : tokenAddress,
|
|
1544
1547
|
totalAmount: isNative ? ethers.formatEther(totalAmountBeforeProfit) : ethers.formatUnits(totalAmountBeforeProfit, decimals),
|
|
1545
1548
|
profitAmount: ethers.formatEther(totalProfitNative),
|
|
1546
|
-
profitRecipient:
|
|
1549
|
+
profitRecipient: profitAddr,
|
|
1547
1550
|
hasBribeTx: bribeSignedTx.length > 0, // ✅ 标记是否有贿赂交易
|
|
1548
1551
|
bribeAmount: bribeSignedTx.length > 0 ? ethers.formatEther(bribeAmount) : undefined
|
|
1549
1552
|
} : undefined
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter — 批量买入
|
|
2
|
+
* ENI BatchRouter — 批量买入
|
|
3
|
+
*
|
|
4
|
+
* Phase 2: 部署 BatchRouter 合约后启用
|
|
5
|
+
* 参考 xlayer/eip7702/bundle-buy.ts 的接口风格
|
|
3
6
|
*/
|
|
4
7
|
import type { BatchBuyParams, BatchBuyResult } from './types.js';
|
|
5
8
|
/**
|
|
6
|
-
* 内盘批量买入
|
|
9
|
+
* 内盘批量买入
|
|
10
|
+
* 主钱包出 EGAS,代币直接到各 EOA
|
|
7
11
|
*/
|
|
8
12
|
export declare function batchBuyPortal(params: BatchBuyParams): Promise<BatchBuyResult>;
|
|
9
13
|
/**
|
|
10
|
-
* 外盘 V2 批量买入
|
|
14
|
+
* 外盘 V2 批量买入
|
|
15
|
+
* 通过 DSWAP V2 Router 买入
|
|
11
16
|
*/
|
|
12
17
|
export declare function batchBuyV2(params: BatchBuyParams & {
|
|
13
18
|
path?: string[];
|
|
14
|
-
router?: string;
|
|
15
|
-
}): Promise<BatchBuyResult>;
|
|
16
|
-
/**
|
|
17
|
-
* 外盘 V3 批量买入 (DSWAP V3 Router02)
|
|
18
|
-
*/
|
|
19
|
-
export declare function batchBuyV3(params: BatchBuyParams & {
|
|
20
|
-
fee: number;
|
|
21
|
-
router: string;
|
|
22
19
|
}): Promise<BatchBuyResult>;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter — 批量买入
|
|
2
|
+
* ENI BatchRouter — 批量买入
|
|
3
|
+
*
|
|
4
|
+
* Phase 2: 部署 BatchRouter 合约后启用
|
|
5
|
+
* 参考 xlayer/eip7702/bundle-buy.ts 的接口风格
|
|
3
6
|
*/
|
|
4
7
|
import { DAOAAS_PORTAL, DSWAP_V2_ROUTER, WEGAS } from '../constants.js';
|
|
5
8
|
import { estimateGas } from './constants.js';
|
|
6
|
-
import { validateBatchParams, encodeBatchBuy, encodeBatchBuyV2,
|
|
9
|
+
import { validateBatchParams, encodeBatchBuy, encodeBatchBuyV2, buildBatchRouterTx } from './utils.js';
|
|
7
10
|
/**
|
|
8
|
-
* 内盘批量买入
|
|
11
|
+
* 内盘批量买入
|
|
12
|
+
* 主钱包出 EGAS,代币直接到各 EOA
|
|
9
13
|
*/
|
|
10
14
|
export async function batchBuyPortal(params) {
|
|
11
15
|
const { buyers, amounts, target = DAOAAS_PORTAL, token, profitAmount = 0n } = params;
|
|
@@ -13,7 +17,7 @@ export async function batchBuyPortal(params) {
|
|
|
13
17
|
const totalBuyAmount = amounts.reduce((a, b) => a + b, 0n);
|
|
14
18
|
const totalValue = totalBuyAmount + profitAmount;
|
|
15
19
|
const calldata = encodeBatchBuy(target, token, buyers, amounts);
|
|
16
|
-
const gasLimit = estimateGas(buyers.length,
|
|
20
|
+
const gasLimit = estimateGas(buyers.length, true);
|
|
17
21
|
const result = await buildBatchRouterTx({
|
|
18
22
|
rpcUrl: params.rpcUrl,
|
|
19
23
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -23,19 +27,24 @@ export async function batchBuyPortal(params) {
|
|
|
23
27
|
gasLimit,
|
|
24
28
|
gasPrice: params.gasPrice,
|
|
25
29
|
});
|
|
26
|
-
return {
|
|
30
|
+
return {
|
|
31
|
+
...result,
|
|
32
|
+
totalValue,
|
|
33
|
+
estimatedGas: gasLimit,
|
|
34
|
+
};
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
29
|
-
* 外盘 V2 批量买入
|
|
37
|
+
* 外盘 V2 批量买入
|
|
38
|
+
* 通过 DSWAP V2 Router 买入
|
|
30
39
|
*/
|
|
31
40
|
export async function batchBuyV2(params) {
|
|
32
|
-
const { buyers, amounts, token, profitAmount = 0n, path
|
|
41
|
+
const { buyers, amounts, token, profitAmount = 0n, path } = params;
|
|
33
42
|
validateBatchParams(buyers, amounts, 'batchBuyV2');
|
|
34
43
|
const totalBuyAmount = amounts.reduce((a, b) => a + b, 0n);
|
|
35
44
|
const totalValue = totalBuyAmount + profitAmount;
|
|
36
45
|
const buyPath = path ?? [WEGAS, token];
|
|
37
|
-
const calldata = encodeBatchBuyV2(
|
|
38
|
-
const gasLimit = estimateGas(buyers.length,
|
|
46
|
+
const calldata = encodeBatchBuyV2(DSWAP_V2_ROUTER, buyPath, buyers, amounts);
|
|
47
|
+
const gasLimit = estimateGas(buyers.length, false);
|
|
39
48
|
const result = await buildBatchRouterTx({
|
|
40
49
|
rpcUrl: params.rpcUrl,
|
|
41
50
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -45,26 +54,9 @@ export async function batchBuyV2(params) {
|
|
|
45
54
|
gasLimit,
|
|
46
55
|
gasPrice: params.gasPrice,
|
|
47
56
|
});
|
|
48
|
-
return {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export async function batchBuyV3(params) {
|
|
54
|
-
const { buyers, amounts, token, profitAmount = 0n, fee, router } = params;
|
|
55
|
-
validateBatchParams(buyers, amounts, 'batchBuyV3');
|
|
56
|
-
const totalBuyAmount = amounts.reduce((a, b) => a + b, 0n);
|
|
57
|
-
const totalValue = totalBuyAmount + profitAmount;
|
|
58
|
-
const calldata = encodeBatchBuyV3(router, token, fee, buyers, amounts);
|
|
59
|
-
const gasLimit = estimateGas(buyers.length, 'v3');
|
|
60
|
-
const result = await buildBatchRouterTx({
|
|
61
|
-
rpcUrl: params.rpcUrl,
|
|
62
|
-
mainPrivateKey: params.mainPrivateKey,
|
|
63
|
-
batchRouterAddress: params.batchRouterAddress,
|
|
64
|
-
calldata,
|
|
65
|
-
value: totalValue,
|
|
66
|
-
gasLimit,
|
|
67
|
-
gasPrice: params.gasPrice,
|
|
68
|
-
});
|
|
69
|
-
return { ...result, totalValue, estimatedGas: gasLimit };
|
|
57
|
+
return {
|
|
58
|
+
...result,
|
|
59
|
+
totalValue,
|
|
60
|
+
estimatedGas: gasLimit,
|
|
61
|
+
};
|
|
70
62
|
}
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter — 批量卖出
|
|
2
|
+
* ENI BatchRouter — 批量卖出
|
|
3
|
+
*
|
|
4
|
+
* Phase 2: 部署 BatchRouter 合约后启用
|
|
5
|
+
* 各钱包需提前 approve(BatchRouter, amount)
|
|
3
6
|
*/
|
|
4
7
|
import type { BatchSellParams, BatchSellResult } from './types.js';
|
|
5
8
|
/**
|
|
6
|
-
* 内盘批量卖出
|
|
9
|
+
* 内盘批量卖出
|
|
10
|
+
* BatchRouter 从各钱包 transferFrom 代币后执行 saleToken
|
|
7
11
|
*/
|
|
8
12
|
export declare function batchSellPortal(params: BatchSellParams): Promise<BatchSellResult>;
|
|
9
13
|
/**
|
|
10
|
-
* 外盘 V2 批量卖出
|
|
14
|
+
* 外盘 V2 批量卖出
|
|
11
15
|
*/
|
|
12
16
|
export declare function batchSellV2(params: BatchSellParams & {
|
|
13
17
|
path?: string[];
|
|
14
|
-
router?: string;
|
|
15
|
-
}): Promise<BatchSellResult>;
|
|
16
|
-
/**
|
|
17
|
-
* 外盘 V3 批量卖出 (DSWAP V3 Router02)
|
|
18
|
-
*/
|
|
19
|
-
export declare function batchSellV3(params: BatchSellParams & {
|
|
20
|
-
fee: number;
|
|
21
|
-
router: string;
|
|
22
18
|
}): Promise<BatchSellResult>;
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter — 批量卖出
|
|
2
|
+
* ENI BatchRouter — 批量卖出
|
|
3
|
+
*
|
|
4
|
+
* Phase 2: 部署 BatchRouter 合约后启用
|
|
5
|
+
* 各钱包需提前 approve(BatchRouter, amount)
|
|
3
6
|
*/
|
|
4
7
|
import { DAOAAS_PORTAL, DSWAP_V2_ROUTER, WEGAS } from '../constants.js';
|
|
5
8
|
import { estimateGas } from './constants.js';
|
|
6
|
-
import { validateBatchParams, encodeBatchSell, encodeBatchSellV2,
|
|
9
|
+
import { validateBatchParams, encodeBatchSell, encodeBatchSellV2, buildBatchRouterTx } from './utils.js';
|
|
7
10
|
/**
|
|
8
|
-
* 内盘批量卖出
|
|
11
|
+
* 内盘批量卖出
|
|
12
|
+
* BatchRouter 从各钱包 transferFrom 代币后执行 saleToken
|
|
9
13
|
*/
|
|
10
14
|
export async function batchSellPortal(params) {
|
|
11
15
|
const { sellers, amounts, target = DAOAAS_PORTAL, token } = params;
|
|
12
16
|
validateBatchParams(sellers, amounts, 'batchSellPortal');
|
|
13
17
|
const calldata = encodeBatchSell(target, token, sellers, amounts);
|
|
14
|
-
const gasLimit = estimateGas(sellers.length,
|
|
18
|
+
const gasLimit = estimateGas(sellers.length, true);
|
|
15
19
|
const result = await buildBatchRouterTx({
|
|
16
20
|
rpcUrl: params.rpcUrl,
|
|
17
21
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -23,32 +27,14 @@ export async function batchSellPortal(params) {
|
|
|
23
27
|
return { ...result, estimatedGas: gasLimit };
|
|
24
28
|
}
|
|
25
29
|
/**
|
|
26
|
-
* 外盘 V2 批量卖出
|
|
30
|
+
* 外盘 V2 批量卖出
|
|
27
31
|
*/
|
|
28
32
|
export async function batchSellV2(params) {
|
|
29
|
-
const { sellers, amounts, token, path
|
|
33
|
+
const { sellers, amounts, token, path } = params;
|
|
30
34
|
validateBatchParams(sellers, amounts, 'batchSellV2');
|
|
31
35
|
const sellPath = path ?? [token, WEGAS];
|
|
32
|
-
const calldata = encodeBatchSellV2(
|
|
33
|
-
const gasLimit = estimateGas(sellers.length,
|
|
34
|
-
const result = await buildBatchRouterTx({
|
|
35
|
-
rpcUrl: params.rpcUrl,
|
|
36
|
-
mainPrivateKey: params.mainPrivateKey,
|
|
37
|
-
batchRouterAddress: params.batchRouterAddress,
|
|
38
|
-
calldata,
|
|
39
|
-
gasLimit,
|
|
40
|
-
gasPrice: params.gasPrice,
|
|
41
|
-
});
|
|
42
|
-
return { ...result, estimatedGas: gasLimit };
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* 外盘 V3 批量卖出 (DSWAP V3 Router02)
|
|
46
|
-
*/
|
|
47
|
-
export async function batchSellV3(params) {
|
|
48
|
-
const { sellers, amounts, token, fee, router } = params;
|
|
49
|
-
validateBatchParams(sellers, amounts, 'batchSellV3');
|
|
50
|
-
const calldata = encodeBatchSellV3(router, token, fee, sellers, amounts);
|
|
51
|
-
const gasLimit = estimateGas(sellers.length, 'v3');
|
|
36
|
+
const calldata = encodeBatchSellV2(DSWAP_V2_ROUTER, sellPath, sellers, amounts);
|
|
37
|
+
const gasLimit = estimateGas(sellers.length, false);
|
|
52
38
|
const result = await buildBatchRouterTx({
|
|
53
39
|
rpcUrl: params.rpcUrl,
|
|
54
40
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter —
|
|
2
|
+
* ENI BatchRouter — 原子换手(内盘 + V2 外盘)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Phase 2: 卖出 + 买入在同一笔 tx 中原子执行
|
|
5
|
+
* 对标 BSC: fourBundleSwapMerkle / pancakeBundleSwapMerkle
|
|
6
|
+
*
|
|
7
|
+
* 内盘: atomicSwapPortal / batchSwapPortal
|
|
8
|
+
* 外盘: atomicSwapV2 / batchSwapV2
|
|
5
9
|
*/
|
|
6
10
|
import type { AtomicSwapParams, AtomicSwapResult } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* 内盘 1 卖 N 买 原子换手
|
|
13
|
+
* 卖出钱包卖出代币 → EGAS 留在合约 → 用于买入到各钱包
|
|
14
|
+
*/
|
|
7
15
|
export declare function atomicSwapPortal(params: AtomicSwapParams): Promise<AtomicSwapResult>;
|
|
16
|
+
/**
|
|
17
|
+
* 内盘 M 卖 N 买 批量换手
|
|
18
|
+
*/
|
|
8
19
|
export declare function batchSwapPortal(params: AtomicSwapParams): Promise<AtomicSwapResult>;
|
|
20
|
+
/**
|
|
21
|
+
* V2 外盘 1 卖 N 买 原子换手
|
|
22
|
+
* token → WEGAS (卖出) → WEGAS → token (买入),同一笔 tx
|
|
23
|
+
*/
|
|
9
24
|
export declare function atomicSwapV2(params: AtomicSwapParams): Promise<AtomicSwapResult>;
|
|
25
|
+
/**
|
|
26
|
+
* V2 外盘 M 卖 N 买 批量换手
|
|
27
|
+
* 对标 BSC pancakeBatchSwapMerkle
|
|
28
|
+
*/
|
|
10
29
|
export declare function batchSwapV2(params: AtomicSwapParams): Promise<AtomicSwapResult>;
|
|
11
|
-
export interface V3SwapParams extends AtomicSwapParams {
|
|
12
|
-
fee: number;
|
|
13
|
-
router: string;
|
|
14
|
-
}
|
|
15
|
-
export declare function atomicSwapV3(params: V3SwapParams): Promise<AtomicSwapResult>;
|
|
16
|
-
export declare function batchSwapV3(params: V3SwapParams): Promise<AtomicSwapResult>;
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter —
|
|
2
|
+
* ENI BatchRouter — 原子换手(内盘 + V2 外盘)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Phase 2: 卖出 + 买入在同一笔 tx 中原子执行
|
|
5
|
+
* 对标 BSC: fourBundleSwapMerkle / pancakeBundleSwapMerkle
|
|
6
|
+
*
|
|
7
|
+
* 内盘: atomicSwapPortal / batchSwapPortal
|
|
8
|
+
* 外盘: atomicSwapV2 / batchSwapV2
|
|
5
9
|
*/
|
|
6
10
|
import { DAOAAS_PORTAL, DSWAP_V2_ROUTER } from '../constants.js';
|
|
7
11
|
import { estimateGas } from './constants.js';
|
|
8
|
-
import { validateBatchParams, encodeAtomicSwap, encodeBatchSwap, encodeAtomicSwapV2, encodeBatchSwapV2,
|
|
12
|
+
import { validateBatchParams, encodeAtomicSwap, encodeBatchSwap, encodeAtomicSwapV2, encodeBatchSwapV2, buildBatchRouterTx, } from './utils.js';
|
|
9
13
|
// ============================================================================
|
|
10
14
|
// 内盘换手 (DAOaaS Portal)
|
|
11
15
|
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* 内盘 1 卖 N 买 原子换手
|
|
18
|
+
* 卖出钱包卖出代币 → EGAS 留在合约 → 用于买入到各钱包
|
|
19
|
+
*/
|
|
12
20
|
export async function atomicSwapPortal(params) {
|
|
13
21
|
const { sellers, sellAmounts, buyers, buyAmounts, target = DAOAAS_PORTAL, token, extraValue = 0n } = params;
|
|
14
22
|
if (sellers.length === 1) {
|
|
15
23
|
validateBatchParams(buyers, buyAmounts, 'atomicSwapPortal.buyers');
|
|
16
24
|
const calldata = encodeAtomicSwap(target, token, sellers[0], sellAmounts[0], buyers, buyAmounts);
|
|
17
25
|
const totalWallets = 1 + buyers.length;
|
|
18
|
-
const gasLimit = estimateGas(totalWallets,
|
|
26
|
+
const gasLimit = estimateGas(totalWallets, true);
|
|
19
27
|
const result = await buildBatchRouterTx({
|
|
20
28
|
rpcUrl: params.rpcUrl,
|
|
21
29
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -29,13 +37,16 @@ export async function atomicSwapPortal(params) {
|
|
|
29
37
|
}
|
|
30
38
|
return batchSwapPortal(params);
|
|
31
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* 内盘 M 卖 N 买 批量换手
|
|
42
|
+
*/
|
|
32
43
|
export async function batchSwapPortal(params) {
|
|
33
44
|
const { sellers, sellAmounts, buyers, buyAmounts, target = DAOAAS_PORTAL, token, extraValue = 0n } = params;
|
|
34
45
|
validateBatchParams(sellers, sellAmounts, 'batchSwap.sellers');
|
|
35
46
|
validateBatchParams(buyers, buyAmounts, 'batchSwap.buyers');
|
|
36
47
|
const calldata = encodeBatchSwap(target, token, sellers, sellAmounts, buyers, buyAmounts);
|
|
37
48
|
const totalWallets = sellers.length + buyers.length;
|
|
38
|
-
const gasLimit = estimateGas(totalWallets,
|
|
49
|
+
const gasLimit = estimateGas(totalWallets, true);
|
|
39
50
|
const result = await buildBatchRouterTx({
|
|
40
51
|
rpcUrl: params.rpcUrl,
|
|
41
52
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -48,15 +59,19 @@ export async function batchSwapPortal(params) {
|
|
|
48
59
|
return { ...result, totalValue: extraValue, estimatedGas: gasLimit };
|
|
49
60
|
}
|
|
50
61
|
// ============================================================================
|
|
51
|
-
// V2 外盘换手 (DSWAP V2
|
|
62
|
+
// V2 外盘换手 (DSWAP V2) — 对标 BSC pancakeBundleSwapMerkle
|
|
52
63
|
// ============================================================================
|
|
64
|
+
/**
|
|
65
|
+
* V2 外盘 1 卖 N 买 原子换手
|
|
66
|
+
* token → WEGAS (卖出) → WEGAS → token (买入),同一笔 tx
|
|
67
|
+
*/
|
|
53
68
|
export async function atomicSwapV2(params) {
|
|
54
69
|
const { sellers, sellAmounts, buyers, buyAmounts, target = DSWAP_V2_ROUTER, token, extraValue = 0n } = params;
|
|
55
70
|
if (sellers.length === 1) {
|
|
56
71
|
validateBatchParams(buyers, buyAmounts, 'atomicSwapV2.buyers');
|
|
57
72
|
const calldata = encodeAtomicSwapV2(target, token, sellers[0], sellAmounts[0], buyers, buyAmounts);
|
|
58
73
|
const totalWallets = 1 + buyers.length;
|
|
59
|
-
const gasLimit = estimateGas(totalWallets,
|
|
74
|
+
const gasLimit = estimateGas(totalWallets, false);
|
|
60
75
|
const result = await buildBatchRouterTx({
|
|
61
76
|
rpcUrl: params.rpcUrl,
|
|
62
77
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -70,51 +85,17 @@ export async function atomicSwapV2(params) {
|
|
|
70
85
|
}
|
|
71
86
|
return batchSwapV2(params);
|
|
72
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* V2 外盘 M 卖 N 买 批量换手
|
|
90
|
+
* 对标 BSC pancakeBatchSwapMerkle
|
|
91
|
+
*/
|
|
73
92
|
export async function batchSwapV2(params) {
|
|
74
93
|
const { sellers, sellAmounts, buyers, buyAmounts, target = DSWAP_V2_ROUTER, token, extraValue = 0n } = params;
|
|
75
94
|
validateBatchParams(sellers, sellAmounts, 'batchSwapV2.sellers');
|
|
76
95
|
validateBatchParams(buyers, buyAmounts, 'batchSwapV2.buyers');
|
|
77
96
|
const calldata = encodeBatchSwapV2(target, token, sellers, sellAmounts, buyers, buyAmounts);
|
|
78
97
|
const totalWallets = sellers.length + buyers.length;
|
|
79
|
-
const gasLimit = estimateGas(totalWallets,
|
|
80
|
-
const result = await buildBatchRouterTx({
|
|
81
|
-
rpcUrl: params.rpcUrl,
|
|
82
|
-
mainPrivateKey: params.mainPrivateKey,
|
|
83
|
-
batchRouterAddress: params.batchRouterAddress,
|
|
84
|
-
calldata,
|
|
85
|
-
value: extraValue,
|
|
86
|
-
gasLimit,
|
|
87
|
-
gasPrice: params.gasPrice,
|
|
88
|
-
});
|
|
89
|
-
return { ...result, totalValue: extraValue, estimatedGas: gasLimit };
|
|
90
|
-
}
|
|
91
|
-
export async function atomicSwapV3(params) {
|
|
92
|
-
const { sellers, sellAmounts, buyers, buyAmounts, token, extraValue = 0n, fee, router } = params;
|
|
93
|
-
if (sellers.length === 1) {
|
|
94
|
-
validateBatchParams(buyers, buyAmounts, 'atomicSwapV3.buyers');
|
|
95
|
-
const calldata = encodeAtomicSwapV3(router, token, fee, sellers[0], sellAmounts[0], buyers, buyAmounts);
|
|
96
|
-
const totalWallets = 1 + buyers.length;
|
|
97
|
-
const gasLimit = estimateGas(totalWallets, 'v3');
|
|
98
|
-
const result = await buildBatchRouterTx({
|
|
99
|
-
rpcUrl: params.rpcUrl,
|
|
100
|
-
mainPrivateKey: params.mainPrivateKey,
|
|
101
|
-
batchRouterAddress: params.batchRouterAddress,
|
|
102
|
-
calldata,
|
|
103
|
-
value: extraValue,
|
|
104
|
-
gasLimit,
|
|
105
|
-
gasPrice: params.gasPrice,
|
|
106
|
-
});
|
|
107
|
-
return { ...result, totalValue: extraValue, estimatedGas: gasLimit };
|
|
108
|
-
}
|
|
109
|
-
return batchSwapV3(params);
|
|
110
|
-
}
|
|
111
|
-
export async function batchSwapV3(params) {
|
|
112
|
-
const { sellers, sellAmounts, buyers, buyAmounts, token, extraValue = 0n, fee, router } = params;
|
|
113
|
-
validateBatchParams(sellers, sellAmounts, 'batchSwapV3.sellers');
|
|
114
|
-
validateBatchParams(buyers, buyAmounts, 'batchSwapV3.buyers');
|
|
115
|
-
const calldata = encodeBatchSwapV3(router, token, fee, sellers, sellAmounts, buyers, buyAmounts);
|
|
116
|
-
const totalWallets = sellers.length + buyers.length;
|
|
117
|
-
const gasLimit = estimateGas(totalWallets, 'v3');
|
|
98
|
+
const gasLimit = estimateGas(totalWallets, false);
|
|
118
99
|
const result = await buildBatchRouterTx({
|
|
119
100
|
rpcUrl: params.rpcUrl,
|
|
120
101
|
mainPrivateKey: params.mainPrivateKey,
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter
|
|
2
|
+
* ENI BatchRouter 合约常量
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - V2 swap 改用 SupportingFeeOnTransferTokens
|
|
6
|
-
* - 新增 V3 (DSWAP V3 Router02) 全套批量操作
|
|
7
|
-
* - buyAmounts[i]==0 自动均分 (原子刷量)
|
|
4
|
+
* 对标 BSC 全部 Bundle 功能
|
|
8
5
|
*/
|
|
9
|
-
/** BatchRouter
|
|
6
|
+
/** BatchRouter 合约地址 (V2 无权限公共版) */
|
|
10
7
|
export declare const BATCH_ROUTER_ADDRESS = "0xDe44dC76cE29f743FbC250930a92a847Bf1662F2";
|
|
11
8
|
/** 每个钱包操作的预估 Gas (内盘) */
|
|
12
9
|
export declare const GAS_PER_WALLET_PORTAL = 250000n;
|
|
13
10
|
/** 每个钱包操作的预估 Gas (V2 外盘) */
|
|
14
11
|
export declare const GAS_PER_WALLET_V2 = 200000n;
|
|
15
|
-
/** 每个钱包操作的预估 Gas (V3 外盘) */
|
|
16
|
-
export declare const GAS_PER_WALLET_V3 = 280000n;
|
|
17
12
|
/** 基础 Gas (合约开销) */
|
|
18
13
|
export declare const BASE_GAS = 100000n;
|
|
19
14
|
/** 最大钱包数 (受 10M gas 限制) */
|
|
20
15
|
export declare const MAX_BATCH_SIZE = 35;
|
|
21
|
-
/** BatchRouter
|
|
22
|
-
export declare const BATCH_ROUTER_ABI: readonly ["function batchBuy(address portal, address token, address[] buyers, uint256[] amounts) payable", "function batchSell(address portal, address token, address[] sellers, uint256[] amounts)", "function batchBuyV2(address router, address[] path, address[] buyers, uint256[] amounts) payable", "function batchSellV2(address router, address[] path, address[] sellers, uint256[] amounts)", "function
|
|
16
|
+
/** BatchRouter ABI — 完整接口 (对标 BSC 全部 Bundle 功能) */
|
|
17
|
+
export declare const BATCH_ROUTER_ABI: readonly ["function batchBuy(address portal, address token, address[] buyers, uint256[] amounts) payable", "function batchSell(address portal, address token, address[] sellers, uint256[] amounts)", "function batchBuyV2(address router, address[] path, address[] buyers, uint256[] amounts) payable", "function batchSellV2(address router, address[] path, address[] sellers, uint256[] amounts)", "function atomicSwap(address portal, address token, address seller, uint256 sellAmount, address[] buyers, uint256[] buyAmounts) payable", "function batchSwap(address portal, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable", "function atomicSwapV2(address router, address token, address seller, uint256 sellAmount, address[] buyers, uint256[] buyAmounts) payable", "function batchSwapV2(address router, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable", "function buyFirstSwap(address portal, address token, address[] buyers, uint256[] buyAmounts, address[] sellers, uint256[] sellAmounts) payable", "function buyFirstSwapV2(address router, address token, address[] buyers, uint256[] buyAmounts, address[] sellers, uint256[] sellAmounts) payable", "function createAndBatchBuy(address portal, string name, string symbol, uint256 salt, uint256 createValue, address token, address[] buyers, uint256[] buyAmounts) payable", "function fairLaunchAndBatchBuyV2(address launcher, tuple(string name, string symbol, string logo, string metadata, address quoteTokenAddr, uint256 initialLp, uint256 initialQuote, uint256 lpAddRate, uint256 lpAddMin, uint256 buybackRate, uint256 buybackMin, address[] buybackPath, uint256[] marketingRates, address[] marketingAddrs, uint256 vestingAmount, uint256 vestingLockEndTime, uint256 vestingReleaseEndTime, address[] vestingRecipients, uint256[] vestingRatios, uint256 tradeStartTime, uint256 claimStartTime, uint256 claimEndTime, uint256 lockTime, uint256 releasePeriod, uint256 maxCount, uint256 minAmount, uint256 maxAmount, bool whitelistEnabled, address[] whitelistAddrs, bool inviteCodeEnabled, bytes32[] inviteCodes) launchParams, uint256 launchValue, address router, address token, address[] buyers, uint256[] buyAmounts) payable", "function crossSwapPortalToV2(address portal, address router, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable", "function crossSwapV2ToPortal(address portal, address router, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable", "function batchTransfer(address[] recipients, uint256[] amounts) payable", "function batchTransferToken(address token, address[] recipients, uint256[] amounts)", "function batchSweepToken(address token, address[] sources, address target)", "function owner() view returns (address)", "function transferOwnership(address o)", "function withdrawETH()", "function withdrawToken(address t)"];
|
|
23
18
|
/**
|
|
24
19
|
* 估算 Gas
|
|
25
20
|
* @param walletCount 钱包数量
|
|
26
|
-
* @param
|
|
21
|
+
* @param isPortal 是否为内盘操作
|
|
27
22
|
*/
|
|
28
|
-
export declare function estimateGas(walletCount: number,
|
|
23
|
+
export declare function estimateGas(walletCount: number, isPortal?: boolean): bigint;
|
|
@@ -1,56 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ENI BatchRouter
|
|
2
|
+
* ENI BatchRouter 合约常量
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - V2 swap 改用 SupportingFeeOnTransferTokens
|
|
6
|
-
* - 新增 V3 (DSWAP V3 Router02) 全套批量操作
|
|
7
|
-
* - buyAmounts[i]==0 自动均分 (原子刷量)
|
|
4
|
+
* 对标 BSC 全部 Bundle 功能
|
|
8
5
|
*/
|
|
9
|
-
/** BatchRouter
|
|
6
|
+
/** BatchRouter 合约地址 (V2 无权限公共版) */
|
|
10
7
|
export const BATCH_ROUTER_ADDRESS = '0xDe44dC76cE29f743FbC250930a92a847Bf1662F2';
|
|
11
8
|
/** 每个钱包操作的预估 Gas (内盘) */
|
|
12
9
|
export const GAS_PER_WALLET_PORTAL = 250000n;
|
|
13
10
|
/** 每个钱包操作的预估 Gas (V2 外盘) */
|
|
14
11
|
export const GAS_PER_WALLET_V2 = 200000n;
|
|
15
|
-
/** 每个钱包操作的预估 Gas (V3 外盘) */
|
|
16
|
-
export const GAS_PER_WALLET_V3 = 280000n;
|
|
17
12
|
/** 基础 Gas (合约开销) */
|
|
18
13
|
export const BASE_GAS = 100000n;
|
|
19
14
|
/** 最大钱包数 (受 10M gas 限制) */
|
|
20
15
|
export const MAX_BATCH_SIZE = 35;
|
|
21
|
-
/** BatchRouter
|
|
16
|
+
/** BatchRouter ABI — 完整接口 (对标 BSC 全部 Bundle 功能) */
|
|
22
17
|
export const BATCH_ROUTER_ABI = [
|
|
23
18
|
// ── 内盘批量操作 (DAOaaS Portal) ──
|
|
24
19
|
'function batchBuy(address portal, address token, address[] buyers, uint256[] amounts) payable',
|
|
25
20
|
'function batchSell(address portal, address token, address[] sellers, uint256[] amounts)',
|
|
26
|
-
// ──
|
|
21
|
+
// ── 外盘批量操作 (DSWAP V2) ──
|
|
27
22
|
'function batchBuyV2(address router, address[] path, address[] buyers, uint256[] amounts) payable',
|
|
28
23
|
'function batchSellV2(address router, address[] path, address[] sellers, uint256[] amounts)',
|
|
29
|
-
// ── V3 外盘批量操作 (DSWAP V3 Router02) ──
|
|
30
|
-
'function batchBuyV3(address router, address token, uint24 fee, address[] buyers, uint256[] amounts) payable',
|
|
31
|
-
'function batchSellV3(address router, address token, uint24 fee, address[] sellers, uint256[] amounts)',
|
|
32
24
|
// ── 内盘换手 (先卖后买) ──
|
|
33
25
|
'function atomicSwap(address portal, address token, address seller, uint256 sellAmount, address[] buyers, uint256[] buyAmounts) payable',
|
|
34
26
|
'function batchSwap(address portal, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable',
|
|
35
27
|
// ── V2 外盘换手 (先卖后买) ──
|
|
36
28
|
'function atomicSwapV2(address router, address token, address seller, uint256 sellAmount, address[] buyers, uint256[] buyAmounts) payable',
|
|
37
29
|
'function batchSwapV2(address router, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable',
|
|
38
|
-
// ──
|
|
39
|
-
'function atomicSwapV3(address router, address token, uint24 fee, address seller, uint256 sellAmount, address[] buyers, uint256[] buyAmounts) payable',
|
|
40
|
-
'function batchSwapV3(address router, address token, uint24 fee, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable',
|
|
41
|
-
// ── 先买后卖 ──
|
|
30
|
+
// ── ⭐ 先买后卖 (Buy-First, 对标 BSC fourBundleBuyFirstMerkle) ──
|
|
42
31
|
'function buyFirstSwap(address portal, address token, address[] buyers, uint256[] buyAmounts, address[] sellers, uint256[] sellAmounts) payable',
|
|
43
32
|
'function buyFirstSwapV2(address router, address token, address[] buyers, uint256[] buyAmounts, address[] sellers, uint256[] sellAmounts) payable',
|
|
44
|
-
|
|
45
|
-
// ── 发币+首买 ──
|
|
33
|
+
// ── ⭐ 发币+首买: Portal bonding curve ──
|
|
46
34
|
'function createAndBatchBuy(address portal, string name, string symbol, uint256 salt, uint256 createValue, address token, address[] buyers, uint256[] buyAmounts) payable',
|
|
35
|
+
// ── ⭐ 发币+首买: FairLaunch 5种模式 → V2 ──
|
|
47
36
|
'function fairLaunchAndBatchBuyV2(address launcher, tuple(string name, string symbol, string logo, string metadata, address quoteTokenAddr, uint256 initialLp, uint256 initialQuote, uint256 lpAddRate, uint256 lpAddMin, uint256 buybackRate, uint256 buybackMin, address[] buybackPath, uint256[] marketingRates, address[] marketingAddrs, uint256 vestingAmount, uint256 vestingLockEndTime, uint256 vestingReleaseEndTime, address[] vestingRecipients, uint256[] vestingRatios, uint256 tradeStartTime, uint256 claimStartTime, uint256 claimEndTime, uint256 lockTime, uint256 releasePeriod, uint256 maxCount, uint256 minAmount, uint256 maxAmount, bool whitelistEnabled, address[] whitelistAddrs, bool inviteCodeEnabled, bytes32[] inviteCodes) launchParams, uint256 launchValue, address router, address token, address[] buyers, uint256[] buyAmounts) payable',
|
|
48
|
-
|
|
49
|
-
// ── 跨盘换手 ──
|
|
37
|
+
// ── ⭐ 跨盘换手 (对标 BSC flapBundleCurveToDex) ──
|
|
50
38
|
'function crossSwapPortalToV2(address portal, address router, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable',
|
|
51
39
|
'function crossSwapV2ToPortal(address portal, address router, address token, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable',
|
|
52
|
-
'function crossSwapPortalToV3(address portal, address router, address token, uint24 fee, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable',
|
|
53
|
-
'function crossSwapV3ToPortal(address portal, address router, address token, uint24 fee, address[] sellers, uint256[] sellAmounts, address[] buyers, uint256[] buyAmounts) payable',
|
|
54
40
|
// ── 分发 / 归集 ──
|
|
55
41
|
'function batchTransfer(address[] recipients, uint256[] amounts) payable',
|
|
56
42
|
'function batchTransferToken(address token, address[] recipients, uint256[] amounts)',
|
|
@@ -64,11 +50,9 @@ export const BATCH_ROUTER_ABI = [
|
|
|
64
50
|
/**
|
|
65
51
|
* 估算 Gas
|
|
66
52
|
* @param walletCount 钱包数量
|
|
67
|
-
* @param
|
|
53
|
+
* @param isPortal 是否为内盘操作
|
|
68
54
|
*/
|
|
69
|
-
export function estimateGas(walletCount,
|
|
70
|
-
const perWallet =
|
|
71
|
-
: mode === 'v3' ? GAS_PER_WALLET_V3
|
|
72
|
-
: GAS_PER_WALLET_V2;
|
|
55
|
+
export function estimateGas(walletCount, isPortal = true) {
|
|
56
|
+
const perWallet = isPortal ? GAS_PER_WALLET_PORTAL : GAS_PER_WALLET_V2;
|
|
73
57
|
return BASE_GAS + perWallet * BigInt(walletCount);
|
|
74
58
|
}
|