four-flap-meme-sdk 1.2.76 → 1.2.78

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.
@@ -225,17 +225,12 @@ export async function batchBuyWithBundleMerkle(params) {
225
225
  throw new Error(getErrorMessage('KEY_AMOUNT_MISMATCH'));
226
226
  }
227
227
  const { provider, chainId } = createChainContext(config.rpcUrl);
228
- const buyers = createWallets(privateKeys, provider);
229
228
  const txType = getTxType(config);
230
- // 优化:并行执行 gasPrice 获取和 nonce 预加载
231
- const [gasPrice, nonceManager] = await Promise.all([
232
- getOptimizedGasPrice(provider, getGasPriceConfig(config)),
233
- (async () => {
234
- const nm = new NonceManager(provider);
235
- // 预加载所有钱包的 nonce(批量查询)
236
- await Promise.all(buyers.map(w => nm.getNextNonce(w)));
237
- return nm;
238
- })()
229
+ const buyers = createWallets(privateKeys, provider);
230
+ // 优化:并行初始化 nonceManager 和获取 gasPrice
231
+ const [nonceManager, gasPrice] = await Promise.all([
232
+ Promise.resolve(new NonceManager(provider)),
233
+ getOptimizedGasPrice(provider, getGasPriceConfig(config))
239
234
  ]);
240
235
  const buyFlow = await executeBuyFlow({
241
236
  wallets: buyers,
@@ -261,17 +256,12 @@ export async function batchSellWithBundleMerkle(params) {
261
256
  throw new Error(getErrorMessage('SELL_KEY_AMOUNT_MISMATCH'));
262
257
  }
263
258
  const { provider, chainId } = createChainContext(config.rpcUrl);
264
- const sellers = createWallets(privateKeys, provider);
265
259
  const txType = getTxType(config);
266
- // 优化:并行执行 gasPrice 获取和 nonce 预加载
267
- const [gasPrice, nonceManager] = await Promise.all([
268
- getOptimizedGasPrice(provider, getGasPriceConfig(config)),
269
- (async () => {
270
- const nm = new NonceManager(provider);
271
- // 预加载所有钱包的 nonce(批量查询)
272
- await Promise.all(sellers.map(w => nm.getNextNonce(w)));
273
- return nm;
274
- })()
260
+ const sellers = createWallets(privateKeys, provider);
261
+ // 优化:并行初始化 nonceManager 和获取 gasPrice
262
+ const [nonceManager, gasPrice] = await Promise.all([
263
+ Promise.resolve(new NonceManager(provider)),
264
+ getOptimizedGasPrice(provider, getGasPriceConfig(config))
275
265
  ]);
276
266
  const sellFlow = await executeSellFlow({
277
267
  wallets: sellers,
@@ -128,21 +128,16 @@ export async function batchBuyWithBundleMerkle(params) {
128
128
  throw new Error(getErrorMessage('KEY_AMOUNT_MISMATCH'));
129
129
  }
130
130
  const { provider, chainId } = createChainContext(chain, config.rpcUrl);
131
+ const nonceManager = new NonceManager(provider);
132
+ const signedTxs = [];
131
133
  const buyers = createWallets(privateKeys, provider);
132
134
  const extractProfit = shouldExtractProfit(config);
133
135
  const { fundsList, originalAmounts, totalBuyAmount, totalProfit } = analyzeBuyFunds(buyAmounts, config, extractProfit);
134
136
  const maxFundsIndex = findMaxIndex(originalAmounts);
135
137
  const gasLimits = buildGasLimitList(buyers.length, config);
136
- const signedTxs = [];
137
- // ✅ 优化:并行执行所有 RPC 调用(gasPrice + nonces + populateTransaction)
138
- const [gasPrice, nonceManager, unsignedBuys] = await Promise.all([
138
+ // 优化:并行执行 gasPrice 和 populateBuyTransactions(最耗时的两个操作)
139
+ const [gasPrice, unsignedBuys] = await Promise.all([
139
140
  resolveGasPrice(provider, config),
140
- (async () => {
141
- const nm = new NonceManager(provider);
142
- // 预加载所有钱包的 nonce(批量查询)
143
- await Promise.all(buyers.map(w => nm.getNextNonce(w)));
144
- return nm;
145
- })(),
146
141
  populateBuyTransactions(buyers, FLAP_PORTAL_ADDRESSES[chain], tokenAddress, fundsList)
147
142
  ]);
148
143
  const buyerNonces = await allocateBuyerNonces(buyers, extractProfit, maxFundsIndex, totalProfit, nonceManager);
@@ -184,35 +179,28 @@ export async function batchSellWithBundleMerkle(params) {
184
179
  throw new Error(getErrorMessage('SELL_KEY_AMOUNT_MISMATCH'));
185
180
  }
186
181
  const { provider, chainId } = createChainContext(chain, config.rpcUrl);
182
+ const nonceManager = new NonceManager(provider);
183
+ const signedTxs = [];
187
184
  const wallets = createWallets(privateKeys, provider);
188
185
  const amountsWei = sellAmounts.map(a => ethers.parseUnits(a, 18));
189
186
  const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
190
187
  const readOnlyPortal = new ethers.Contract(portalAddr, PORTAL_ABI, provider);
191
188
  const gasLimits = buildGasLimitList(wallets.length, config);
192
- const signedTxs = [];
193
- // ✅ 优化:并行执行所有 RPC 调用(gasPrice + nonces + quotes)
194
- const [gasPrice, nonceManager, quotedOutputs] = await Promise.all([
189
+ // 优化:并行执行 gasPrice 和 quoteSellOutputs(最耗时的两个操作)
190
+ const [gasPrice, quotedOutputs] = await Promise.all([
195
191
  resolveGasPrice(provider, config),
196
- (async () => {
197
- const nm = new NonceManager(provider);
198
- // 预加载所有钱包的 nonce(批量查询)
199
- await Promise.all(wallets.map(w => nm.getNextNonce(w)));
200
- return nm;
201
- })(),
202
192
  quoteSellOutputs(readOnlyPortal, tokenAddress, amountsWei)
203
193
  ]);
204
194
  const minOuts = resolveMinOutputs(minOutputAmounts, wallets.length, quotedOutputs);
205
- // 优化:使用单个 portal 实例生成所有 populateTransaction(避免重复创建合约实例)
206
- const unsignedList = await Promise.all(wallets.map((_, i) => readOnlyPortal.swapExactInput.populateTransaction({
195
+ const portals = wallets.map(w => new ethers.Contract(portalAddr, PORTAL_ABI, w));
196
+ const unsignedList = await Promise.all(portals.map((portal, i) => portal.swapExactInput.populateTransaction({
207
197
  inputToken: tokenAddress,
208
198
  outputToken: ZERO_ADDRESS,
209
199
  inputAmount: amountsWei[i],
210
200
  minOutputAmount: minOuts[i],
211
201
  permitData: '0x'
212
202
  })));
213
- // ✅ 优化:批量获取 nonces(已预加载,直接从缓存读取)
214
203
  const nonces = await Promise.all(wallets.map(w => nonceManager.getNextNonce(w)));
215
- // ✅ 优化:批量签名交易
216
204
  const signedList = await Promise.all(unsignedList.map((unsigned, i) => wallets[i].signTransaction({
217
205
  ...unsigned,
218
206
  from: wallets[i].address,
@@ -288,15 +276,14 @@ function findMaxIndex(values) {
288
276
  return maxIndex;
289
277
  }
290
278
  async function populateBuyTransactions(buyers, portalAddr, tokenAddress, fundsList) {
291
- // 优化:使用单个合约实例(避免重复创建)
292
- const portal = new ethers.Contract(portalAddr, PORTAL_ABI, buyers[0]);
293
- return await Promise.all(fundsList.map((funds) => portal.swapExactInput.populateTransaction({
279
+ const portals = buyers.map(wallet => new ethers.Contract(portalAddr, PORTAL_ABI, wallet));
280
+ return await Promise.all(portals.map((portal, i) => portal.swapExactInput.populateTransaction({
294
281
  inputToken: ZERO_ADDRESS,
295
282
  outputToken: tokenAddress,
296
- inputAmount: funds,
283
+ inputAmount: fundsList[i],
297
284
  minOutputAmount: 0n,
298
285
  permitData: '0x'
299
- }, { value: funds })));
286
+ }, { value: fundsList[i] })));
300
287
  }
301
288
  function buildGasLimitList(length, config) {
302
289
  const gasLimit = getGasLimit(config);
@@ -502,51 +502,56 @@ export async function approveTokenBatchRaw(params) {
502
502
  // 验证地址
503
503
  await validateContractAddress(provider, normalizedToken, 'Token');
504
504
  await validateContractAddress(provider, normalizedSpender, 'Spender');
505
- const results = [];
506
- let approvedCount = 0;
507
- let errorCount = 0;
508
- for (let i = 0; i < privateKeys.length; i++) {
509
- const signer = new Wallet(privateKeys[i], provider);
510
- const ownerAddress = signer.address;
511
- const requiredAmount = amounts[i] === 'max'
512
- ? BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
513
- : amounts[i];
505
+ // 优化:批量创建钱包和合约实例
506
+ const wallets = privateKeys.map(key => new Wallet(key, provider));
507
+ const ownerAddresses = wallets.map(w => w.address);
508
+ const requiredAmounts = amounts.map(amount => amount === 'max'
509
+ ? BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
510
+ : amount);
511
+ // 优化:并行检查所有钱包的授权额度
512
+ const currentAllowances = await batchCheckAllowances(provider, normalizedToken, ownerAddresses, normalizedSpender);
513
+ // ✅ 优化:并行发送所有需要授权的交易
514
+ const approvalPromises = wallets.map(async (wallet, i) => {
515
+ const ownerAddress = ownerAddresses[i];
516
+ const currentAllowance = currentAllowances[i];
517
+ const requiredAmount = requiredAmounts[i];
514
518
  try {
515
- const erc20 = new Contract(normalizedToken, ERC20_ABI, signer);
516
- // 检查当前授权
517
- const currentAllowance = await erc20.allowance(ownerAddress, normalizedSpender);
519
+ // 如果已经授权足够,跳过
518
520
  if (currentAllowance >= requiredAmount) {
519
- results.push({
521
+ return {
520
522
  owner: ownerAddress,
521
523
  alreadyApproved: true,
522
524
  currentAllowance,
523
525
  requiredAllowance: requiredAmount
524
- });
525
- continue;
526
+ };
526
527
  }
527
528
  // 发送授权交易
529
+ const erc20 = new Contract(normalizedToken, ERC20_ABI, wallet);
528
530
  const tx = await erc20.approve(normalizedSpender, requiredAmount);
529
531
  const receipt = await tx.wait();
530
- results.push({
532
+ return {
531
533
  owner: ownerAddress,
532
534
  alreadyApproved: false,
533
535
  currentAllowance,
534
536
  requiredAllowance: requiredAmount,
535
537
  txHash: receipt.hash
536
- });
537
- approvedCount++;
538
+ };
538
539
  }
539
540
  catch (error) {
540
- results.push({
541
+ return {
541
542
  owner: ownerAddress,
542
543
  alreadyApproved: false,
543
- currentAllowance: 0n,
544
+ currentAllowance,
544
545
  requiredAllowance: requiredAmount,
545
546
  error: error.message
546
- });
547
- errorCount++;
547
+ };
548
548
  }
549
- }
549
+ });
550
+ // ✅ 优化:并行等待所有授权交易完成
551
+ const results = await Promise.all(approvalPromises);
552
+ // 统计结果
553
+ const approvedCount = results.filter(r => !r.alreadyApproved && !r.error).length;
554
+ const errorCount = results.filter(r => r.error).length;
550
555
  // ✅ 只要没有错误,就算成功(包括所有钱包都已授权的情况)
551
556
  return {
552
557
  success: errorCount === 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.2.76",
3
+ "version": "1.2.78",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",