four-flap-meme-sdk 1.3.47 → 1.3.48

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.
@@ -82,31 +82,30 @@ const V2_ROUTER_ABI = [
82
82
  /**
83
83
  * SwapRouter02 的 V2 方法 ABI (PotatoSwap)
84
84
  *
85
- * 根据官方文档,SwapRouter02 支持完整的 V2 方法:
85
+ * 重要:根据实际 ABI,SwapRouter02 V2 方法只有:
86
86
  * - swapExactTokensForTokens(amountIn, amountOutMin, path[], to)
87
- * - swapExactETHForTokens(amountOutMin, path[], to) - ETH 换代币,自动 wrap
88
- * - swapExactTokensForETH(amountIn, amountOutMin, path[], to) - 代币换 ETH,自动 unwrap
89
87
  * - swapTokensForExactTokens(amountOut, amountInMax, path[], to)
90
- * - swapTokensForExactETH(amountOut, amountInMax, path[], to)
91
- * - swapETHForExactTokens(amountOut, path[], to)
88
+ *
89
+ * 没有 swapExactETHForTokens / swapExactTokensForETH!
90
+ * 必须手动处理 ETH/WETH 转换:
91
+ * - 买入(ETH→Token): wrapETH + swapExactTokensForTokens,通过 multicall 组合
92
+ * - 卖出(Token→ETH): swapExactTokensForTokens(to=ADDRESS_THIS) + unwrapWETH9,通过 multicall 组合
92
93
  */
93
94
  const SWAP_ROUTER02_V2_ABI = [
94
- // V2 交换方法 - 精确输入
95
+ // V2 交换方法(只有 token-to-token)
95
96
  'function swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to) external payable returns (uint256 amountOut)',
96
- 'function swapExactETHForTokens(uint256 amountOutMin, address[] calldata path, address to) external payable returns (uint256 amountOut)',
97
- 'function swapExactTokensForETH(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to) external payable returns (uint256 amountOut)',
98
- // V2 交换方法 - 精确输出
99
97
  'function swapTokensForExactTokens(uint256 amountOut, uint256 amountInMax, address[] calldata path, address to) external payable returns (uint256 amountIn)',
100
- 'function swapTokensForExactETH(uint256 amountOut, uint256 amountInMax, address[] calldata path, address to) external payable returns (uint256 amountIn)',
101
- 'function swapETHForExactTokens(uint256 amountOut, address[] calldata path, address to) external payable returns (uint256 amountIn)',
102
98
  // Multicall - 多种重载
103
99
  'function multicall(uint256 deadline, bytes[] calldata data) external payable returns (bytes[] memory results)',
100
+ 'function multicall(bytes32 previousBlockhash, bytes[] calldata data) external payable returns (bytes[] memory results)',
104
101
  'function multicall(bytes[] calldata data) external payable returns (bytes[] memory results)',
105
- // 辅助方法
102
+ // 辅助方法 - ETH/WETH 转换
106
103
  'function wrapETH(uint256 value) external payable',
107
104
  'function unwrapWETH9(uint256 amountMinimum, address recipient) external payable',
108
105
  'function unwrapWETH9(uint256 amountMinimum) external payable',
109
106
  'function refundETH() external payable',
107
+ // 代币操作
108
+ 'function pull(address token, uint256 value) external payable',
110
109
  'function sweepToken(address token, uint256 amountMinimum, address recipient) external payable',
111
110
  'function sweepToken(address token, uint256 amountMinimum) external payable',
112
111
  ];
@@ -331,26 +330,37 @@ export async function directV2BatchBuy(params) {
331
330
  let txData;
332
331
  let txValue;
333
332
  if (useSwapRouter02) {
334
- // ✅ SwapRouter02: 直接调用 V2 方法(不需要 multicall)
333
+ // ✅ SwapRouter02: 使用 multicall(deadline, bytes[]) 组合调用
334
+ // ABI 中没有 swapExactETHForTokens,只有 swapExactTokensForTokens
335
335
  if (useNative) {
336
- // ETH -> 代币:直接调用 swapExactETHForTokens
337
- // msg.value ETH 会自动包装为 WETH
338
- // path 第一个元素必须是 WETH
339
- txData = routerIface.encodeFunctionData('swapExactETHForTokens', [
336
+ // ETH -> 代币:直接用 swapExactTokensForTokens(参考之前成功的交易)
337
+ // 之前成功的交易只用了一个 swapExactTokensForTokens,没有 wrapETH
338
+ // SwapRouter02 会自动处理 msg.value 的 ETH
339
+ const swapData = routerIface.encodeFunctionData('swapExactTokensForTokens', [
340
+ amountWei,
340
341
  0n, // amountOutMin
341
342
  path, // path: [WETH, ..., tokenOut]
342
343
  wallet.address, // to
343
344
  ]);
345
+ // 使用 multicall(uint256 deadline, bytes[]) - 带 deadline 的版本
346
+ txData = routerIface.encodeFunctionData('multicall(uint256,bytes[])', [
347
+ deadline,
348
+ [swapData],
349
+ ]);
344
350
  txValue = amountWei;
345
351
  }
346
352
  else {
347
- // 代币 -> 代币:直接调用 swapExactTokensForTokens
348
- txData = routerIface.encodeFunctionData('swapExactTokensForTokens', [
353
+ // 代币 -> 代币:也用 multicall 包装
354
+ const swapData = routerIface.encodeFunctionData('swapExactTokensForTokens', [
349
355
  amountWei,
350
356
  0n, // amountOutMin
351
357
  path,
352
358
  wallet.address, // to
353
359
  ]);
360
+ txData = routerIface.encodeFunctionData('multicall(uint256,bytes[])', [
361
+ deadline,
362
+ [swapData],
363
+ ]);
354
364
  txValue = 0n;
355
365
  }
356
366
  }
@@ -479,26 +489,47 @@ export async function directV2BatchSell(params) {
479
489
  // 卖出交易
480
490
  let txData;
481
491
  if (useSwapRouter02) {
482
- // ✅ SwapRouter02: 直接调用 V2 方法(不需要 multicall)
492
+ // ✅ SwapRouter02: 使用 multicall(deadline, bytes[]) 组合调用
493
+ // ABI 中没有 swapExactTokensForETH,只有 swapExactTokensForTokens
483
494
  if (useNativeOutput) {
484
- // 代币 -> ETH:直接调用 swapExactTokensForETH
485
- // path 最后一个元素必须是 WETH
486
- // 最终 WETH 会自动解包为 ETH 发送给 to
487
- txData = routerIface.encodeFunctionData('swapExactTokensForETH', [
495
+ // 代币 -> ETH:swapExactTokensForTokens + unwrapWETH9
496
+ const multicallData = [];
497
+ // SwapRouter02 特殊地址约定:
498
+ // address(2) = ADDRESS_THIS = Router 合约自己
499
+ const ADDRESS_THIS = '0x0000000000000000000000000000000000000002';
500
+ // 1. swapExactTokensForTokens - Token -> WETH,发送到 Router 自己
501
+ // path 最后一个元素是 WETH
502
+ const swapData = routerIface.encodeFunctionData('swapExactTokensForTokens', [
488
503
  sellAmount,
489
504
  0n, // amountOutMin
490
505
  path, // path: [token, ..., WETH]
491
- wallet.address, // to
506
+ ADDRESS_THIS, // to = Router 自己,WETH 留在 Router 中
507
+ ]);
508
+ multicallData.push(swapData);
509
+ // 2. unwrapWETH9 - 将 Router 中的 WETH 解包为 ETH 发送给用户
510
+ const unwrapData = routerIface.encodeFunctionData('unwrapWETH9(uint256,address)', [
511
+ 0n, // amountMinimum
512
+ wallet.address, // recipient = 用户
513
+ ]);
514
+ multicallData.push(unwrapData);
515
+ // 使用 multicall(uint256 deadline, bytes[]) - 带 deadline 的版本
516
+ txData = routerIface.encodeFunctionData('multicall(uint256,bytes[])', [
517
+ deadline,
518
+ multicallData,
492
519
  ]);
493
520
  }
494
521
  else {
495
- // 代币 -> 代币:直接调用 swapExactTokensForTokens
496
- txData = routerIface.encodeFunctionData('swapExactTokensForTokens', [
522
+ // 代币 -> 代币:也用 multicall 包装
523
+ const swapData = routerIface.encodeFunctionData('swapExactTokensForTokens', [
497
524
  sellAmount,
498
525
  0n, // amountOutMin
499
526
  path,
500
527
  wallet.address, // to
501
528
  ]);
529
+ txData = routerIface.encodeFunctionData('multicall(uint256,bytes[])', [
530
+ deadline,
531
+ [swapData],
532
+ ]);
502
533
  }
503
534
  }
504
535
  else if (useNativeOutput) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.3.47",
3
+ "version": "1.3.48",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",