four-flap-meme-sdk 1.1.98 → 1.1.99

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.
@@ -229,6 +229,16 @@ export async function fourBatchPrivateSellMerkle(params) {
229
229
  if (privateKeys.length !== amounts.length) {
230
230
  throw new Error('privateKeys and amounts length mismatch');
231
231
  }
232
+ // ⚠️ 友好提示:利润提取需要 minFundsEach
233
+ if (!minFundsEach && shouldExtractProfit(config)) {
234
+ console.log('\n⚠️ 重要提示:未传入 minFundsEach 参数,将无法提取利润!');
235
+ console.log(' Four.meme 内盘代币无法自动报价,需要手动估算预期收益');
236
+ console.log(' 建议步骤:');
237
+ console.log(' 1. 在 four.meme 网站查看卖出预期收益');
238
+ console.log(' 2. 传入 minFundsEach 参数');
239
+ console.log(' 示例: minFundsEach: 0.1 (预计每个钱包收到 0.1 BNB)');
240
+ console.log(' 如果只是测试卖出,可以忽略此提示\n');
241
+ }
232
242
  const merkle = new MerkleClient({
233
243
  apiKey: config.apiKey,
234
244
  chainId: 56,
@@ -239,10 +249,20 @@ export async function fourBatchPrivateSellMerkle(params) {
239
249
  const gasPrice = await getOptimizedGasPrice(provider, getGasPriceConfig(config));
240
250
  const gasMultiplier = config.gasLimitMultiplier ?? 1.0;
241
251
  const minOut = minFundsEach ?? 0n;
252
+ const sellGasLimit = BigInt(Math.ceil(800000 * gasMultiplier));
242
253
  const signedTxs = [];
243
254
  const nonceManager = new NonceManager(provider);
244
255
  const wallets = privateKeys.map((k) => new Wallet(k, provider));
245
- const amountsWei = amounts.map((a) => ethers.parseUnits(a, 18));
256
+ // ⚠️ Four.meme 可能对小数精度敏感,建议使用整数
257
+ const amountsWei = amounts.map((a, idx) => {
258
+ const amountWei = ethers.parseUnits(a, 18);
259
+ const hasDecimals = a.includes('.');
260
+ if (hasDecimals) {
261
+ console.log(`⚠️ 钱包 ${idx}: 检测到小数卖出数量 ${a}`);
262
+ console.log(` 建议: 使用整数数量(如 42988 而非 42988.04)可能提高成功率`);
263
+ }
264
+ return amountWei;
265
+ });
246
266
  // ✅ Step 0: 检查代币余额
247
267
  console.log('🔍 检查代币余额...');
248
268
  const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
@@ -297,11 +317,49 @@ export async function fourBatchPrivateSellMerkle(params) {
297
317
  throw new Error(`需要授权: ${needApprovalIndexes.length} 个钱包授权额度不足。\n` +
298
318
  `解决方案:调用 approveFourTokenManagerBatch({ amounts: ['max', 'max', ...] })`);
299
319
  }
300
- // ✅ Step 3: 为每个钱包生成卖出交易
320
+ // ✅ Step 3: 检查 BNB 余额(用于支付 gas)
321
+ console.log('💰 检查 BNB 余额(用于支付 gas 费)...');
322
+ const bnbBalances = await Promise.all(wallets.map(w => provider.getBalance(w.address)));
323
+ const estimatedGasCost = sellGasLimit * gasPrice;
324
+ for (let i = 0; i < wallets.length; i++) {
325
+ const bnbBalance = bnbBalances[i];
326
+ const bnbFormatted = ethers.formatEther(bnbBalance);
327
+ const gasFormatted = ethers.formatEther(estimatedGasCost);
328
+ console.log(` 钱包 ${i}:`);
329
+ console.log(` BNB 余额: ${bnbFormatted}`);
330
+ console.log(` 预计 Gas: ${gasFormatted}`);
331
+ if (bnbBalance < estimatedGasCost) {
332
+ console.log(` ❌ BNB 不足!`);
333
+ throw new Error(`钱包 ${i} BNB 余额不足支付 gas 费\n` +
334
+ `需要: ${gasFormatted} BNB\n` +
335
+ `实际: ${bnbFormatted} BNB\n` +
336
+ `缺少: ${ethers.formatEther(estimatedGasCost - bnbBalance)} BNB`);
337
+ }
338
+ else {
339
+ const remaining = bnbBalance - estimatedGasCost;
340
+ console.log(` ✅ BNB 充足(剩余 ${ethers.formatEther(remaining)})`);
341
+ }
342
+ }
343
+ // ✅ Step 4: 为每个钱包生成卖出交易
344
+ console.log('\n💰 构建卖出交易...');
345
+ console.log(` TokenManager 合约: ${tmAddr}`);
346
+ console.log(` 代币地址: ${tokenAddress}`);
347
+ console.log(` minFundsEach (最小收益): ${minOut === 0n ? '0 (不限制)' : ethers.formatEther(minOut) + ' BNB'}`);
301
348
  const tm2Contracts = wallets.map((w) => new ethers.Contract(tmAddr, TM2_ABI, w));
349
+ // 显示每个交易的详细参数
350
+ console.log(`\n 📋 交易参数:`);
351
+ for (let i = 0; i < wallets.length; i++) {
352
+ console.log(` 钱包 ${i}:`);
353
+ console.log(` 卖出数量: ${ethers.formatUnits(amountsWei[i], 18)} 代币`);
354
+ console.log(` 最小收益: ${minOut === 0n ? '0 BNB (接受任何价格)' : ethers.formatEther(minOut) + ' BNB'}`);
355
+ console.log(` 合约方法: sellToken(origin=0, token=${tokenAddress.slice(0, 8)}..., amount=${ethers.formatUnits(amountsWei[i], 18)}, minFunds=${minOut})`);
356
+ }
302
357
  const sellUnsigned = await Promise.all(tm2Contracts.map((c, i) => c.sellToken.populateTransaction(0n, tokenAddress, amountsWei[i], minOut)));
303
- const sellGasLimit = BigInt(Math.ceil(800000 * gasMultiplier));
304
358
  const sellGasLimits = new Array(wallets.length).fill(sellGasLimit);
359
+ console.log(`\n ⛽ Gas 设置:`);
360
+ console.log(` Gas Limit: ${sellGasLimit}`);
361
+ console.log(` Gas Price: ${ethers.formatUnits(gasPrice, 'gwei')} Gwei`);
362
+ console.log(` 预计 Gas 费: ${ethers.formatEther(sellGasLimit * gasPrice)} BNB (每笔)\n`);
305
363
  const sellNonces = await Promise.all(wallets.map((w) => nonceManager.getNextNonce(w)));
306
364
  const signedSells = await Promise.all(sellUnsigned.map((unsigned, i) => wallets[i].signTransaction({
307
365
  ...unsigned,
@@ -313,6 +371,7 @@ export async function fourBatchPrivateSellMerkle(params) {
313
371
  type: getTxType(config)
314
372
  })));
315
373
  signedTxs.push(...signedSells);
374
+ console.log(`✅ 已生成 ${signedSells.length} 个卖出交易签名\n`);
316
375
  // ✅ 基于 minFunds 为每个钱包添加利润转账
317
376
  const extractProfit = shouldExtractProfit(config);
318
377
  if (extractProfit) {
@@ -342,6 +401,12 @@ export async function fourBatchPrivateSellMerkle(params) {
342
401
  }
343
402
  // ✅ 清理临时 nonce 缓存
344
403
  nonceManager.clearTemp();
404
+ console.log(`📦 Bundle 摘要:`);
405
+ console.log(` 总交易数: ${signedTxs.length}`);
406
+ console.log(` - 卖出交易: ${signedSells.length}`);
407
+ console.log(` - 利润交易: ${signedTxs.length - signedSells.length}`);
408
+ console.log(`\n⚠️ 注意: 交易已签名,但尚未提交到链上`);
409
+ console.log(` 请将 signedTransactions 提交到服务器,由服务器调用 Merkle API\n`);
345
410
  // ✅ 简化返回:只返回签名交易
346
411
  return {
347
412
  signedTransactions: signedTxs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.1.98",
3
+ "version": "1.1.99",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",