four-flap-meme-sdk 4.0.11 → 4.0.13

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.
@@ -176,11 +176,14 @@ export async function pancakeQuickBatchSwapMerkle(params) {
176
176
  sellerRequired = bribeAmount + sellerGasCost;
177
177
  }
178
178
  else {
179
- // ERC20 模式:子钱包已预留 BNB,不需要主钱包转 Gas
180
- // 卖方 Gas: 贿赂(BRIBE) + 卖出(gasLimit) + N个ERC20转账(65000 each) + 利润(BRIBE)
179
+ // ERC20:卖方还要给每个买方转一笔买入 Gas(hop=0 直转 / hop>0 多跳)
181
180
  sellerGasCost =
182
- gasPrice * (BRIBE_GAS_LIMIT + finalGasLimit + ERC20_TRANSFER_GAS * BigInt(buyers.length) + BRIBE_GAS_LIMIT);
183
- sellerRequired = bribeAmount + sellerGasCost;
181
+ gasPrice *
182
+ (BRIBE_GAS_LIMIT +
183
+ finalGasLimit +
184
+ (NATIVE_TRANSFER_GAS_LIMIT + ERC20_TRANSFER_GAS) * BigInt(buyers.length) +
185
+ BRIBE_GAS_LIMIT);
186
+ sellerRequired = bribeAmount + sellerGasCost + gasPrice * finalGasLimit * BigInt(buyers.length);
184
187
  }
185
188
  if (sellerBalance < sellerRequired) {
186
189
  throw new Error(`主钱包 BNB 余额不足: 需要约 ${ethers.formatEther(sellerRequired)} BNB (贿赂: ${ethers.formatEther(bribeAmount)}, Gas: ${ethers.formatEther(sellerGasCost)}), 实际 ${ethers.formatEther(sellerBalance)} BNB`);
@@ -265,10 +268,9 @@ export async function pancakeQuickBatchSwapMerkle(params) {
265
268
  });
266
269
  let transferTxs;
