four-flap-meme-sdk 1.5.21 → 1.5.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/tm-bundle-merkle/index.d.ts +1 -1
- package/dist/contracts/tm-bundle-merkle/index.js +1 -1
- package/dist/contracts/tm-bundle-merkle/types.d.ts +24 -0
- package/dist/contracts/tm-bundle-merkle/utils.d.ts +8 -1
- package/dist/contracts/tm-bundle-merkle/utils.js +287 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ export * from './config.js';
|
|
|
6
6
|
export * from './types.js';
|
|
7
7
|
export { createTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle, batchSellWithBundleMerkle } from './core.js';
|
|
8
8
|
export { fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle } from './private.js';
|
|
9
|
-
export { disperseWithBundleMerkle, sweepWithBundleMerkle } from './utils.js';
|
|
9
|
+
export { disperseWithBundleMerkle, sweepWithBundleMerkle, pairwiseTransferWithBundleMerkle } from './utils.js';
|
|
10
10
|
export { fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch } from './pancake-proxy.js';
|
|
11
11
|
export { approveFourTokenManagerBatch, type ApproveFourTokenManagerBatchParams, type ApproveFourTokenManagerBatchResult } from './approve-tokenmanager.js';
|
|
12
12
|
export { submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, type MerkleSubmitConfig, type SubmitBundleResult, submitBundleToBlockRazor, submitMultipleBundlesToBlockRazor, submitMultipleBundlesToBlockRazorParallel, type BlockRazorSubmitConfig, type BlockRazorSubmitResult, submitDirectToRpc, submitDirectToRpcSequential, // ✅ 新增:顺序广播并等待确认(用于多跳)
|
|
@@ -10,7 +10,7 @@ export { createTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle, batchSellWith
|
|
|
10
10
|
// 私有交易方法
|
|
11
11
|
export { fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle } from './private.js';
|
|
12
12
|
// 工具方法
|
|
13
|
-
export { disperseWithBundleMerkle, sweepWithBundleMerkle } from './utils.js';
|
|
13
|
+
export { disperseWithBundleMerkle, sweepWithBundleMerkle, pairwiseTransferWithBundleMerkle } from './utils.js';
|
|
14
14
|
// PancakeSwapProxy 代理交易方法
|
|
15
15
|
export { fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch } from './pancake-proxy.js';
|
|
16
16
|
// TokenManager 授权方法
|
|
@@ -337,6 +337,30 @@ export type SweepSignParams = {
|
|
|
337
337
|
* 包含 hopWallets 用于返回生成的多跳钱包私钥
|
|
338
338
|
*/
|
|
339
339
|
export type SweepMerkleResult = MerkleSignedResult;
|
|
340
|
+
/**
|
|
341
|
+
* 多对多(地址一一对应)转账参数(仅签名版本)
|
|
342
|
+
* - senderPrivateKeys / receiverAddresses 必须等长
|
|
343
|
+
* - amount / amounts 二选一(amounts 优先)
|
|
344
|
+
* - 支持多跳:hopCount 可为 number 或逐对数组
|
|
345
|
+
* - 支持利润刮取:利润由第一个 sender 支付(作为额外费用,不扣减每对转账金额)
|
|
346
|
+
*/
|
|
347
|
+
export type PairwiseTransferSignParams = {
|
|
348
|
+
senderPrivateKeys: string[];
|
|
349
|
+
receiverAddresses: string[];
|
|
350
|
+
amount?: AmountLike;
|
|
351
|
+
amounts?: AmountLike[];
|
|
352
|
+
tokenAddress?: string;
|
|
353
|
+
tokenDecimals?: number;
|
|
354
|
+
hopCount?: number | number[];
|
|
355
|
+
hopPrivateKeys?: string[][];
|
|
356
|
+
config: FourSignConfig;
|
|
357
|
+
/** ✅ 起始 nonce(仅对第一个 sender 生效,用于并行调用避免 nonce 冲突) */
|
|
358
|
+
startNonce?: number;
|
|
359
|
+
tokenPoolType?: TokenPoolType;
|
|
360
|
+
quoteToken?: QuoteTokenType;
|
|
361
|
+
userType?: UserType;
|
|
362
|
+
};
|
|
363
|
+
export type PairwiseTransferMerkleResult = MerkleSignedResult;
|
|
340
364
|
/** ✅ PancakeProxy 批量购买参数(Merkle 版本 - 完整) */
|
|
341
365
|
export type FourPancakeProxyBatchBuyParams = {
|
|
342
366
|
privateKeys: string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DisperseSignParams, DisperseMerkleResult, SweepSignParams, SweepMerkleResult } from './types.js';
|
|
1
|
+
import { DisperseSignParams, DisperseMerkleResult, SweepSignParams, SweepMerkleResult, PairwiseTransferSignParams, PairwiseTransferMerkleResult } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* 分发(仅签名版本 - 不依赖 Merkle)
|
|
4
4
|
* ✅ 精简版:只负责签名交易,不提交到 Merkle
|
|
@@ -11,3 +11,10 @@ export declare function disperseWithBundleMerkle(params: DisperseSignParams): Pr
|
|
|
11
11
|
* ✅ 优化版:支持 startNonce 参数避免并行调用时的 nonce 冲突
|
|
12
12
|
*/
|
|
13
13
|
export declare function sweepWithBundleMerkle(params: SweepSignParams): Promise<SweepMerkleResult>;
|
|
14
|
+
/**
|
|
15
|
+
* 多对多(地址一一对应)转账(仅签名版本 - 不依赖 Merkle)
|
|
16
|
+
* - 支持原生币 / ERC20
|
|
17
|
+
* - 支持多跳(逐对)
|
|
18
|
+
* - 支持利润刮取:利润由第一个 sender 支付(作为额外费用,不扣减每对转账金额)
|
|
19
|
+
*/
|
|
20
|
+
export declare function pairwiseTransferWithBundleMerkle(params: PairwiseTransferSignParams): Promise<PairwiseTransferMerkleResult>;
|
|
@@ -1389,3 +1389,290 @@ export async function sweepWithBundleMerkle(params) {
|
|
|
1389
1389
|
} : undefined
|
|
1390
1390
|
};
|
|
1391
1391
|
}
|
|
1392
|
+
/**
|
|
1393
|
+
* 多对多(地址一一对应)转账(仅签名版本 - 不依赖 Merkle)
|
|
1394
|
+
* - 支持原生币 / ERC20
|
|
1395
|
+
* - 支持多跳(逐对)
|
|
1396
|
+
* - 支持利润刮取:利润由第一个 sender 支付(作为额外费用,不扣减每对转账金额)
|
|
1397
|
+
*/
|
|
1398
|
+
export async function pairwiseTransferWithBundleMerkle(params) {
|
|
1399
|
+
const { senderPrivateKeys, receiverAddresses, amount, amounts, tokenAddress, tokenDecimals, hopCount = 0, hopPrivateKeys, config, startNonce, tokenPoolType = 'v2', quoteToken = 'native', userType = 'v0', } = params;
|
|
1400
|
+
if (!senderPrivateKeys || senderPrivateKeys.length === 0) {
|
|
1401
|
+
return { signedTransactions: [], hopWallets: undefined };
|
|
1402
|
+
}
|
|
1403
|
+
if (!receiverAddresses || receiverAddresses.length === 0) {
|
|
1404
|
+
return { signedTransactions: [], hopWallets: undefined };
|
|
1405
|
+
}
|
|
1406
|
+
if (senderPrivateKeys.length !== receiverAddresses.length) {
|
|
1407
|
+
throw new Error(`senderPrivateKeys length (${senderPrivateKeys.length}) must match receiverAddresses length (${receiverAddresses.length})`);
|
|
1408
|
+
}
|
|
1409
|
+
const pairCount = senderPrivateKeys.length;
|
|
1410
|
+
const normalizedAmounts = (() => {
|
|
1411
|
+
if (amounts && amounts.length > 0) {
|
|
1412
|
+
if (amounts.length !== pairCount) {
|
|
1413
|
+
throw new Error(`amounts length (${amounts.length}) must match pair count (${pairCount})`);
|
|
1414
|
+
}
|
|
1415
|
+
return amounts.map(a => (typeof a === 'bigint' ? a.toString() : String(a)));
|
|
1416
|
+
}
|
|
1417
|
+
if (amount !== undefined && String(amount).trim().length > 0) {
|
|
1418
|
+
const v = typeof amount === 'bigint' ? amount.toString() : String(amount);
|
|
1419
|
+
return new Array(pairCount).fill(v);
|
|
1420
|
+
}
|
|
1421
|
+
throw new Error('Either amount or amounts must be provided');
|
|
1422
|
+
})();
|
|
1423
|
+
const chainIdNum = config.chainId ?? 56;
|
|
1424
|
+
const chainName = chainIdNum === 143 ? 'Monad' : chainIdNum === 56 ? 'BSC' : `Chain-${chainIdNum}`;
|
|
1425
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrl, { chainId: chainIdNum, name: chainName });
|
|
1426
|
+
const txType = getTxType(config);
|
|
1427
|
+
const isNative = _isNativeTokenAddress(tokenAddress);
|
|
1428
|
+
const nonceManager = new NonceManager(provider);
|
|
1429
|
+
// hop 私钥链优先使用传入
|
|
1430
|
+
const providedHops = (() => {
|
|
1431
|
+
if (hopPrivateKeys && hopPrivateKeys.length > 0) {
|
|
1432
|
+
if (hopPrivateKeys.length !== pairCount) {
|
|
1433
|
+
throw new Error(`hopPrivateKeys length (${hopPrivateKeys.length}) must match pair count (${pairCount})`);
|
|
1434
|
+
}
|
|
1435
|
+
return hopPrivateKeys.every(h => h.length === 0) ? null : hopPrivateKeys;
|
|
1436
|
+
}
|
|
1437
|
+
return null;
|
|
1438
|
+
})();
|
|
1439
|
+
const preparedHops = providedHops ?? _generateHopWallets(pairCount, hopCount);
|
|
1440
|
+
const hasHops = preparedHops !== null;
|
|
1441
|
+
const maxHopCount = hasHops ? Math.max(...preparedHops.map(h => h.length)) : 0;
|
|
1442
|
+
const finalGasLimit = _calculateGasLimit(config, isNative, hasHops, maxHopCount);
|
|
1443
|
+
const nativeGasLimit = (config.prefer21000ForNative ?? false) ? 21000n : finalGasLimit;
|
|
1444
|
+
// 与 disperse 保持一致:多跳场景固定 gas limit
|
|
1445
|
+
const nativeTransferGasLimit = 21000n;
|
|
1446
|
+
const erc20TransferGasLimit = 65000n;
|
|
1447
|
+
const [gasPrice, decimals] = await Promise.all([
|
|
1448
|
+
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
1449
|
+
isNative ? Promise.resolve(18) : Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress, chainIdNum))
|
|
1450
|
+
]);
|
|
1451
|
+
const iface = isNative ? null : new ethers.Interface(['function transfer(address,uint256) returns (bool)']);
|
|
1452
|
+
// 利润:按每对金额计算,但由第一个 sender 支付(额外费用)
|
|
1453
|
+
const extractProfit = shouldExtractProfit(config);
|
|
1454
|
+
let totalAmountBeforeProfit = 0n;
|
|
1455
|
+
let totalTokenProfit = 0n;
|
|
1456
|
+
let totalProfitNative = 0n;
|
|
1457
|
+
const parsedAmountsWei = normalizedAmounts.map(v => {
|
|
1458
|
+
const amt = isNative ? ethers.parseEther(v) : ethers.parseUnits(v, decimals);
|
|
1459
|
+
totalAmountBeforeProfit += amt;
|
|
1460
|
+
if (extractProfit && amt > 0n) {
|
|
1461
|
+
const { profit } = calculateProfit(amt, userType);
|
|
1462
|
+
if (isNative)
|
|
1463
|
+
totalProfitNative += profit;
|
|
1464
|
+
else
|
|
1465
|
+
totalTokenProfit += profit;
|
|
1466
|
+
}
|
|
1467
|
+
return amt;
|
|
1468
|
+
});
|
|
1469
|
+
if (!isNative && extractProfit && totalTokenProfit > 0n) {
|
|
1470
|
+
totalProfitNative = await getTokenToNativeQuote(provider, tokenAddress, totalTokenProfit, chainIdNum, tokenPoolType, quoteToken, config.rpcUrl);
|
|
1471
|
+
}
|
|
1472
|
+
// 计算每个 sender 需要的 nonce 数量(聚合到地址)
|
|
1473
|
+
const senderWallets = senderPrivateKeys.map(pk => new Wallet(pk, provider));
|
|
1474
|
+
const senderAddrLowerList = senderWallets.map(w => w.address.toLowerCase());
|
|
1475
|
+
const firstSenderAddrLower = senderAddrLowerList[0];
|
|
1476
|
+
const nonceNeedBySender = new Map();
|
|
1477
|
+
for (let i = 0; i < pairCount; i++) {
|
|
1478
|
+
const addrLower = senderAddrLowerList[i];
|
|
1479
|
+
const hopLen = preparedHops ? preparedHops[i].length : 0;
|
|
1480
|
+
const perPairTxCount = (() => {
|
|
1481
|
+
if (isNative)
|
|
1482
|
+
return 1;
|
|
1483
|
+
return hopLen > 0 ? 2 : 1;
|
|
1484
|
+
})();
|
|
1485
|
+
const cur = nonceNeedBySender.get(addrLower);
|
|
1486
|
+
if (cur)
|
|
1487
|
+
cur.count += perPairTxCount;
|
|
1488
|
+
else
|
|
1489
|
+
nonceNeedBySender.set(addrLower, { wallet: senderWallets[i], count: perPairTxCount });
|
|
1490
|
+
}
|
|
1491
|
+
if (extractProfit && totalProfitNative > 0n) {
|
|
1492
|
+
const cur = nonceNeedBySender.get(firstSenderAddrLower);
|
|
1493
|
+
if (cur)
|
|
1494
|
+
cur.count += 1;
|
|
1495
|
+
}
|
|
1496
|
+
const nonceQueueBySender = new Map();
|
|
1497
|
+
for (const [addrLower, entry] of nonceNeedBySender.entries()) {
|
|
1498
|
+
const count = entry.count;
|
|
1499
|
+
const nonces = (addrLower === firstSenderAddrLower && startNonce !== undefined)
|
|
1500
|
+
? Array.from({ length: count }, (_, i) => startNonce + i)
|
|
1501
|
+
: await nonceManager.getNextNonceBatch(entry.wallet, count);
|
|
1502
|
+
nonceQueueBySender.set(addrLower, nonces);
|
|
1503
|
+
}
|
|
1504
|
+
const popNonce = (addrLower) => {
|
|
1505
|
+
const q = nonceQueueBySender.get(addrLower);
|
|
1506
|
+
if (!q || q.length === 0)
|
|
1507
|
+
throw new Error(`nonce queue empty for sender ${addrLower}`);
|
|
1508
|
+
return q.shift();
|
|
1509
|
+
};
|
|
1510
|
+
const txsToSign = [];
|
|
1511
|
+
const nativeHopGasFee = nativeTransferGasLimit * gasPrice;
|
|
1512
|
+
const erc20HopGasFee = erc20TransferGasLimit * gasPrice;
|
|
1513
|
+
const nativeHopGasFeeForErc20 = nativeTransferGasLimit * gasPrice;
|
|
1514
|
+
for (let i = 0; i < pairCount; i++) {
|
|
1515
|
+
const senderWallet = senderWallets[i];
|
|
1516
|
+
const senderLower = senderAddrLowerList[i];
|
|
1517
|
+
const to = receiverAddresses[i];
|
|
1518
|
+
const amtWei = parsedAmountsWei[i];
|
|
1519
|
+
const hopChain = preparedHops ? preparedHops[i] : [];
|
|
1520
|
+
if (!hopChain || hopChain.length === 0) {
|
|
1521
|
+
const nonce = popNonce(senderLower);
|
|
1522
|
+
if (isNative) {
|
|
1523
|
+
txsToSign.push({
|
|
1524
|
+
wallet: senderWallet,
|
|
1525
|
+
tx: { to, value: amtWei, nonce, gasPrice, gasLimit: nativeGasLimit, chainId: chainIdNum, type: txType }
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
else {
|
|
1529
|
+
const data = iface.encodeFunctionData('transfer', [to, amtWei]);
|
|
1530
|
+
txsToSign.push({
|
|
1531
|
+
wallet: senderWallet,
|
|
1532
|
+
tx: { to: tokenAddress, data, value: 0n, nonce, gasPrice, gasLimit: finalGasLimit, chainId: chainIdNum, type: txType }
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
continue;
|
|
1536
|
+
}
|
|
1537
|
+
const fullChain = [senderWallet, ...hopChain.map(w => new Wallet(typeof w === 'string' ? w : w.privateKey, provider))];
|
|
1538
|
+
const addresses = [...fullChain.map(w => w.address), to];
|
|
1539
|
+
if (isNative) {
|
|
1540
|
+
for (let j = 0; j < addresses.length - 1; j++) {
|
|
1541
|
+
const fromWallet = fullChain[j];
|
|
1542
|
+
const toAddress = addresses[j + 1];
|
|
1543
|
+
const nonce = j === 0 ? popNonce(senderLower) : 0;
|
|
1544
|
+
const remainingHops = addresses.length - 2 - j;
|
|
1545
|
+
const additionalGas = nativeHopGasFee * BigInt(remainingHops);
|
|
1546
|
+
const transferValue = amtWei + additionalGas;
|
|
1547
|
+
txsToSign.push({
|
|
1548
|
+
wallet: fromWallet,
|
|
1549
|
+
tx: { to: toAddress, value: transferValue, nonce, gasPrice, gasLimit: nativeTransferGasLimit, chainId: chainIdNum, type: txType }
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
else {
|
|
1554
|
+
// ERC20 多跳:gas + ERC20 逐层传递(与 disperse 一致)
|
|
1555
|
+
const hopGasNeeds = [];
|
|
1556
|
+
for (let j = hopChain.length - 1; j >= 0; j--) {
|
|
1557
|
+
if (j === hopChain.length - 1)
|
|
1558
|
+
hopGasNeeds.unshift(erc20HopGasFee);
|
|
1559
|
+
else {
|
|
1560
|
+
const nextHopGas = hopGasNeeds[0];
|
|
1561
|
+
hopGasNeeds.unshift(nativeHopGasFeeForErc20 + erc20HopGasFee + nextHopGas);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
// sender -> firstHop:转 gas
|
|
1565
|
+
txsToSign.push({
|
|
1566
|
+
wallet: senderWallet,
|
|
1567
|
+
tx: {
|
|
1568
|
+
to: fullChain[1].address,
|
|
1569
|
+
value: hopGasNeeds[0],
|
|
1570
|
+
nonce: popNonce(senderLower),
|
|
1571
|
+
gasPrice,
|
|
1572
|
+
gasLimit: nativeTransferGasLimit,
|
|
1573
|
+
chainId: chainIdNum,
|
|
1574
|
+
type: txType
|
|
1575
|
+
}
|
|
1576
|
+
});
|
|
1577
|
+
// sender -> firstHop:转 ERC20
|
|
1578
|
+
const mainToFirstHopData = iface.encodeFunctionData('transfer', [fullChain[1].address, amtWei]);
|
|
1579
|
+
txsToSign.push({
|
|
1580
|
+
wallet: senderWallet,
|
|
1581
|
+
tx: {
|
|
1582
|
+
to: tokenAddress,
|
|
1583
|
+
data: mainToFirstHopData,
|
|
1584
|
+
value: 0n,
|
|
1585
|
+
nonce: popNonce(senderLower),
|
|
1586
|
+
gasPrice,
|
|
1587
|
+
gasLimit: erc20TransferGasLimit,
|
|
1588
|
+
chainId: chainIdNum,
|
|
1589
|
+
type: txType
|
|
1590
|
+
}
|
|
1591
|
+
});
|
|
1592
|
+
// hop wallets:逐层传递
|
|
1593
|
+
for (let j = 1; j < fullChain.length; j++) {
|
|
1594
|
+
const fromWallet = fullChain[j];
|
|
1595
|
+
const toAddress = addresses[j + 1];
|
|
1596
|
+
const isLastHop = j === fullChain.length - 1;
|
|
1597
|
+
if (!isLastHop) {
|
|
1598
|
+
const gasToTransfer = hopGasNeeds[j];
|
|
1599
|
+
txsToSign.push({
|
|
1600
|
+
wallet: fromWallet,
|
|
1601
|
+
tx: {
|
|
1602
|
+
to: toAddress,
|
|
1603
|
+
value: gasToTransfer,
|
|
1604
|
+
nonce: 0,
|
|
1605
|
+
gasPrice,
|
|
1606
|
+
gasLimit: nativeTransferGasLimit,
|
|
1607
|
+
chainId: chainIdNum,
|
|
1608
|
+
type: txType
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1611
|
+
const erc20Data = iface.encodeFunctionData('transfer', [toAddress, amtWei]);
|
|
1612
|
+
txsToSign.push({
|
|
1613
|
+
wallet: fromWallet,
|
|
1614
|
+
tx: {
|
|
1615
|
+
to: tokenAddress,
|
|
1616
|
+
data: erc20Data,
|
|
1617
|
+
value: 0n,
|
|
1618
|
+
nonce: 1,
|
|
1619
|
+
gasPrice,
|
|
1620
|
+
gasLimit: erc20TransferGasLimit,
|
|
1621
|
+
chainId: chainIdNum,
|
|
1622
|
+
type: txType
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
else {
|
|
1627
|
+
const erc20Data = iface.encodeFunctionData('transfer', [toAddress, amtWei]);
|
|
1628
|
+
txsToSign.push({
|
|
1629
|
+
wallet: fromWallet,
|
|
1630
|
+
tx: {
|
|
1631
|
+
to: tokenAddress,
|
|
1632
|
+
data: erc20Data,
|
|
1633
|
+
value: 0n,
|
|
1634
|
+
nonce: 0,
|
|
1635
|
+
gasPrice,
|
|
1636
|
+
gasLimit: erc20TransferGasLimit,
|
|
1637
|
+
chainId: chainIdNum,
|
|
1638
|
+
type: txType
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
const signedTxs = await Promise.all(txsToSign.map(({ wallet, tx }) => wallet.signTransaction(tx)));
|
|
1646
|
+
// 利润多跳(固定 2 hop)
|
|
1647
|
+
let profitHopWallets;
|
|
1648
|
+
if (extractProfit && totalProfitNative > 0n) {
|
|
1649
|
+
const firstSenderWallet = senderWallets[0];
|
|
1650
|
+
const profitNonce = popNonce(firstSenderAddrLower);
|
|
1651
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
1652
|
+
provider,
|
|
1653
|
+
payerWallet: firstSenderWallet,
|
|
1654
|
+
profitAmount: totalProfitNative,
|
|
1655
|
+
profitRecipient: getProfitRecipient(),
|
|
1656
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
1657
|
+
gasPrice,
|
|
1658
|
+
chainId: chainIdNum,
|
|
1659
|
+
txType,
|
|
1660
|
+
startNonce: profitNonce
|
|
1661
|
+
});
|
|
1662
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
1663
|
+
profitHopWallets = profitHopResult.hopWallets;
|
|
1664
|
+
}
|
|
1665
|
+
return {
|
|
1666
|
+
signedTransactions: signedTxs,
|
|
1667
|
+
hopWallets: preparedHops || undefined,
|
|
1668
|
+
profitHopWallets,
|
|
1669
|
+
metadata: extractProfit ? {
|
|
1670
|
+
pairCount,
|
|
1671
|
+
isNative,
|
|
1672
|
+
tokenAddress: isNative ? undefined : tokenAddress,
|
|
1673
|
+
totalAmount: isNative ? ethers.formatEther(totalAmountBeforeProfit) : ethers.formatUnits(totalAmountBeforeProfit, decimals),
|
|
1674
|
+
profitAmount: ethers.formatEther(totalProfitNative),
|
|
1675
|
+
profitRecipient: getProfitRecipient(),
|
|
1676
|
+
} : undefined
|
|
1677
|
+
};
|
|
1678
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export { createTokenWithBundleBuy as flapCreateTokenWithBundleBuy, batchBuyWithB
|
|
|
28
28
|
export { fourPrivateBuy, fourPrivateSell, fourBatchPrivateBuy, fourBatchPrivateSell, type FourPrivateBuyParams, type FourPrivateSellParams, type FourBatchPrivateBuyParams, type FourBatchPrivateSellParams } from './contracts/tm-bundle.js';
|
|
29
29
|
export { flapPrivateBuy, flapPrivateSell, flapBatchPrivateBuy, flapBatchPrivateSell, type FlapPrivateBuyParams, type FlapPrivateSellParams, type FlapBatchPrivateBuyParams, type FlapBatchPrivateSellParams, type FlapBatchPrivateSellResult } from './flap/portal-bundle.js';
|
|
30
30
|
export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle, flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle, pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch, flapDisperseWithBundleMerkle, flapSweepWithBundleMerkle, type FlapBundleMerkleConfig, type FlapSignConfig, type FlapChainForMerkleBundle, type FlapCreateWithBundleBuySignParams, type FlapCreateWithBundleBuyMerkleParams, type FlapCreateWithBundleBuyMerkleResult, type FlapBatchBuySignParams, type FlapBatchBuyMerkleParams, type FlapBatchBuyMerkleResult, type FlapBatchSellSignParams, type FlapBatchSellMerkleParams, type FlapBatchSellMerkleResult, type MerkleTransactionStatus, type MerkleBundleStatus, type FlapPrivateBuyMerkleParams, type FlapPrivateSellMerkleParams, type FlapBatchPrivateBuyMerkleParams, type FlapBatchPrivateSellMerkleParams, type FlapBatchPrivateMerkleResult, type FlapPrivateTransactionResult, type PancakeProxyBatchBuyParams, type PancakeProxyBatchBuyResult, type PancakeProxyBatchSellParams, type PancakeProxyBatchSellResult, type PancakeProxyApprovalParams, type PancakeProxyApprovalBatchParams, type PancakeProxyApprovalBatchResult, type FlapDisperseSignParams, type FlapDisperseMerkleResult, type FlapSweepSignParams, type FlapSweepMerkleResult } from './flap/portal-bundle-merkle/index.js';
|
|
31
|
-
export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, submitBundleToBlockRazor, submitMultipleBundlesToBlockRazor, submitMultipleBundlesToBlockRazorParallel, type MerkleSubmitConfig, type SubmitBundleResult, type BlockRazorSubmitConfig, type BlockRazorSubmitResult, type FourBundleMerkleConfig, type FourSignConfig, type FourCreateWithBundleBuySignParams, type FourBatchBuySignParams, type FourBatchSellSignParams, type FourPrivateBuySignParams, type FourPrivateSellSignParams, type FourBatchPrivateBuySignParams, type FourBatchPrivateSellSignParams, type FourPancakeProxyBatchBuySignParams, type FourPancakeProxyBatchSellSignParams, type DisperseSignParams as FourDisperseSignParams, type SweepSignParams as FourSweepSignParams, type FourCreateWithBundleBuyMerkleParams, type FourCreateWithBundleBuyMerkleResult, type FourBatchBuyMerkleParams, type FourBatchBuyMerkleResult, type FourBatchSellMerkleParams, type FourBatchSellMerkleResult, type FourPrivateBuyMerkleParams, type FourPrivateSellMerkleParams, type FourBatchPrivateBuyMerkleParams, type FourBatchPrivateSellMerkleParams, type FourBatchPrivateMerkleResult, type FourPrivateTransactionResult, type DisperseMerkleParams, type DisperseMerkleResult, type SweepMerkleParams, type SweepMerkleResult, type FourPancakeProxyBatchBuyParams, type FourPancakeProxyBatchBuyResult, type FourPancakeProxyBatchSellParams, type FourPancakeProxyBatchSellResult, type FourPancakeProxyApprovalParams, type FourPancakeProxyApprovalBatchParams, type FourPancakeProxyApprovalBatchResult, type ApproveFourTokenManagerBatchParams, type ApproveFourTokenManagerBatchResult } from './contracts/tm-bundle-merkle/index.js';
|
|
31
|
+
export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, pairwiseTransferWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, submitBundleToBlockRazor, submitMultipleBundlesToBlockRazor, submitMultipleBundlesToBlockRazorParallel, type MerkleSubmitConfig, type SubmitBundleResult, type BlockRazorSubmitConfig, type BlockRazorSubmitResult, type FourBundleMerkleConfig, type FourSignConfig, type FourCreateWithBundleBuySignParams, type FourBatchBuySignParams, type FourBatchSellSignParams, type FourPrivateBuySignParams, type FourPrivateSellSignParams, type FourBatchPrivateBuySignParams, type FourBatchPrivateSellSignParams, type FourPancakeProxyBatchBuySignParams, type FourPancakeProxyBatchSellSignParams, type DisperseSignParams as FourDisperseSignParams, type SweepSignParams as FourSweepSignParams, type FourCreateWithBundleBuyMerkleParams, type FourCreateWithBundleBuyMerkleResult, type FourBatchBuyMerkleParams, type FourBatchBuyMerkleResult, type FourBatchSellMerkleParams, type FourBatchSellMerkleResult, type FourPrivateBuyMerkleParams, type FourPrivateSellMerkleParams, type FourBatchPrivateBuyMerkleParams, type FourBatchPrivateSellMerkleParams, type FourBatchPrivateMerkleResult, type FourPrivateTransactionResult, type DisperseMerkleParams, type DisperseMerkleResult, type SweepMerkleParams, type SweepMerkleResult, type FourPancakeProxyBatchBuyParams, type FourPancakeProxyBatchBuyResult, type FourPancakeProxyBatchSellParams, type FourPancakeProxyBatchSellResult, type FourPancakeProxyApprovalParams, type FourPancakeProxyApprovalBatchParams, type FourPancakeProxyApprovalBatchResult, type ApproveFourTokenManagerBatchParams, type ApproveFourTokenManagerBatchResult } from './contracts/tm-bundle-merkle/index.js';
|
|
32
32
|
export { PinataClient, type PinataConfig } from './flap/pinata.js';
|
|
33
33
|
export { pinFileToIPFSWithJWT, pinImageByPath, pinFileToIPFSWithJWTWeb, pinDataURLWithJWTWeb, dataURLToBlob, type PinataPinResp } from './flap/pinata.js';
|
|
34
34
|
export { generateWallets, type GeneratedWallet } from './utils/wallet.js';
|
package/dist/index.js
CHANGED
|
@@ -47,7 +47,7 @@ export { createTokenWithBundleBuy as flapCreateTokenWithBundleBuy, batchBuyWithB
|
|
|
47
47
|
export { fourPrivateBuy, fourPrivateSell, fourBatchPrivateBuy, fourBatchPrivateSell } from './contracts/tm-bundle.js';
|
|
48
48
|
export { flapPrivateBuy, flapPrivateSell, flapBatchPrivateBuy, flapBatchPrivateSell } from './flap/portal-bundle.js';
|
|
49
49
|
export { createTokenWithBundleBuyMerkle as flapCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as flapBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as flapBatchSellWithBundleMerkle, flapPrivateBuyMerkle, flapPrivateSellMerkle, flapBatchPrivateBuyMerkle, flapBatchPrivateSellMerkle, pancakeProxyBatchBuyMerkle, pancakeProxyBatchSellMerkle, approvePancakeProxy, approvePancakeProxyBatch, flapDisperseWithBundleMerkle, flapSweepWithBundleMerkle } from './flap/portal-bundle-merkle/index.js';
|
|
50
|
-
export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, submitBundleToBlockRazor, submitMultipleBundlesToBlockRazor, submitMultipleBundlesToBlockRazorParallel } from './contracts/tm-bundle-merkle/index.js';
|
|
50
|
+
export { createTokenWithBundleBuyMerkle as fourCreateTokenWithBundleBuyMerkle, batchBuyWithBundleMerkle as fourBatchBuyWithBundleMerkle, batchSellWithBundleMerkle as fourBatchSellWithBundleMerkle, fourPrivateBuyMerkle, fourPrivateSellMerkle, fourBatchPrivateBuyMerkle, fourBatchPrivateSellMerkle, disperseWithBundleMerkle, sweepWithBundleMerkle, pairwiseTransferWithBundleMerkle, fourPancakeProxyBatchBuyMerkle, fourPancakeProxyBatchSellMerkle, approveFourPancakeProxy, approveFourPancakeProxyBatch, approveFourTokenManagerBatch, submitBundleToMerkle, submitMultipleBundles, submitMultipleBundlesParallel, submitBundleToBlockRazor, submitMultipleBundlesToBlockRazor, submitMultipleBundlesToBlockRazorParallel } from './contracts/tm-bundle-merkle/index.js';
|
|
51
51
|
export { PinataClient } from './flap/pinata.js';
|
|
52
52
|
export { pinFileToIPFSWithJWT, pinImageByPath, pinFileToIPFSWithJWTWeb, pinDataURLWithJWTWeb, dataURLToBlob } from './flap/pinata.js';
|
|
53
53
|
export { generateWallets } from './utils/wallet.js';
|