four-flap-meme-sdk 2.0.0 → 2.1.0

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.
Files changed (205) hide show
  1. package/dist/__tests__/subpath-exports.test.js +34 -0
  2. package/dist/chains/index.d.ts +13 -0
  3. package/dist/chains/index.js +13 -0
  4. package/dist/chains/xlayer/eip7702/index.d.ts +2 -0
  5. package/dist/flap/index.d.ts +10 -0
  6. package/dist/flap/index.js +8 -0
  7. package/dist/shared/constants/index.d.ts +2 -0
  8. package/dist/shared/index.d.ts +2 -0
  9. package/package.json +66 -1
  10. package/dist/chains/bsc/four/disperse.d.ts +0 -12
  11. package/dist/chains/bsc/four/disperse.js +0 -470
  12. package/dist/chains/bsc/four/pairwise.d.ts +0 -7
  13. package/dist/chains/bsc/four/pairwise.js +0 -308
  14. package/dist/chains/bsc/four/submit/blockrazor.d.ts +0 -18
  15. package/dist/chains/bsc/four/submit/blockrazor.js +0 -86
  16. package/dist/chains/bsc/four/submit/direct.d.ts +0 -66
  17. package/dist/chains/bsc/four/submit/direct.js +0 -452
  18. package/dist/chains/bsc/four/submit/helpers.d.ts +0 -18
  19. package/dist/chains/bsc/four/submit/helpers.js +0 -57
  20. package/dist/chains/bsc/four/submit/index.d.ts +0 -12
  21. package/dist/chains/bsc/four/submit/index.js +0 -11
  22. package/dist/chains/bsc/four/submit/merkle.d.ts +0 -18
  23. package/dist/chains/bsc/four/submit/merkle.js +0 -74
  24. package/dist/chains/bsc/four/submit/types.d.ts +0 -143
  25. package/dist/chains/bsc/four/swap/index.d.ts +0 -32
  26. package/dist/chains/bsc/four/swap/index.js +0 -829
  27. package/dist/chains/bsc/four/swap/types.d.ts +0 -70
  28. package/dist/chains/bsc/four/swap/types.js +0 -1
  29. package/dist/chains/bsc/four/sweep.d.ts +0 -13
  30. package/dist/chains/bsc/four/sweep.js +0 -788
  31. package/dist/chains/bsc/four/utils/index.d.ts +0 -20
  32. package/dist/chains/bsc/four/utils/index.js +0 -1558
  33. package/dist/chains/bsc/four/utils/types.d.ts +0 -1
  34. package/dist/chains/bsc/four/utils/types.js +0 -1
  35. package/dist/chains/bsc/pancake/bundle-buy-first/index.d.ts +0 -8
  36. package/dist/chains/bsc/pancake/bundle-buy-first/index.js +0 -907
  37. package/dist/chains/bsc/pancake/bundle-buy-first/types.d.ts +0 -73
  38. package/dist/chains/bsc/pancake/bundle-buy-first/types.js +0 -1
  39. package/dist/chains/bsc/pancake/bundle-swap/helpers.d.ts +0 -102
  40. package/dist/chains/bsc/pancake/bundle-swap/helpers.js +0 -572
  41. package/dist/chains/bsc/pancake/bundle-swap/index.d.ts +0 -50
  42. package/dist/chains/bsc/pancake/bundle-swap/index.js +0 -1066
  43. package/dist/chains/bsc/pancake/bundle-swap/types.d.ts +0 -202
  44. package/dist/chains/bsc/pancake/bundle-swap/types.js +0 -3
  45. package/dist/chains/xlayer/eip7702/bundle-swap/index.d.ts +0 -72
  46. package/dist/chains/xlayer/eip7702/bundle-swap/index.js +0 -921
  47. package/dist/chains/xlayer/eip7702/bundle-swap/types.d.ts +0 -65
  48. package/dist/chains/xlayer/eip7702/bundle-swap/types.js +0 -1
  49. package/dist/chains/xlayer/eip7702/multi-hop-transfer/index.d.ts +0 -128
  50. package/dist/chains/xlayer/eip7702/multi-hop-transfer/index.js +0 -857
  51. package/dist/chains/xlayer/eip7702/multi-hop-transfer/types.d.ts +0 -85
  52. package/dist/chains/xlayer/eip7702/multi-hop-transfer/types.js +0 -1
  53. package/dist/chains/xlayer/eip7702/volume/index.d.ts +0 -96
  54. package/dist/chains/xlayer/eip7702/volume/index.js +0 -793
  55. package/dist/chains/xlayer/eip7702/volume/types.d.ts +0 -124
  56. package/dist/chains/xlayer/eip7702/volume/types.js +0 -1
  57. package/dist/chains/xlayer/eoa/types-core.d.ts +0 -363
  58. package/dist/chains/xlayer/eoa/types-core.js +0 -53
  59. package/dist/chains/xlayer/eoa/types-create.d.ts +0 -413
  60. package/dist/chains/xlayer/eoa/types-create.js +0 -9
  61. package/dist/chains/xlayer/eoa/types-volume.d.ts +0 -209
  62. package/dist/chains/xlayer/eoa/types-volume.js +0 -13
  63. package/dist/dex/direct-router/index.d.ts +0 -70
  64. package/dist/dex/direct-router/index.js +0 -1410
  65. package/dist/dex/direct-router/types.d.ts +0 -81
  66. package/dist/dex/direct-router/types.js +0 -1
  67. package/dist/shared/abis/TaxToken.json +0 -969
  68. package/dist/shared/abis/TokenManager.json +0 -836
  69. package/dist/shared/abis/TokenManager2.json +0 -136
  70. package/dist/shared/abis/TokenManagerHelper3.json +0 -993
  71. package/dist/shared/abis 2/TaxToken.json +0 -105
  72. package/dist/shared/abis 2/TokenManager.json +0 -836
  73. package/dist/shared/abis 2/TokenManager2.json +0 -60
  74. package/dist/shared/abis 2/TokenManagerHelper3.json +0 -993
  75. package/dist/shared/abis 2/common.d.ts +0 -85
  76. package/dist/shared/abis 2/common.js +0 -254
  77. package/dist/shared/abis 2/index.d.ts +0 -8
  78. package/dist/shared/abis 2/index.js +0 -8
  79. package/dist/shared/clients 2/blockrazor.d.ts +0 -314
  80. package/dist/shared/clients 2/blockrazor.js +0 -596
  81. package/dist/shared/clients 2/club48.d.ts +0 -154
  82. package/dist/shared/clients 2/club48.js +0 -331
  83. package/dist/shared/clients 2/emitservice.d.ts +0 -47
  84. package/dist/shared/clients 2/emitservice.js +0 -44
  85. package/dist/shared/clients 2/four.d.ts +0 -132
  86. package/dist/shared/clients 2/four.js +0 -281
  87. package/dist/shared/clients 2/merkle.d.ts +0 -210
  88. package/dist/shared/clients 2/merkle.js +0 -400
  89. package/dist/shared/flap/__tests__/curve.test.d.ts +0 -1
  90. package/dist/shared/flap/__tests__/curve.test.js +0 -85
  91. package/dist/shared/flap/portal/index.d.ts +0 -12
  92. package/dist/shared/flap/portal/index.js +0 -11
  93. package/dist/shared/flap/portal/portal.d.ts +0 -47
  94. package/dist/shared/flap/portal/portal.js +0 -218
  95. package/dist/shared/flap/portal/types.d.ts +0 -227
  96. package/dist/shared/flap/portal/types.js +0 -80
  97. package/dist/shared/flap/portal/writer.d.ts +0 -121
  98. package/dist/shared/flap/portal/writer.js +0 -265
  99. package/dist/shared/flap/portal-bundle-merkle/core/index.d.ts +0 -18
  100. package/dist/shared/flap/portal-bundle-merkle/core/index.js +0 -938
  101. package/dist/shared/flap/portal-bundle-merkle/core/types.d.ts +0 -1
  102. package/dist/shared/flap/portal-bundle-merkle/core/types.js +0 -1
  103. package/dist/shared/flap/portal-bundle-merkle/swap/index.d.ts +0 -42
  104. package/dist/shared/flap/portal-bundle-merkle/swap/index.js +0 -1448
  105. package/dist/shared/flap/portal-bundle-merkle/swap/types.d.ts +0 -84
  106. package/dist/shared/flap/portal-bundle-merkle/swap/types.js +0 -1
  107. package/dist/shared/flap/portal-bundle-merkle/utils/index.d.ts +0 -17
  108. package/dist/shared/flap/portal-bundle-merkle/utils/index.js +0 -1024
  109. package/dist/shared/flap/portal-bundle-merkle/utils/types.d.ts +0 -16
  110. package/dist/shared/flap/portal-bundle-merkle/utils/types.js +0 -1
  111. package/dist/shared/flap/portal-bundle-merkle/utils-helpers.d.ts +0 -100
  112. package/dist/shared/flap/portal-bundle-merkle/utils-helpers.js +0 -133
  113. package/dist/shared/flap 2/__tests__/curve.test.d.ts +0 -1
  114. package/dist/shared/flap 2/__tests__/curve.test.js +0 -85
  115. package/dist/shared/flap 2/abi.d.ts +0 -4
  116. package/dist/shared/flap 2/abi.js +0 -4
  117. package/dist/shared/flap 2/constants.d.ts +0 -128
  118. package/dist/shared/flap 2/constants.js +0 -143
  119. package/dist/shared/flap 2/curve.d.ts +0 -33
  120. package/dist/shared/flap 2/curve.js +0 -84
  121. package/dist/shared/flap 2/errors.d.ts +0 -37
  122. package/dist/shared/flap 2/errors.js +0 -114
  123. package/dist/shared/flap 2/index.d.ts +0 -22
  124. package/dist/shared/flap 2/index.js +0 -33
  125. package/dist/shared/flap 2/ipfs.d.ts +0 -21
  126. package/dist/shared/flap 2/ipfs.js +0 -38
  127. package/dist/shared/flap 2/meta.d.ts +0 -30
  128. package/dist/shared/flap 2/meta.js +0 -195
  129. package/dist/shared/flap 2/permit.d.ts +0 -16
  130. package/dist/shared/flap 2/permit.js +0 -67
  131. package/dist/shared/flap 2/pinata.d.ts +0 -40
  132. package/dist/shared/flap 2/pinata.js +0 -106
  133. package/dist/shared/flap 2/portal-bundle-merkle/config.d.ts +0 -79
  134. package/dist/shared/flap 2/portal-bundle-merkle/config.js +0 -133
  135. package/dist/shared/flap 2/portal-bundle-merkle/core.d.ts +0 -18
  136. package/dist/shared/flap 2/portal-bundle-merkle/core.js +0 -938
  137. package/dist/shared/flap 2/portal-bundle-merkle/create-to-dex.d.ts +0 -125
  138. package/dist/shared/flap 2/portal-bundle-merkle/create-to-dex.js +0 -665
  139. package/dist/shared/flap 2/portal-bundle-merkle/curve-to-dex.d.ts +0 -88
  140. package/dist/shared/flap 2/portal-bundle-merkle/curve-to-dex.js +0 -446
  141. package/dist/shared/flap 2/portal-bundle-merkle/index.d.ts +0 -14
  142. package/dist/shared/flap 2/portal-bundle-merkle/index.js +0 -26
  143. package/dist/shared/flap 2/portal-bundle-merkle/pancake-proxy.d.ts +0 -28
  144. package/dist/shared/flap 2/portal-bundle-merkle/pancake-proxy.js +0 -701
  145. package/dist/shared/flap 2/portal-bundle-merkle/private.d.ts +0 -17
  146. package/dist/shared/flap 2/portal-bundle-merkle/private.js +0 -549
  147. package/dist/shared/flap 2/portal-bundle-merkle/swap-buy-first.d.ts +0 -65
  148. package/dist/shared/flap 2/portal-bundle-merkle/swap-buy-first.js +0 -831
  149. package/dist/shared/flap 2/portal-bundle-merkle/swap.d.ts +0 -201
  150. package/dist/shared/flap 2/portal-bundle-merkle/swap.js +0 -1359
  151. package/dist/shared/flap 2/portal-bundle-merkle/types.d.ts +0 -358
  152. package/dist/shared/flap 2/portal-bundle-merkle/types.js +0 -1
  153. package/dist/shared/flap 2/portal-bundle-merkle/utils.d.ts +0 -89
  154. package/dist/shared/flap 2/portal-bundle-merkle/utils.js +0 -963
  155. package/dist/shared/flap 2/portal-bundle.d.ts +0 -119
  156. package/dist/shared/flap 2/portal-bundle.js +0 -584
  157. package/dist/shared/flap 2/portal.d.ts +0 -392
  158. package/dist/shared/flap 2/portal.js +0 -559
  159. package/dist/shared/flap 2/vanity.d.ts +0 -48
  160. package/dist/shared/flap 2/vanity.js +0 -110
  161. package/dist/shared/flap 2/vault.d.ts +0 -240
  162. package/dist/shared/flap 2/vault.js +0 -366
  163. package/dist/shared/four 2/index.d.ts +0 -7
  164. package/dist/shared/four 2/index.js +0 -22
  165. package/dist/shared/four 2/tax-token.d.ts +0 -176
  166. package/dist/shared/four 2/tax-token.js +0 -302
  167. package/dist/shared/index 2.js +0 -10
  168. package/dist/shared/index.d 2.ts +0 -10
  169. package/dist/types/distribute.d.ts +0 -72
  170. package/dist/types/distribute.js +0 -1
  171. package/dist/types 2/errors.d.ts +0 -27
  172. package/dist/types 2/errors.js +0 -34
  173. package/dist/utils/__tests__/errors.test.d.ts +0 -1
  174. package/dist/utils/__tests__/errors.test.js +0 -76
  175. package/dist/utils/airdrop-sweep-types.d.ts +0 -1
  176. package/dist/utils/airdrop-sweep-types.js +0 -1
  177. package/dist/utils/erc20/index.d.ts +0 -242
  178. package/dist/utils/erc20/index.js +0 -645
  179. package/dist/utils/erc20/types.d.ts +0 -77
  180. package/dist/utils/erc20/types.js +0 -1
  181. package/dist/utils/erc20-types.d.ts +0 -1
  182. package/dist/utils/erc20-types.js +0 -1
  183. package/dist/utils/holders-maker/helpers.d.ts +0 -43
  184. package/dist/utils/holders-maker/helpers.js +0 -371
  185. package/dist/utils/holders-maker/index.d.ts +0 -26
  186. package/dist/utils/holders-maker/index.js +0 -218
  187. package/dist/utils/holders-maker/types.d.ts +0 -72
  188. package/dist/utils/holders-maker/types.js +0 -4
  189. package/dist/utils/holders-maker-types.d.ts +0 -1
  190. package/dist/utils/holders-maker-types.js +0 -1
  191. package/dist/utils/lp-inspect/index.d.ts +0 -44
  192. package/dist/utils/lp-inspect/index.js +0 -937
  193. package/dist/utils/lp-inspect/types.d.ts +0 -100
  194. package/dist/utils/lp-inspect/types.js +0 -1
  195. package/dist/utils/lp-inspect-types.d.ts +0 -1
  196. package/dist/utils/lp-inspect-types.js +0 -1
  197. package/dist/utils/private-sale-types.d.ts +0 -1
  198. package/dist/utils/private-sale-types.js +0 -1
  199. package/dist/utils/quote-helpers/index.d.ts +0 -107
  200. package/dist/utils/quote-helpers/index.js +0 -346
  201. package/dist/utils/quote-helpers/types.d.ts +0 -16
  202. package/dist/utils/quote-helpers/types.js +0 -1
  203. package/dist/utils/quote-helpers-types.d.ts +0 -1
  204. package/dist/utils/quote-helpers-types.js +0 -1
  205. /package/dist/{chains/bsc/four/submit/types.js → __tests__/subpath-exports.test.d.ts} +0 -0
