four-flap-meme-sdk 1.4.54 → 1.4.55

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.
@@ -1,7 +1,7 @@
1
1
  export class FourClient {
2
2
  constructor(cfg) {
3
3
  // 默认使用 Cloudflare Workers 代理,已配置 CORS,浏览器可直接使用
4
- this.baseUrl = cfg?.baseUrl || 'https://throbbing-shape-a160.paulalsop072.workers.dev';
4
+ this.baseUrl = cfg?.baseUrl || 'https://bscfourapi.emit.tools';
5
5
  }
6
6
  async generateNonce(req) {
7
7
  const r = await fetch(`${this.baseUrl}/v1/private/user/nonce/generate`, {
@@ -1,3 +1,3 @@
1
1
  export declare const TM_ABI: string[];
2
2
  export declare const HELPER3_ABI: string[];
3
- export declare const TM_ADDRESS: "0x342399a59943B5815849657Aa0e06D7058D9d5C6";
3
+ export declare const TM_ADDRESS: "0x5c952063c7fc8610FFDB798152D69F0B9550762b";
@@ -14,4 +14,5 @@ export const HELPER3_ABI = [
14
14
  'function tryBuy(address token, uint256 amount, uint256 funds) view returns (address tokenManager, address quote, uint256 estimatedAmount, uint256 estimatedCost, uint256 estimatedFee, uint256 amountMsgValue, uint256 amountApproval, uint256 amountFunds)',
15
15
  'function trySell(address token, uint256 amount) view returns (address tokenManager, address quote, uint256 funds, uint256 fee)'
16
16
  ];
17
- export const TM_ADDRESS = ADDRESSES.BSC.TokenManagerV2Proxy;
17
+ // Four.meme 使用 TokenManagerOriginal(代理合约已移除)
18
+ export const TM_ADDRESS = ADDRESSES.BSC.TokenManagerOriginal;
@@ -176,7 +176,7 @@ export async function createTokenWithBundleBuy(params) {
176
176
  clickFun: false,
177
177
  });
178
178
  // 4. 构建交易
179
- const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
179
+ const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
180
180
  // ✅ 获取 gas price
181
181
  let gasPrice;
182
182
  if (club48) {
@@ -403,7 +403,7 @@ export async function batchBuyWithBundle(params) {
403
403
  explorerEndpoint: config.club48ExplorerEndpoint
404
404
  });
405
405
  const blockOffset = config.bundleBlockOffset ?? 100;
406
- const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
406
+ const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
407
407
  const gasPrice = await club48.getMinGasPrice();
408
408
  const signedTxs = [];
409
409
  const nextNonceMap = new Map();
@@ -535,7 +535,7 @@ export async function batchSellWithBundle(params) {
535
535
  explorerEndpoint: config.club48ExplorerEndpoint
536
536
  });
537
537
  const blockOffset = config.bundleBlockOffset ?? 100;
538
- const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
538
+ const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
539
539
  const gasPrice = await club48.getMinGasPrice();
540
540
  const signedTxs = [];
541
541
  const nextNonceMap = new Map();
@@ -666,7 +666,7 @@ export async function fourPrivateBuy(params) {
666
666
  const provider = new JsonRpcProvider(rpcUrl);
667
667
  const wallet = new Wallet(privateKey, provider);
668
668
  const club48 = new Club48Client({ endpoint: club48Endpoint, explorerEndpoint: club48ExplorerEndpoint });
669
- const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
669
+ const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
670
670
  const gasPrice = await club48.getMinGasPrice();
671
671
  const fundsWei = ethers.parseEther(funds);
672
672
  const minAmount = 0n;
@@ -686,7 +686,7 @@ export async function fourPrivateSell(params) {
686
686
  const provider = new JsonRpcProvider(rpcUrl);
687
687
  const wallet = new Wallet(privateKey, provider);
688
688
  const club48 = new Club48Client({ endpoint: club48Endpoint, explorerEndpoint: club48ExplorerEndpoint });
689
- const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
689
+ const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
690
690
  const gasPrice = await club48.getMinGasPrice();
691
691
  const amountWei = ethers.parseUnits(amount, 18);
692
692
  const minOut = minFunds ?? 0n;
@@ -707,7 +707,7 @@ export async function fourBatchPrivateBuy(params) {
707
707
  throw new Error('privateKeys and fundsList length mismatch');
708
708
  const provider = new JsonRpcProvider(rpcUrl);
709
709
  const club48 = new Club48Client({ endpoint: club48Endpoint, explorerEndpoint: club48ExplorerEndpoint });
710
- const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
710
+ const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
711
711
  // ✅ 并行处理
712
712
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
713
713
  const fundsWeiList = fundsList.map(f => ethers.parseEther(f));
@@ -757,7 +757,7 @@ export async function fourBatchPrivateSell(params) {
757
757
  throw new Error('privateKeys and amounts length mismatch');
758
758
  const provider = new JsonRpcProvider(rpcUrl);
759
759
  const club48 = new Club48Client({ endpoint: club48Endpoint, explorerEndpoint: club48ExplorerEndpoint });
760
- const tmAddr = ADDRESSES.BSC.TokenManagerV2Proxy;
760
+ const tmAddr = ADDRESSES.BSC.TokenManagerOriginal;
761
761
  const minOut = minFundsEach ?? 0n;
762
762
  // ✅ 并行处理
763
763
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
@@ -55,8 +55,6 @@ export declare const ADDRESSES: {
55
55
  readonly USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d";
56
56
  readonly BUSD: "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56";
57
57
  readonly TokenManagerOriginal: "0x5c952063c7fc8610FFDB798152D69F0B9550762b";
58
- readonly TokenManagerV1Proxy: "0xf7F823d0E790219dBf727bDb971837574655fCB0";
59
- readonly TokenManagerV2Proxy: "0x342399a59943B5815849657Aa0e06D7058D9d5C6";
60
58
  readonly TokenManagerV1: "0xf7F823d0E790219dBf727bDb971837574655fCB0";
61
59
  readonly TokenManagerV2: "0x342399a59943B5815849657Aa0e06D7058D9d5C6";
62
60
  readonly TokenManagerHelper3: "0xF251F83e40a78868FcfA3FA4599Dad6494E46034";
@@ -51,9 +51,6 @@ export const ADDRESSES = {
51
51
  // ========== Four.meme 合约 ==========
52
52
  // 原始合约(TokenManager2,创建代币专用,不收费)
53
53
  TokenManagerOriginal: '0x5c952063c7fc8610FFDB798152D69F0B9550762b',
54
- // 代理合约(收费版,仅交易)
55
- TokenManagerV1Proxy: '0xf7F823d0E790219dBf727bDb971837574655fCB0',
56
- TokenManagerV2Proxy: '0x342399a59943B5815849657Aa0e06D7058D9d5C6',
57
54
  // ✅ 向后兼容别名(保持旧代码可用)
58
55
  TokenManagerV1: '0xf7F823d0E790219dBf727bDb971837574655fCB0',
59
56
  TokenManagerV2: '0x342399a59943B5815849657Aa0e06D7058D9d5C6',
@@ -299,7 +299,7 @@ function resolveSpenderAddress(chain, platform) {
299
299
  MONAD: ADDRESSES.MONAD.FlapPortal, // ✅ Monad Flap Portal
300
300
  },
301
301
  four: {
302
- // Four.meme 使用 TokenManagerOriginal(买卖交易实际使用的合约)
302
+ // Four.meme 使用 TokenManagerOriginal(代理合约已移除)
303
303
  BSC: ADDRESSES.BSC.TokenManagerOriginal,
304
304
  BASE: ADDRESSES.BASE.TokenManagerHelper3,
305
305
  XLAYER: ZERO_ADDRESS, // XLAYER 暂不支持 Four.meme
@@ -264,26 +264,35 @@ async function buildV2BuyTx(wallet, tokenAddress, buyAmount, nonce, gasPrice, ga
264
264
  /**
265
265
  * 构建 V3 单跳买入交易
266
266
  * BNB → Token (使用 exactInputSingle + multicall)
267
+ *
268
+ * ✅ 修复:使用 ethers.Interface 手动编码 calldata,避免 multicall 重载问题
267
269
  */
268
270
  async function buildV3BuyTx(wallet, tokenAddress, buyAmount, nonce, gasPrice, gasLimit, chainId, txType, v3Fee = 2500 // 默认 0.25% 手续费
269
271
  ) {
270
272
  const deadline = getDeadline();
271
273
  const v3RouterIface = new ethers.Interface(V3_ROUTER02_ABI);
272
274
  // 构建 exactInputSingle calldata
273
- const exactInputSingleData = v3RouterIface.encodeFunctionData('exactInputSingle', [{
274
- tokenIn: WBNB_ADDRESS,
275
- tokenOut: tokenAddress,
276
- fee: v3Fee,
277
- recipient: wallet.address,
278
- amountIn: buyAmount,
279
- amountOutMinimum: 0n,
280
- sqrtPriceLimitX96: 0n
281
- }]);
282
- // 使用 multicall 包装,传入 deadline 和 ETH value
283
- const v3Router = new Contract(PANCAKE_V3_ROUTER_ADDRESS, V3_ROUTER02_ABI, wallet);
284
- const unsigned = await v3Router.multicall.populateTransaction(deadline, [exactInputSingleData], { value: buyAmount });
275
+ const swapParams = {
276
+ tokenIn: WBNB_ADDRESS,
277
+ tokenOut: tokenAddress,
278
+ fee: v3Fee,
279
+ recipient: wallet.address,
280
+ amountIn: buyAmount,
281
+ amountOutMinimum: 0n,
282
+ sqrtPriceLimitX96: 0n
283
+ };
284
+ const exactInputSingleData = v3RouterIface.encodeFunctionData('exactInputSingle', [swapParams]);
285
+ // 添加 refundETH,退还多余的 ETH
286
+ const refundETHData = v3RouterIface.encodeFunctionData('refundETH', []);
287
+ // ✅ 使用明确的函数签名编码 multicall,避免重载问题
288
+ const multicallData = v3RouterIface.encodeFunctionData('multicall(uint256,bytes[])', [
289
+ deadline,
290
+ [exactInputSingleData, refundETHData]
291
+ ]);
285
292
  const tx = {
286
- ...unsigned,
293
+ to: PANCAKE_V3_ROUTER_ADDRESS,
294
+ data: multicallData,
295
+ value: buyAmount,
287
296
  nonce,
288
297
  gasLimit: BigInt(gasLimit),
289
298
  chainId
@@ -331,25 +340,32 @@ async function buildV2BuyTxWithERC20(wallet, tokenAddress, baseTokenAddress, buy
331
340
  /**
332
341
  * 构建 V3 买入交易(ERC20 输入)
333
342
  * USDT/USDC → Token (使用 exactInputSingle + multicall)
343
+ *
344
+ * ✅ 修复:使用 ethers.Interface 手动编码 calldata,避免 multicall 重载问题
334
345
  */
335
346
  async function buildV3BuyTxWithERC20(wallet, tokenAddress, baseTokenAddress, buyAmount, nonce, gasPrice, gasLimit, chainId, txType, v3Fee = 2500) {
336
347
  const deadline = getDeadline();
337
348
  const v3RouterIface = new ethers.Interface(V3_ROUTER02_ABI);
338
349
  // 构建 exactInputSingle calldata
339
- const exactInputSingleData = v3RouterIface.encodeFunctionData('exactInputSingle', [{
340
- tokenIn: baseTokenAddress,
341
- tokenOut: tokenAddress,
342
- fee: v3Fee,
343
- recipient: wallet.address,
344
- amountIn: buyAmount,
345
- amountOutMinimum: 0n,
346
- sqrtPriceLimitX96: 0n
347
- }]);
348
- // 使用 multicall 包装(无需 ETH value)
349
- const v3Router = new Contract(PANCAKE_V3_ROUTER_ADDRESS, V3_ROUTER02_ABI, wallet);
350
- const unsigned = await v3Router.multicall.populateTransaction(deadline, [exactInputSingleData]);
350
+ const swapParams = {
351
+ tokenIn: baseTokenAddress,
352
+ tokenOut: tokenAddress,
353
+ fee: v3Fee,
354
+ recipient: wallet.address,
355
+ amountIn: buyAmount,
356
+ amountOutMinimum: 0n,
357
+ sqrtPriceLimitX96: 0n
358
+ };
359
+ const exactInputSingleData = v3RouterIface.encodeFunctionData('exactInputSingle', [swapParams]);
360
+ // 使用明确的函数签名编码 multicall,避免重载问题
361
+ const multicallData = v3RouterIface.encodeFunctionData('multicall(uint256,bytes[])', [
362
+ deadline,
363
+ [exactInputSingleData]
364
+ ]);
351
365
  const tx = {
352
- ...unsigned,
366
+ to: PANCAKE_V3_ROUTER_ADDRESS,
367
+ data: multicallData,
368
+ value: 0n,
353
369
  nonce,
354
370
  gasLimit: BigInt(gasLimit),
355
371
  chainId
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.4.54",
3
+ "version": "1.4.55",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",