UNPKG

four-flap-meme-sdk

Version:

SDK for Flap bonding curve and four.meme TokenManager

169 lines (168 loc) 6.67 kB
/** * 私募转账签名工具 * * ✅ 优化:能批量的批量,能并行的并行 * - 贿赂交易:向 BlockRazor Builder EOA 转账 BNB 提高优先级 * - 利润提取:千分之三(30 bps) */ import { ethers, Wallet, JsonRpcProvider } from 'ethers'; import { PROFIT_CONFIG, BLOCKRAZOR_BUILDER_EOA } from './constants.js'; import { NonceManager, buildProfitHopTransactions, PROFIT_HOP_COUNT } from './bundle-helpers.js'; // ============================================================================ // 核心功能 // ============================================================================ /** * 生成私募转账签名交易(带贿赂和利润提取) * * ✅ 优化: * 1. 批量获取 nonce(单次 RPC 请求) * 2. 并行签名所有交易(贿赂 + 转账 + 利润) * 3. 批量创建钱包实例 * * 交易顺序: * 1. 贿赂交易(第一个发送者 → BlockRazor) * 2. 转账交易(各发送者 → 合约) * 3. 利润交易(第一个发送者 → 利润地址) * * @param params 批量转账参数 * @returns 签名交易结果 */ export async function batchPrivateSaleMerkle(params) { const { transfers, config } = params; if (transfers.length === 0) { throw new Error('转账列表不能为空'); } // ✅ 配置参数(提前计算,避免重复) const chainId = config.chainId || 56; const gasLimit = BigInt(config.gasLimit || 21000); const gasPrice = ethers.parseUnits(String(config.gasPriceGwei || 0.1), 'gwei'); const bribeAmount = ethers.parseEther(String(config.bribeAmount || 0.000001)); const extractProfit = config.extractProfit !== false; const profitBps = config.profitBps ?? PROFIT_CONFIG.RATE_BPS; // 创建 Provider const provider = new JsonRpcProvider(config.rpcUrl); const nonceManager = new NonceManager(provider); // ✅ 批量创建钱包实例(使用 Map 去重) const walletMap = new Map(); const transferWallets = []; for (const transfer of transfers) { const key = new Wallet(transfer.senderPrivateKey).address.toLowerCase(); if (!walletMap.has(key)) { const wallet = new Wallet(transfer.senderPrivateKey, provider); walletMap.set(key, wallet); } transferWallets.push(walletMap.get(key)); } // 第一个发送者(负责贿赂和利润交易) const firstWallet = transferWallets[0]; const firstWalletKey = firstWallet.address.toLowerCase(); // ✅ 批量计算总金额(使用 reduce) const totalAmountWei = transfers.reduce((sum, t) => sum + ethers.parseEther(String(t.amount)), 0n); const profitWei = extractProfit ? (totalAmountWei * BigInt(profitBps)) / 10000n : 0n; const hasProfit = extractProfit && profitWei > 0n; // ✅ 批量获取所有 nonce(单次 RPC 请求) const uniqueWallets = Array.from(walletMap.values()); const noncesArray = await nonceManager.getNextNoncesForWallets(uniqueWallets); // 构建 nonce 映射 const nonceMap = new Map(); uniqueWallets.forEach((wallet, i) => { nonceMap.set(wallet.address.toLowerCase(), noncesArray[i]); }); // ✅ 预计算每个钱包的 nonce 分配 // 第一个钱包:baseNonce(贿赂) → baseNonce+1...+N(转账) → 最后(利润) const firstWalletBaseNonce = nonceMap.get(firstWalletKey); // 统计第一个钱包的转账数量 let firstWalletTransferCount = 0; for (let i = 0; i < transfers.length; i++) { if (transferWallets[i].address.toLowerCase() === firstWalletKey) { firstWalletTransferCount++; } } // ✅ 为每个转账预分配 nonce const transferNonces = []; const currentNonces = new Map(); // 初始化 nonce(第一个钱包跳过贿赂交易的 nonce) for (const [key, nonce] of nonceMap) { currentNonces.set(key, key === firstWalletKey ? nonce + 1 : nonce); } // 为每个转账分配 nonce for (let i = 0; i < transfers.length; i++) { const walletKey = transferWallets[i].address.toLowerCase(); const nonce = currentNonces.get(walletKey); transferNonces.push(nonce); currentNonces.set(walletKey, nonce + 1); } // 利润交易的 nonce const profitNonce = hasProfit ? currentNonces.get(firstWalletKey) : 0; // ✅ 签名交易数组 const signedTransactions = []; // 1. 贿赂交易签名 const bribeTx = await firstWallet.signTransaction({ to: BLOCKRAZOR_BUILDER_EOA, value: bribeAmount, gasLimit, gasPrice, nonce: firstWalletBaseNonce, chainId, type: 0, }); signedTransactions.push(bribeTx); // 2. 转账交易签名(并行) const transferPromises = []; for (let i = 0; i < transfers.length; i++) { const transfer = transfers[i]; const wallet = transferWallets[i]; const nonce = transferNonces[i]; transferPromises.push(wallet.signTransaction({ to: transfer.recipient, value: ethers.parseEther(String(transfer.amount)), gasLimit, gasPrice, nonce, chainId, type: 0, })); } const transferTxs = await Promise.all(transferPromises); signedTransactions.push(...transferTxs); // 3. 利润多跳转账(强制 2 跳中转) if (hasProfit) { const profitHopResult = await buildProfitHopTransactions({ provider, payerWallet: firstWallet, profitAmount: profitWei, profitRecipient: PROFIT_CONFIG.RECIPIENT, hopCount: PROFIT_HOP_COUNT, gasPrice, chainId, txType: 0, startNonce: profitNonce }); signedTransactions.push(...profitHopResult.signedTransactions); } return { signedTransactions, metadata: { totalCount: signedTransactions.length, bribeCount: 1, transferCount: transfers.length, profitCount: hasProfit ? PROFIT_HOP_COUNT + 1 : 0, // ✅ 支付者 1 笔 + 中转钱包 N 笔 totalAmountWei: totalAmountWei.toString(), totalProfitWei: profitWei.toString(), bribeAmountWei: bribeAmount.toString(), }, }; } /** * 生成单笔私募转账签名交易(带贿赂和利润提取) * * @param transfer 转账参数 * @param config 签名配置 * @returns 签名交易结果 */ export async function privateSaleMerkle(transfer, config) { return batchPrivateSaleMerkle({ transfers: [transfer], config, }); }