@@ -1,17 +0,0 @@
1
- import { FlapPrivateBuyMerkleParams, FlapPrivateSellMerkleParams, FlapPrivateTransactionResult, FlapBatchPrivateBuyMerkleParams, FlapBatchPrivateSellMerkleParams, FlapBatchPrivateMerkleResult } from './types.js';
2
- /**
3
- * 私有购买(单笔)(Merkle 版本)
4
- */
5
- export declare function flapPrivateBuyMerkle(params: FlapPrivateBuyMerkleParams): Promise<FlapPrivateTransactionResult>;
6
- /**
7
- * 私有卖出(单笔)(Merkle 版本)
8
- */
9
- export declare function flapPrivateSellMerkle(params: FlapPrivateSellMerkleParams): Promise<FlapPrivateTransactionResult>;
10
- /**
11
- * 批量私有购买(Merkle 版本)
12
- */
13
- export declare function flapBatchPrivateBuyMerkle(params: FlapBatchPrivateBuyMerkleParams): Promise<FlapBatchPrivateMerkleResult>;
14
- /**
15
- * 批量私有卖出(Merkle 版本)
16
- */
17
- export declare function flapBatchPrivateSellMerkle(params: FlapBatchPrivateSellMerkleParams): Promise<FlapBatchPrivateMerkleResult>;
@@ -1,549 +0,0 @@
1
- import { ethers, Wallet } from 'ethers';
2
- import { MerkleClient } from '../../clients/merkle.js';
3
- import { getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../../utils/bundle-helpers.js';
4
- import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
5
- import { ZERO_ADDRESS } from '../../../utils/constants.js';
6
- import { GAS_LIMITS, CHAINS } from '../../constants/index.js';
7
- import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA } from './config.js';
8
- const DEFAULT_GAS_LIMIT = 800000;
9
- /**
10
- * 私有购买(单笔)(Merkle 版本)
11
- */
12
- export async function flapPrivateBuyMerkle(params) {
13
- const { chain, privateKey, tokenAddress, amountIn, minOutputAmount, config } = params;
14
- const { chainId, provider } = createMerkleContext(chain, config);
15
- const wallet = new Wallet(privateKey, provider);
16
- const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
17
- const originalAmountWei = ethers.parseEther(amountIn);
18
- // ✅ 利润提取配置
19
- const extractProfit = shouldExtractProfit(config);
20
- const { actualAmountWei, profitWei } = splitBuyAmount(originalAmountWei, extractProfit, config);
21
- const minAmountOut = parseMinOutput(minOutputAmount);
22
- const portal = new ethers.Contract(portalAddr, PORTAL_ABI, wallet);
23
- // ✅ 并行获取 gasPrice、nonce 和构建未签名交易
24
- const [gasPrice, currentNonce, unsigned] = await Promise.all([
25
- getOptimizedGasPrice(provider, getGasPriceConfig(config)),
26
- // ✅ 使用 pending nonce,避免 xLayer 等链上“已有 pending 交易”导致 nonce too low
27
- provider.getTransactionCount(wallet.address, 'pending'),
28
- portal.swapExactInput.populateTransaction({
29
- inputToken: ZERO_ADDRESS,
30
- outputToken: tokenAddress,
31
- inputAmount: actualAmountWei,
32
- minOutputAmount: minAmountOut,
33
- permitData: '0x',
34
- }, { value: actualAmountWei })
35
- ]);
36
- const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
37
- // ✅ 获取贿赂金额
38
- const bribeAmount = getBribeAmount(config);
39
- const needBribeTx = bribeAmount > 0n;
40
- const needProfitTx = extractProfit && profitWei > 0n;
41
- // ✅ 分配 nonces:贿赂 → 买入 → 利润
42
- let nonceIdx = 0;
43
- const bribeNonce = needBribeTx ? currentNonce + nonceIdx++ : undefined;
44
- const buyNonce = currentNonce + nonceIdx++;
45
- const profitNonce = needProfitTx ? currentNonce + nonceIdx : undefined;
46
- // ✅ 并行签名所有交易(贿赂、买入、利润)
47
- const signPromises = [];
48
- const txType = getTxType(config);
49
- // 贿赂交易
50
- if (needBribeTx && bribeNonce !== undefined) {
51
- signPromises.push(wallet.signTransaction({
52
- to: BLOCKRAZOR_BUILDER_EOA,
53
- value: bribeAmount,
54
- nonce: bribeNonce,
55
- gasPrice,
56
- gasLimit: GAS_LIMITS.BRIBE,
57
- chainId,
58
- type: txType
59
- }));
60
- }
61
- // 买入交易
62
- signPromises.push(wallet.signTransaction({
63
- ...unsigned,
64
- from: wallet.address,
65
- nonce: buyNonce,
66
- gasLimit,
67
- gasPrice,
68
- chainId,
69
- type: txType,
70
- value: actualAmountWei
71
- }));
72
- // ✅ 并行签名完成后按顺序返回
73
- const signedTxs = await Promise.all(signPromises);
74
- // ✅ 利润多跳转账(强制 2 跳中转)
75
- let profitHopWallets;
76
- if (needProfitTx && profitNonce !== undefined) {
77
- const profitHopResult = await buildProfitHopTransactions({
78
- provider,
79
- payerWallet: wallet,
80
- profitAmount: profitWei,
81
- profitRecipient: getProfitRecipient(),
82
- hopCount: PROFIT_HOP_COUNT,
83
- gasPrice,
84
- chainId,
85
- txType,
86
- startNonce: profitNonce
87
- });
88
- signedTxs.push(...profitHopResult.signedTransactions);
89
- profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
90
- }
91
- return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
92
- }
93
- /**
94
- * 私有卖出(单笔)(Merkle 版本)
95
- */
96
- export async function flapPrivateSellMerkle(params) {
97
- const { chain, privateKey, tokenAddress, amount, minOutputAmount, config } = params;
98
- const { chainId, provider } = createMerkleContext(chain, config);
99
- const wallet = new Wallet(privateKey, provider);
100
- const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
101
- const amountWei = ethers.parseUnits(amount, 18);
102
- const portal = new ethers.Contract(portalAddr, PORTAL_ABI, wallet);
103
- // ✅ 并行获取 gasPrice、nonce、报价和构建未签名交易
104
- const [gasPrice, currentNonce, { quotedOutput }, unsigned] = await Promise.all([
105
- getOptimizedGasPrice(provider, getGasPriceConfig(config)),
106
- // ✅ 使用 pending nonce,避免 xLayer 等链上“已有 pending 交易”导致 nonce too low
107
- provider.getTransactionCount(wallet.address, 'pending'),
108
- resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutputAmount),
109
- portal.swapExactInput.populateTransaction({
110
- inputToken: tokenAddress,
111
- outputToken: ZERO_ADDRESS,
112
- inputAmount: amountWei,
113
- minOutputAmount: 0n, // ✅ 已移除滑点保护
114
- permitData: '0x',
115
- })
116
- ]);
117
- const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
118
- const txType = getTxType(config);
119
- // ✅ 获取贿赂金额
120
- const bribeAmount = getBribeAmount(config);
121
- const needBribeTx = bribeAmount > 0n;
122
- // ✅ 利润计算
123
- const extractProfit = shouldExtractProfit(config);
124
- const { profit: profitWei } = extractProfit && quotedOutput > 0n
125
- ? calculateProfit(quotedOutput, config)
126
- : { profit: 0n };
127
- const needProfitTx = extractProfit && profitWei > 0n;
128
- // ✅ 分配 nonces:贿赂 → 卖出 → 利润
129
- let nonceIdx = 0;
130
- const bribeNonce = needBribeTx ? currentNonce + nonceIdx++ : undefined;
131
- const sellNonce = currentNonce + nonceIdx++;
132
- const profitNonce = needProfitTx ? currentNonce + nonceIdx : undefined;
133
- // ✅ 并行签名所有交易(贿赂、卖出、利润)
134
- const signPromises = [];
135
- // 贿赂交易
136
- if (needBribeTx && bribeNonce !== undefined) {
137
- signPromises.push(wallet.signTransaction({
138
- to: BLOCKRAZOR_BUILDER_EOA,
139
- value: bribeAmount,
140
- nonce: bribeNonce,
141
- gasPrice,
142
- gasLimit: GAS_LIMITS.BRIBE,
143
- chainId,
144
- type: txType
145
- }));
146
- }
147
- // 卖出交易
148
- signPromises.push(wallet.signTransaction({
149
- ...unsigned,
150
- from: wallet.address,
151
- nonce: sellNonce,
152
- gasLimit,
153
- gasPrice,
154
- chainId,
155
- type: txType
156
- }));
157
- // ✅ 并行签名完成后按顺序返回
158
- const signedTxs = await Promise.all(signPromises);
159
- // ✅ 利润多跳转账(强制 2 跳中转)
160
- let profitHopWallets;
161
- if (needProfitTx && profitNonce !== undefined) {
162
- const profitHopResult = await buildProfitHopTransactions({
163
- provider,
164
- payerWallet: wallet,
165
- profitAmount: profitWei,
166
- profitRecipient: getProfitRecipient(),
167
- hopCount: PROFIT_HOP_COUNT,
168
- gasPrice,
169
- chainId,
170
- txType,
171
- startNonce: profitNonce
172
- });
173
- signedTxs.push(...profitHopResult.signedTransactions);
174
- profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
175
- }
176
- return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
177
- }
178
- /**
179
- * 批量私有购买(Merkle 版本)
180
- */
181
- export async function flapBatchPrivateBuyMerkle(params) {
182
- const { chain, privateKeys, amountsIn, tokenAddress, minOutputAmounts, config } = params;
183
- if (privateKeys.length !== amountsIn.length) {
184
- throw new Error('privateKeys and amountsIn length mismatch');
185
- }
186
- const { chainId, provider } = createMerkleContext(chain, config);
187
- const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
188
- const wallets = privateKeys.map(k => new Wallet(k, provider));
189
- const originalAmountsWei = amountsIn.map(a => ethers.parseEther(a));
190
- // ✅ 利润提取配置
191
- const extractProfit = shouldExtractProfit(config);
192
- const { totalProfit, remainingAmounts } = calculateBatchProfit(originalAmountsWei, config);
193
- const actualAmountsWei = remainingAmounts;
194
- const maxFundsIndex = findMaxIndex(originalAmountsWei);
195
- const minOuts = resolveBatchMinOutputs(minOutputAmounts, wallets.length);
196
- const portals = wallets.map(w => new ethers.Contract(portalAddr, PORTAL_ABI, w));
197
- // ✅ 获取贿赂金额
198
- const bribeAmount = getBribeAmount(config);
199
- const needBribeTx = bribeAmount > 0n;
200
- const needProfitTx = extractProfit && totalProfit > 0n;
201
- // ✅ 并行获取 gasPrice、所有 nonces 和构建未签名交易
202
- const [gasPrice, initialNonces, unsignedList] = await Promise.all([
203
- getOptimizedGasPrice(provider, getGasPriceConfig(config)),
204
- // ✅ 使用 pending nonce,避免 xLayer 等链上“已有 pending 交易”导致 nonce too low
205
- Promise.all(wallets.map(w => provider.getTransactionCount(w.address, 'pending'))),
206
- Promise.all(portals.map((portal, i) => portal.swapExactInput.populateTransaction({
207
- inputToken: ZERO_ADDRESS,
208
- outputToken: tokenAddress,
209
- inputAmount: actualAmountsWei[i],
210
- minOutputAmount: minOuts[i],
211
- permitData: '0x',
212
- }, { value: actualAmountsWei[i] })))
213
- ]);
214
- // ✅ 分配 nonces:贿赂(可选) → 买入 → 利润(可选)
215
- let payerNonceOffset = 0;
216
- let bribeNonce;
217
- if (needBribeTx && maxFundsIndex >= 0) {
218
- bribeNonce = initialNonces[maxFundsIndex];
219
- payerNonceOffset++;
220
- }
221
- const nonces = initialNonces.map((n, i) => {
222
- if (i === maxFundsIndex) {
223
- return n + payerNonceOffset; // payer 的买入 nonce 需要偏移
224
- }
225
- return n;
226
- });
227
- const profitNonce = needProfitTx && maxFundsIndex >= 0
228
- ? initialNonces[maxFundsIndex] + payerNonceOffset + 1
229
- : undefined;
230
- const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
231
- const gasLimits = new Array(wallets.length).fill(gasLimit);
232
- const signedTxs = [];
233
- // ✅ 贿赂交易放在首位
234
- if (needBribeTx && bribeNonce !== undefined && maxFundsIndex >= 0) {
235
- const bribeTx = await wallets[maxFundsIndex].signTransaction({
236
- to: BLOCKRAZOR_BUILDER_EOA,
237
- value: bribeAmount,
238
- nonce: bribeNonce,
239
- gasPrice,
240
- gasLimit: GAS_LIMITS.BRIBE,
241
- chainId,
242
- type: getTxType(config)
243
- });
244
- signedTxs.push(bribeTx);
245
- }
246
- // ✅ 并行签名所有买入交易
247
- const signedList = await signBatchTransactions({
248
- unsignedList,
249
- wallets,
250
- nonces,
251
- gasLimits,
252
- gasPrice,
253
- chainId,
254
- config,
255
- values: actualAmountsWei
256
- });
257
- signedTxs.push(...signedList);
258
- // ✅ 利润多跳转账(强制 2 跳中转)
259
- let profitHopWallets;
260
- if (needProfitTx && profitNonce !== undefined && maxFundsIndex >= 0) {
261
- const profitHopResult = await buildProfitHopTransactions({
262
- provider,
263
- payerWallet: wallets[maxFundsIndex],
264
- profitAmount: totalProfit,
265
- profitRecipient: getProfitRecipient(),
266
- hopCount: PROFIT_HOP_COUNT,
267
- gasPrice,
268
- chainId,
269
- txType: getTxType(config),
270
- startNonce: profitNonce
271
- });
272
- signedTxs.push(...profitHopResult.signedTransactions);
273
- profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
274
- }
275
- return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
276
- }
277
- /**
278
- * 批量私有卖出(Merkle 版本)
279
- */
280
- export async function flapBatchPrivateSellMerkle(params) {
281
- const { chain, privateKeys, amounts, tokenAddress, minOutputAmounts, config } = params;
282
- if (privateKeys.length !== amounts.length) {
283
- throw new Error('privateKeys and amounts length mismatch');
284
- }
285
- const { chainId, provider } = createMerkleContext(chain, config);
286
- const portalAddr = FLAP_PORTAL_ADDRESSES[chain];
287
- const wallets = privateKeys.map(k => new Wallet(k, provider));
288
- const amountsWei = amounts.map(a => ethers.parseUnits(a, 18));
289
- const portal = new ethers.Contract(portalAddr, PORTAL_ABI, provider);
290
- const portals = wallets.map(w => new ethers.Contract(portalAddr, PORTAL_ABI, w));
291
- // ✅ 并行获取 gasPrice、所有 nonces、所有报价和构建未签名交易
292
- const [gasPrice, initialNonces, quotedOutputs, unsignedList] = await Promise.all([
293
- getOptimizedGasPrice(provider, getGasPriceConfig(config)),
294
- // ✅ 使用 pending nonce,避免 xLayer 等链上“已有 pending 交易”导致 nonce too low
295
- Promise.all(wallets.map(w => provider.getTransactionCount(w.address, 'pending'))),
296
- Promise.all(amountsWei.map(amount => portal.quoteExactInput.staticCall({
297
- inputToken: tokenAddress,
298
- outputToken: ZERO_ADDRESS,
299
- inputAmount: amount
300
- }).catch(() => 0n))),
301
- // ✅ 并行构建未签名交易(已移除滑点保护:minOuts 固定为 0)
302
- Promise.all(portals.map((p, i) => p.swapExactInput.populateTransaction({
303
- inputToken: tokenAddress,
304
- outputToken: ZERO_ADDRESS,
305
- inputAmount: amountsWei[i],
306
- minOutputAmount: 0n,
307
- permitData: '0x'
308
- })))
309
- ]);
310
- const extractProfit = shouldExtractProfit(config);
311
- const { totalProfit, maxRevenueIndex } = summarizeSellProfits(quotedOutputs, extractProfit, config);
312
- // ✅ 获取贿赂金额
313
- const bribeAmount = getBribeAmount(config);
314
- const needBribeTx = bribeAmount > 0n;
315
- const needProfitTx = extractProfit && totalProfit > 0n;
316
- // ✅ 分配 nonces:贿赂(可选) → 卖出 → 利润(可选)
317
- let payerNonceOffset = 0;
318
- let bribeNonce;
319
- if (needBribeTx && maxRevenueIndex >= 0) {
320
- bribeNonce = initialNonces[maxRevenueIndex];
321
- payerNonceOffset++;
322
- }
323
- const nonces = initialNonces.map((n, i) => {
324
- if (i === maxRevenueIndex) {
325
- return n + payerNonceOffset; // payer 的卖出 nonce 需要偏移
326
- }
327
- return n;
328
- });
329
- const profitNonce = needProfitTx && maxRevenueIndex >= 0
330
- ? initialNonces[maxRevenueIndex] + payerNonceOffset + 1
331
- : undefined;
332
- const gasLimit = resolveGasLimit(config.gasLimitMultiplier);
333
- const gasLimits = new Array(wallets.length).fill(gasLimit);
334
- const signedTxs = [];
335
- // ✅ 贿赂交易放在首位
336
- if (needBribeTx && bribeNonce !== undefined && maxRevenueIndex >= 0) {
337
- const bribeTx = await wallets[maxRevenueIndex].signTransaction({
338
- to: BLOCKRAZOR_BUILDER_EOA,
339
- value: bribeAmount,
340
- nonce: bribeNonce,
341
- gasPrice,
342
- gasLimit: GAS_LIMITS.BRIBE,
343
- chainId,
344
- type: getTxType(config)
345
- });
346
- signedTxs.push(bribeTx);
347
- }
348
- // ✅ 并行签名所有卖出交易
349
- const signedList = await signBatchTransactions({
350
- unsignedList,
351
- wallets,
352
- nonces,
353
- gasLimits,
354
- gasPrice,
355
- chainId,
356
- config
357
- });
358
- signedTxs.push(...signedList);
359
- // ✅ 利润多跳转账(强制 2 跳中转)
360
- let profitHopWallets;
361
- if (needProfitTx && profitNonce !== undefined && maxRevenueIndex >= 0) {
362
- const profitHopResult = await buildProfitHopTransactions({
363
- provider,
364
- payerWallet: wallets[maxRevenueIndex],
365
- profitAmount: totalProfit,
366
- profitRecipient: getProfitRecipient(),
367
- hopCount: PROFIT_HOP_COUNT,
368
- gasPrice,
369
- chainId,
370
- txType: getTxType(config),
371
- startNonce: profitNonce
372
- });
373
- signedTxs.push(...profitHopResult.signedTransactions);
374
- profitHopWallets = profitHopResult.hopWallets; // ✅ 收集利润多跳钱包
375
- }
376
- return { signedTransactions: signedTxs, profitHopWallets }; // ✅ 返回利润多跳钱包
377
- }
378
- // ==================== 内部工具函数 ====================
379
- function createMerkleContext(chain, config) {
380
- const chainId = CHAIN_ID_MAP[chain];
381
- // ✅ 检查是否为 Merkle 支持的链(BSC, ETH)
382
- // Monad 不支持 Merkle 捆绑服务,使用普通 RPC
383
- if (chainId !== CHAINS.BSC.chainId && chainId !== CHAINS.ETHEREUM.chainId) {
384
- // 对于不支持 Merkle 的链(如 Monad),必须提供自定义 RPC
385
- if (!config.customRpcUrl) {
386
- throw new Error(`Chain ${chain} (chainId: ${chainId}) does not support Merkle bundle service. Please provide customRpcUrl.`);
387
- }
388
- const { JsonRpcProvider } = require('ethers');
389
- // ✅ 禁用 ENS: 避免 "network does not support ENS" 错误
390
- return {
391
- chainId,
392
- provider: new JsonRpcProvider(config.customRpcUrl, { chainId, name: chain.toLowerCase(), ensAddress: undefined })
393
- };
394
- }
395
- const merkle = new MerkleClient({
396
- apiKey: config.apiKey,
397
- chainId: chainId, // 类型断言为 Merkle 支持的 chainId
398
- customRpcUrl: config.customRpcUrl
399
- });
400
- return {
401
- chainId,
402
- provider: merkle.getProvider()
403
- };
404
- }
405
- function splitBuyAmount(amount, extractProfit, config) {
406
- if (!extractProfit) {
407
- return { actualAmountWei: amount, profitWei: 0n };
408
- }
409
- const { remaining, profit } = calculateProfit(amount, config);
410
- return { actualAmountWei: remaining, profitWei: profit };
411
- }
412
- function parseMinOutput(value) {
413
- if (value === undefined) {
414
- return 0n;
415
- }
416
- return typeof value === 'string' ? ethers.parseUnits(value, 18) : value;
417
- }
418
- function resolveGasLimit(multiplier, defaultGas = DEFAULT_GAS_LIMIT) {
419
- const factor = multiplier ?? 1.0;
420
- return BigInt(Math.ceil(defaultGas * factor));
421
- }
422
- /**
423
- * 追加利润多跳转账交易(强制 2 跳中转)
424
- */
425
- async function appendSingleProfitTransfer({ extractProfit, profitWei, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
426
- if (!extractProfit || profitWei === 0n) {
427
- return undefined;
428
- }
429
- const profitHopResult = await buildProfitHopTransactions({
430
- provider,
431
- payerWallet: wallet,
432
- profitAmount: profitWei,
433
- profitRecipient: getProfitRecipient(),
434
- hopCount: PROFIT_HOP_COUNT,
435
- gasPrice,
436
- chainId,
437
- txType: getTxType(config),
438
- startNonce: baseNonce + 1
439
- });
440
- signedTxs.push(...profitHopResult.signedTransactions);
441
- return profitHopResult.hopWallets; // ✅ 返回利润多跳钱包
442
- }
443
- async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutputAmount) {
444
- if (minOutputAmount !== undefined) {
445
- const minOut = typeof minOutputAmount === 'string'
446
- ? ethers.parseEther(minOutputAmount)
447
- : minOutputAmount;
448
- return {
449
- quotedOutput: minOut,
450
- minOut
451
- };
452
- }
453
- try {
454
- const quotedOutput = await portal.quoteExactInput.staticCall({
455
- inputToken: tokenAddress,
456
- outputToken: ZERO_ADDRESS,
457
- inputAmount: amountWei
458
- });
459
- return {
460
- quotedOutput,
461
- minOut: 0n // ✅ 已移除滑点保护:minOut 固定为 0
462
- };
463
- }
464
- catch {
465
- return {
466
- quotedOutput: 0n,
467
- minOut: 0n
468
- };
469
- }
470
- }
471
- /**
472
- * 追加卖出利润多跳转账交易(强制 2 跳中转)
473
- */
474
- async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
475
- if (!extractProfit || quotedOutput <= 0n) {
476
- return undefined;
477
- }
478
- const { profit } = calculateProfit(quotedOutput, config);
479
- if (profit === 0n) {
480
- return undefined;
481
- }
482
- const profitHopResult = await buildProfitHopTransactions({
483
- provider,
484
- payerWallet: wallet,
485
- profitAmount: profit,
486
- profitRecipient: getProfitRecipient(),
487
- hopCount: PROFIT_HOP_COUNT,
488
- gasPrice,
489
- chainId,
490
- txType: getTxType(config),
491
- startNonce: baseNonce + 1
492
- });
493
- signedTxs.push(...profitHopResult.signedTransactions);
494
- return profitHopResult.hopWallets; // ✅ 返回利润多跳钱包
495
- }
496
- function resolveBatchMinOutputs(minOutputAmounts, walletCount) {
497
- if (minOutputAmounts && minOutputAmounts.length === walletCount) {
498
- return minOutputAmounts.map(m => typeof m === 'string' ? ethers.parseUnits(m, 18) : m);
499
- }
500
- return new Array(walletCount).fill(0n);
501
- }
502
- function findMaxIndex(values) {
503
- if (values.length === 0) {
504
- return -1;
505
- }
506
- let maxIndex = 0;
507
- let maxValue = values[0];
508
- for (let i = 1; i < values.length; i++) {
509
- if (values[i] > maxValue) {
510
- maxValue = values[i];
511
- maxIndex = i;
512
- }
513
- }
514
- return maxIndex;
515
- }
516
- async function signBatchTransactions({ unsignedList, wallets, nonces, gasLimits, gasPrice, chainId, config, values }) {
517
- return await Promise.all(unsignedList.map((unsigned, i) => {
518
- const value = values ? values[i] : unsigned.value;
519
- return wallets[i].signTransaction({
520
- ...unsigned,
521
- from: wallets[i].address,
522
- nonce: nonces[i],
523
- gasLimit: gasLimits[i],
524
- gasPrice,
525
- chainId,
526
- type: getTxType(config),
527
- value
528
- });
529
- }));
530
- }
531
- function summarizeSellProfits(quotedOutputs, extractProfit, config) {
532
- let totalProfit = 0n;
533
- let maxRevenueIndex = -1;
534
- let maxRevenue = 0n;
535
- if (extractProfit) {
536
- for (let i = 0; i < quotedOutputs.length; i++) {
537
- const quoted = quotedOutputs[i];
538
- if (quoted > 0n) {
539
- const { profit } = calculateProfit(quoted, config);
540
- totalProfit += profit;
541
- if (quoted > maxRevenue) {
542
- maxRevenue = quoted;
543
- maxRevenueIndex = i;
544
- }
545
- }
546
- }
547
- }
548
- return { totalProfit, maxRevenueIndex: maxRevenueIndex < 0 ? 0 : maxRevenueIndex };
549
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * Flap Protocol 内盘捆绑换手(Merkle Bundle)- 先买后卖
3
- *
4
- * 功能:钱包B先买入代币 → 钱包A卖出相同数量 → 原子执行
5
- */
6
- import { CommonBundleConfig } from '../../../utils/bundle-helpers.js';
7
- import { FlapSignConfig } from './config.js';
8
- import type { GeneratedWallet } from '../../../utils/wallet.js';
9
- export type FlapChain = 'bsc' | 'xlayer' | 'base';
10
- export type UserType = 'v0' | 'v1';
11
- export interface FlapBuyFirstSignConfig extends FlapSignConfig {
12
- reserveGasETH?: number;
13
- skipQuoteOnError?: boolean;
14
- userType?: UserType;
15
- }
16
- export interface FlapBuyFirstConfig extends CommonBundleConfig {
17
- apiKey: string;
18
- customRpcUrl?: string;
19
- bundleBlockOffset?: number;
20
- reserveGasETH?: number;
21
- skipQuoteOnError?: boolean;
22
- waitForConfirmation?: boolean;
23
- waitTimeoutMs?: number;
24
- }
25
- export interface FlapBundleBuyFirstSignParams {
26
- chain: FlapChain;
27
- buyerPrivateKey?: string;
28
- buyerPrivateKeys?: string[];
29
- sellerPrivateKey?: string;
30
- sellerPrivateKeys?: string[];
31
- tokenAddress: string;
32
- buyerFunds?: string;
33
- buyerFundsPercentage?: number;
34
- config: FlapBuyFirstSignConfig;
35
- quoteToken?: string;
36
- quoteTokenDecimals?: number;
37
- buyCount?: number;
38
- sellCount?: number;
39
- }
40
- export interface FlapBundleBuyFirstParams {
41
- chain: FlapChain;
42
- buyerPrivateKey: string;
43
- sellerPrivateKey: string;
44
- tokenAddress: string;
45
- buyerFunds?: string;
46
- buyerFundsPercentage?: number;
47
- config: FlapBuyFirstConfig;
48
- }
49
- /** ✅ Flap BuyFirst 结果(简化版) */
50
- export type FlapBuyFirstResult = {
51
- signedTransactions: string[];
52
- profitHopWallets?: GeneratedWallet[];
53
- metadata?: {
54
- buyerAddress: string;
55
- sellerAddress: string;
56
- buyAmount: string;
57
- sellAmount: string;
58
- profitAmount?: string;
59
- buyCount?: number;
60
- sellCount?: number;
61
- buyAmounts?: string[];
62
- sellAmounts?: string[];
63
- };
64
- };
65
- export declare function flapBundleBuyFirstMerkle(params: FlapBundleBuyFirstSignParams): Promise<FlapBuyFirstResult>;