267
270
  if (disperseHopCount === 0) {
268
- // ✅ 无多跳:直接转账
269
- const transferNonces = buyers.map((_, i) => sellerNonce + i);
270
- sellerNonce += buyers.length;
271
271
  if (useNativeToken) {
272
+ const transferNonces = buyers.map((_, i) => sellerNonce + i);
273
+ sellerNonce += buyers.length;
272
274
  transferTxs = await Promise.all(buyers.map((buyer, i) => {
273
275
  const transferValue = transferAmountsWei[i] + FLAT_FEE + buyerGasCost;
274
276
  return seller.signTransaction({
@@ -284,19 +286,30 @@ export async function pancakeQuickBatchSwapMerkle(params) {
284
286
  }
285
287
  else {
286
288
  const erc20Interface = new ethers.Interface(ERC20_ABI);
287
- transferTxs = await Promise.all(buyers.map((buyer, i) => {
289
+ transferTxs = [];
290
+ for (let i = 0; i < buyers.length; i++) {
291
+ const buyer = buyers[i];
292
+ transferTxs.push(await seller.signTransaction({
293
+ to: buyer.address,
294
+ value: buyerGasCost,
295
+ nonce: sellerNonce++,
296
+ gasPrice,
297
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
298
+ chainId: context.chainId,
299
+ type: txType,
300
+ }));
288
301
  const transferData = erc20Interface.encodeFunctionData('transfer', [buyer.address, transferAmountsWei[i]]);
289
- return seller.signTransaction({
302
+ transferTxs.push(await seller.signTransaction({
290
303
  to: quoteToken,
291
304
  data: transferData,
292
305
  value: 0n,
293
- nonce: transferNonces[i],
306
+ nonce: sellerNonce++,
294
307
  gasPrice,
295
308
  gasLimit: ERC20_TRANSFER_GAS,
296
309
  chainId: context.chainId,
297
310
  type: txType,
298
- });
299
- }));
311
+ }));
312
+ }
300
313
  }
301
314
  }
302
315
  else {
@@ -139,10 +139,15 @@ export async function flapQuickBatchSwapMerkle(params) {
139
139
  sellerRequired = bribeAmount + sellerGasCost;
140
140
  }
141
141
  else {
142
- // ERC20 模式:贿赂 + Gas(卖出 + ERC20转账 + 利润)
142
+ const reserveForBuyers = ethers.parseEther((config.reserveGasETH || 0.0005).toString());
143
143
  sellerGasCost =
144
- gasPrice * (BRIBE_GAS_LIMIT + finalGasLimit + ERC20_TRANSFER_GAS * BigInt(buyers.length) + BRIBE_GAS_LIMIT);
145
- sellerRequired = bribeAmount + sellerGasCost;
144
+ gasPrice *
145
+ (BRIBE_GAS_LIMIT +
146
+ finalGasLimit +
147
+ (NATIVE_TRANSFER_GAS_LIMIT + ERC20_TRANSFER_GAS) * BigInt(buyers.length) +
148
+ BRIBE_GAS_LIMIT);
149
+ sellerRequired =
150
+ bribeAmount + sellerGasCost + (reserveForBuyers + gasPrice * finalGasLimit) * BigInt(buyers.length);
146
151
  }
147
152
  if (sellerBalance < sellerRequired) {
148
153
  throw new Error(`主钱包 ${chainContext.nativeToken} 余额不足: 需要约 ${ethers.formatEther(sellerRequired)} (贿赂: ${ethers.formatEther(bribeAmount)}, Gas: ${ethers.formatEther(sellerGasCost)}), 实际 ${ethers.formatEther(sellerBalance)}`);
@@ -195,10 +200,9 @@ export async function flapQuickBatchSwapMerkle(params) {
195
200
  });
196
201
  let transferTxs;
197
202
  if (disperseHopCount === 0) {
198
- // ✅ 无多跳:直接转账
199
- const transferNonces = buyers.map((_, i) => sellerNonce + i);
200
- sellerNonce += buyers.length;
201
203
  if (useNativeToken) {
204
+ const transferNonces = buyers.map((_, i) => sellerNonce + i);
205
+ sellerNonce += buyers.length;
202
206
  transferTxs = await Promise.all(buyers.map((buyer, i) => {
203
207
  const transferValue = transferAmountsWei[i] + reserveGas + buyerGasCost;
204
208
  return seller.signTransaction({
@@ -214,19 +218,30 @@ export async function flapQuickBatchSwapMerkle(params) {
214
218
  }
215
219
  else {
216
220
  const erc20Interface = new ethers.Interface(ERC20_ABI);
217
- transferTxs = await Promise.all(buyers.map((buyer, i) => {
221
+ transferTxs = [];
222
+ for (let i = 0; i < buyers.length; i++) {
223
+ const buyer = buyers[i];
224
+ transferTxs.push(await seller.signTransaction({
225
+ to: buyer.address,
226
+ value: reserveGas + buyerGasCost,
227
+ nonce: sellerNonce++,
228
+ gasPrice,
229
+ gasLimit: NATIVE_TRANSFER_GAS_LIMIT,
230
+ chainId: chainContext.chainId,
231
+ type: txType,
232
+ }));
218
233
  const transferData = erc20Interface.encodeFunctionData('transfer', [buyer.address, transferAmountsWei[i]]);
219
- return seller.signTransaction({
234
+ transferTxs.push(await seller.signTransaction({
220
235
  to: quoteToken,
221
236
  data: transferData,
222
237
  value: 0n,
223
- nonce: transferNonces[i],
238
+ nonce: sellerNonce++,
224
239
  gasPrice,
225
240
  gasLimit: ERC20_TRANSFER_GAS,
226
241
  chainId: chainContext.chainId,
227
242
  type: txType,
228
- });
229
- }));
243
+ }));
244
+ }
230
245
  }
231
246
  }
232
247
  else {
@@ -7,7 +7,7 @@
7
7
  import { Contract, formatEther } from 'ethers';
8
8
  import { ADDRESSES, ZERO_ADDRESS } from '../../core/constants/index.js';
9
9
  import { Helper3 } from '../four/contracts/helper3.js';
10
- import { FlapPortal } from '../flap/portal.js';
10
+ import { FlapPortal, TokenStatus, } from '../flap/portal.js';
11
11
  import { getTaxTokenInfo, isTaxToken } from '../four/tax-token.js';
12
12
  import { DEFAULT_V3_FEE_TIERS } from './lp-inspect-helpers.js';
13
13
  import { getChainConfig } from './registry.js';
@@ -16,10 +16,19 @@ import { determinePlatform, formatBalance, getProvider, getTokenDecimals, normal
16
16
  // 常量(从公共模块导入)
17
17
  // ============================================================================
18
18
  const MULTICALL3_ADDRESS = ADDRESSES.BSC.Multicall3;
19
- /** BSC V8 买卖税;status=0 说明不是 Flap 币,slot 里常见残留 100 bps(1%)不能当当前税。 */
19
+ /** 内盘可交易:1=Tradable,2=InDuel。0=无效(非 Flap 币常见)、3=已杀死、4=已毕业外盘,都不能当内盘提前返回。 */
20
+ function isFlapInnerMarket(status) {
21
+ const n = Number(status);
22
+ return n === TokenStatus.Tradable || n === TokenStatus.InDuel;
23
+ }
24
+ /** BSC V8 买卖税。只有真实 Flap 状态才读买卖税,避免非 Flap 币 slot 残留 100 bps。 */
20
25
  function flapV8TaxBps(st) {
21
- if (!Number(st.status))
26
+ const status = Number(st.status);
27
+ if (status !== TokenStatus.Tradable &&
28
+ status !== TokenStatus.InDuel &&
29
+ status !== TokenStatus.DEX) {
22
30
  return 0;
31
+ }
23
32
  return Math.max(Number(st.buyTaxRate ?? 0n), Number(st.sellTaxRate ?? 0n));
24
33
  }
25
34
  // ============================================================================
@@ -95,7 +104,7 @@ export async function inspectTokenLP(token, opts) {
95
104
  st = await flap.getTokenV5(token);
96
105
  }
97
106
  }
98
- if (st && st.status !== undefined && Number(st.status) !== 4) {
107
+ if (st && isFlapInnerMarket(st.status)) {
99
108
  result.platform = 'FLAP';
100
109
  let quoteDecimals = 18;
101
110
  let quoteSymbol = chainConfig.wrappedNativeSymbol;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "4.0.11",
3
+ "version": "4.0.13",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",