four-flap-meme-sdk 2.2.11 → 2.2.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.
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ export { TM2, type FourChainV2 } from './contracts/tm2.js';
15
15
  export { Helper3, Helper3Writer } from './contracts/helper3.js';
16
16
  export { CDPV2 } from './shared/flap/curve.js';
17
17
  export { FlapPortal, FlapPortalWriter, type FlapChain, type PortalConfig, type TokenStateV2, type TokenStateV3, type TokenStateV4, type TokenStateV5, type TokenStateV7, type QuoteExactInputParams, type ExactInputParams, type ExactInputV3Params, type NewTokenV3Params, type NewTokenV4Params, type NewTokenV5Params, type TaxDistributionConfig, validateTaxDistribution, TokenStatus, TokenVersion, FeeType, DexThreshType, MigratorType, V3LPFeeProfile, lpFeeProfileToV3Fee, DEXId } from './shared/flap/portal.js';
18
+ export { getFlapGraduatedDexMetrics, buildFlapInfinityPoolKey, computeInfinityPoolId, isInfinityCLPoolManagerAddress, PCS_INFINITY_CL_POOL_MANAGER_BSC, FLAP_INFINITY_HOOKS_BSC, type GraduatedDexMetrics, type InfinityPoolKey, } from './shared/flap/graduated-dex.js';
18
19
  export { uploadTokenMeta, type TokenMetaInput } from './shared/flap/ipfs.js';
19
20
  export { buildPermitPiggybackAuto } from './shared/flap/permit.js';
20
21
  export { predictVanityTokenAddressByChain, findSaltEndingByChain } from './shared/flap/vanity.js';
package/dist/index.js CHANGED
@@ -48,6 +48,7 @@ export { TM2 } from './contracts/tm2.js';
48
48
  export { Helper3, Helper3Writer } from './contracts/helper3.js';
49
49
  export { CDPV2 } from './shared/flap/curve.js';
50
50
  export { FlapPortal, FlapPortalWriter, validateTaxDistribution, TokenStatus, TokenVersion, FeeType, DexThreshType, MigratorType, V3LPFeeProfile, lpFeeProfileToV3Fee, DEXId } from './shared/flap/portal.js';
51
+ export { getFlapGraduatedDexMetrics, buildFlapInfinityPoolKey, computeInfinityPoolId, isInfinityCLPoolManagerAddress, PCS_INFINITY_CL_POOL_MANAGER_BSC, FLAP_INFINITY_HOOKS_BSC, } from './shared/flap/graduated-dex.js';
51
52
  export { uploadTokenMeta } from './shared/flap/ipfs.js';
52
53
  export { buildPermitPiggybackAuto } from './shared/flap/permit.js';
53
54
  export { predictVanityTokenAddressByChain, findSaltEndingByChain } from './shared/flap/vanity.js';
@@ -0,0 +1 @@
1
+ export { getFlapGraduatedDexMetrics, buildFlapInfinityPoolKey, computeInfinityPoolId, isInfinityCLPoolManagerAddress, PCS_INFINITY_CL_POOL_MANAGER_BSC, FLAP_INFINITY_HOOKS_BSC, type GraduatedDexMetrics, type InfinityPoolKey, } from '../../utils/pcs-infinity-cl.js';
@@ -0,0 +1 @@
1
+ export { getFlapGraduatedDexMetrics, buildFlapInfinityPoolKey, computeInfinityPoolId, isInfinityCLPoolManagerAddress, PCS_INFINITY_CL_POOL_MANAGER_BSC, FLAP_INFINITY_HOOKS_BSC, } from '../../utils/pcs-infinity-cl.js';
@@ -158,8 +158,13 @@ export async function createTokenWithBundleBuyMerkle(params) {
158
158
  profitTokenAmount = totalProfit / divisor;
159
159
  }
160
160
  // ✅ 优化:并行获取 unsignedBuys 和 buyerNonces
161
+ // TOKEN_V3_PERMIT / newTokenV7 内盘买入须 swapExactInputV3(与 create-to-dex 一致)
162
+ const usePortalSwapV3 = useV7Portal ||
163
+ (params.lpFeeProfile !== undefined && !normalizedTax) ||
164
+ (!!params.extensionID &&
165
+ params.extensionID !== '0x' + '00'.repeat(32));
161
166
  const [unsignedBuys, buyerNonces] = await Promise.all([
162
- populateBuyTransactionsWithQuote(buyers, portalAddr, tokenAddress, adjustedFundsList, inputToken, useNativeToken),
167
+ populateBuyTransactionsWithQuote(buyers, portalAddr, tokenAddress, adjustedFundsList, inputToken, useNativeToken, usePortalSwapV3, params.extensionData ?? '0x'),
163
168
  allocateBuyerNonces(buyers, extractProfit, maxFundsIndex, useNativeToken ? totalProfit : profitTokenAmount, nonceManager)
164
169
  ]);
165
170
  // ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
@@ -667,17 +672,22 @@ function findMaxIndex(values) {
667
672
  * ✅ 支持 quoteToken 的买入交易构建
668
673
  * 当 inputToken 为非零地址(如 USDC)时,value 为 0
669
674
  */
670
- async function populateBuyTransactionsWithQuote(buyers, portalAddr, tokenAddress, fundsList, inputToken, useNativeToken) {
675
+ async function populateBuyTransactionsWithQuote(buyers, portalAddr, tokenAddress, fundsList, inputToken, useNativeToken, usePortalSwapV3 = false, extensionData = '0x') {
671
676
  const portals = buyers.map(wallet => new ethers.Contract(portalAddr, PORTAL_ABI, wallet));
672
- return await Promise.all(portals.map((portal, i) => portal.swapExactInput.populateTransaction({
673
- inputToken,
674
- outputToken: tokenAddress,
675
- inputAmount: fundsList[i],
676
- minOutputAmount: 0n,
677
- permitData: '0x'
678
- },
679
- // ✅ 如果使用原生代币,value 为购买金额;否则为 0
680
- useNativeToken ? { value: fundsList[i] } : {})));
677
+ return await Promise.all(portals.map((portal, i) => {
678
+ const swapParams = {
679
+ inputToken,
680
+ outputToken: tokenAddress,
681
+ inputAmount: fundsList[i],
682
+ minOutputAmount: 0n,
683
+ permitData: '0x',
684
+ };
685
+ const overrides = useNativeToken ? { value: fundsList[i] } : {};
686
+ if (usePortalSwapV3) {
687
+ return portal.swapExactInputV3.populateTransaction({ ...swapParams, extensionData: extensionData ?? '0x' }, overrides);
688
+ }
689
+ return portal.swapExactInput.populateTransaction(swapParams, overrides);
690
+ }));
681
691
  }
682
692
  function buildGasLimitList(length, config) {
683
693
  const gasLimit = getGasLimit(config);
@@ -3,6 +3,7 @@ import { ADDRESSES, ZERO_ADDRESS } from './constants.js';
3
3
  import { MULTICALL3_ABI, V2_FACTORY_ABI, V2_PAIR_ABI, V3_FACTORY_ABI, ERC20_ABI } from '../shared/abis/common.js';
4
4
  import { Helper3 } from '../contracts/helper3.js';
5
5
  import { FlapPortal } from '../shared/flap/portal.js';
6
+ import { getFlapGraduatedDexMetrics, PCS_INFINITY_CL_POOL_MANAGER_BSC, } from './pcs-infinity-cl.js';
6
7
  // ============================================================================
7
8
  // 链配置
8
9
  // ============================================================================
@@ -360,7 +361,61 @@ export async function inspectTokenLP(token, opts) {
360
361
  if (opts.debug)
361
362
  console.log('[LP Inspect] Flap V7 failed, using V5');
362
363
  }
363
- if (st && st.status !== undefined && Number(st.status) !== 4) {
364
+ if (st && st.status !== undefined) {
365
+ const status = Number(st.status);
366
+ // ✅ 已毕业:PCS Infinity CL 外盘(Portal pool 字段为 CLPoolManager)
367
+ if (status === 4) {
368
+ const quoteAddr = st.quoteTokenAddress && st.quoteTokenAddress.toLowerCase() !== ZERO_ADDRESS
369
+ ? st.quoteTokenAddress
370
+ : chainConfig.wrappedNative;
371
+ let quoteDecimals = 18;
372
+ let quoteSymbol = chainConfig.wrappedNativeSymbol;
373
+ if (quoteAddr.toLowerCase() !== chainConfig.wrappedNative.toLowerCase()) {
374
+ quoteDecimals = await getTokenDecimals(quoteAddr, provider);
375
+ const stableCoin = chainConfig.stableCoins.find(c => c.address.toLowerCase() === quoteAddr.toLowerCase());
376
+ quoteSymbol = stableCoin?.symbol || 'TOKEN';
377
+ }
378
+ const metrics = await getFlapGraduatedDexMetrics({
379
+ portal: flap,
380
+ tokenAddress: token,
381
+ state: st,
382
+ rpcUrl: opts.rpcUrl,
383
+ wrappedNativeAddress: chainConfig.wrappedNative,
384
+ });
385
+ result.platform = 'FLAP';
386
+ result.flap = {
387
+ quoteToken: quoteAddr,
388
+ quoteSymbol,
389
+ quoteDecimals,
390
+ reserveNative: metrics.poolBNBAmount,
391
+ circulatingSupply: formatBalance(st.circulatingSupply, shouldFormat, tokenDecimals ?? 18),
392
+ price: metrics.price,
393
+ taxRate,
394
+ };
395
+ if (taxRate && taxRate > 0)
396
+ result.taxRate = taxRate;
397
+ const liqRaw = metrics.poolBNBAmount
398
+ ? BigInt(Math.floor(parseFloat(metrics.poolBNBAmount) * 1e18))
399
+ : 0n;
400
+ const tokRaw = metrics.poolTokenAmount
401
+ ? BigInt(Math.floor(parseFloat(metrics.poolTokenAmount) * 1e18))
402
+ : 0n;
403
+ result.bestPools.push({
404
+ dex: 'PancakeSwap Infinity CL',
405
+ dexKey: 'PCS_INFINITY_CL',
406
+ version: 'v3',
407
+ fee: metrics.infinityFee,
408
+ quoteToken: quoteAddr,
409
+ quoteSymbol,
410
+ quoteDecimals,
411
+ pairAddress: metrics.poolId ?? PCS_INFINITY_CL_POOL_MANAGER_BSC,
412
+ liquidity: metrics.poolBNBAmount,
413
+ liquidityRaw: liqRaw,
414
+ reserveToken: metrics.poolTokenAmount,
415
+ reserveTokenRaw: tokRaw,
416
+ });
417
+ return result;
418
+ }
364
419
  result.platform = 'FLAP';
365
420
  let quoteDecimals = 18;
366
421
  let quoteSymbol = chainConfig.wrappedNativeSymbol;
@@ -0,0 +1,62 @@
1
+ import type { FlapPortal } from '../shared/flap/portal.js';
2
+ import type { TokenStateV7 } from '../shared/flap/portal.js';
3
+ /** PancakeSwap Infinity CL PoolManager(BSC / Base 同址) */
4
+ export declare const PCS_INFINITY_CL_POOL_MANAGER_BSC = "0xa0FfB9c1CE1Fe56963B0321B32E7A0302114058b";
5
+ /** Flap Portal 毕业到 Infinity CL 时使用的 hooks(BSC) */
6
+ export declare const FLAP_INFINITY_HOOKS_BSC = "0xF1A9aA042454b8553bE3896597ff11a0f011c1c1";
7
+ export type InfinityPoolKey = {
8
+ currency0: string;
9
+ currency1: string;
10
+ hooks: string;
11
+ poolManager: string;
12
+ fee: number;
13
+ parameters: string;
14
+ };
15
+ export declare function sortInfinityCurrencies(a: string, b: string): [string, string];
16
+ export declare function computeInfinityPoolId(key: InfinityPoolKey): string;
17
+ export declare function buildFlapInfinityPoolKey(params: {
18
+ tokenAddress: string;
19
+ quoteTokenAddress: string;
20
+ chain: string;
21
+ lpFeeProfile?: number;
22
+ }): InfinityPoolKey | null;
23
+ /** 由 slot0 计算 quote per token(与 memeweb V3 spot 公式一致) */
24
+ export declare function infinitySpotPriceQuotePerToken(params: {
25
+ sqrtPriceX96: bigint;
26
+ tokenAddress: string;
27
+ currency0: string;
28
+ currency1: string;
29
+ quoteTokenAddress: string;
30
+ tokenDecimals?: number;
31
+ quoteDecimals?: number;
32
+ }): string | null;
33
+ /** 用活跃流动性 L 与 sqrtPrice 估算两侧虚拟储备(UI 展示用) */
34
+ export declare function estimateInfinityReserves(params: {
35
+ liquidity: bigint;
36
+ sqrtPriceX96: bigint;
37
+ tokenIsCurrency0: boolean;
38
+ }): {
39
+ reserveToken: string;
40
+ reserveQuote: string;
41
+ };
42
+ export type GraduatedDexMetrics = {
43
+ price: string;
44
+ progress: string;
45
+ poolBNBAmount: string;
46
+ poolTokenAmount: string;
47
+ poolId?: string;
48
+ infinityFee?: number;
49
+ };
50
+ /**
51
+ * Flap 毕业后(status=4)外盘:PCS Infinity CL + Portal quote
52
+ * getTokenV7().pool 在 V7 标准币上为 CLPoolManager 合约地址,非 V3 pair。
53
+ */
54
+ export declare function getFlapGraduatedDexMetrics(params: {
55
+ portal: FlapPortal;
56
+ tokenAddress: string;
57
+ state: TokenStateV7;
58
+ rpcUrl: string;
59
+ wrappedNativeAddress?: string;
60
+ }): Promise<GraduatedDexMetrics>;
61
+ /** 判断 getTokenV7.pool 是否为 Infinity CL PoolManager(而非 V3 pair) */
62
+ export declare function isInfinityCLPoolManagerAddress(pool: string, chain: string): boolean;
@@ -0,0 +1,224 @@
1
+ import { AbiCoder, Contract, JsonRpcProvider, formatEther, formatUnits, keccak256 } from 'ethers';
2
+ import { FLAP_TOTAL_SUPPLY, ZERO_ADDRESS } from '../shared/flap/constants.js';
3
+ /** PancakeSwap Infinity CL PoolManager(BSC / Base 同址) */
4
+ export const PCS_INFINITY_CL_POOL_MANAGER_BSC = '0xa0FfB9c1CE1Fe56963B0321B32E7A0302114058b';
5
+ /** Flap Portal 毕业到 Infinity CL 时使用的 hooks(BSC) */
6
+ export const FLAP_INFINITY_HOOKS_BSC = '0xF1A9aA042454b8553bE3896597ff11a0f011c1c1';
7
+ const CL_POOL_MANAGER_ABI = [
8
+ 'function getSlot0(bytes32 id) view returns (uint160 sqrtPriceX96, int24 tick, uint24 protocolFee, uint24 lpFee)',
9
+ 'function getLiquidity(bytes32 id) view returns (uint128 liquidity)',
10
+ ];
11
+ /** BSC:lpFeeProfile → Infinity PoolKey 的 fee / parameters(与链上 Initialize 一致) */
12
+ const BSC_INFINITY_POOL_KEY_BY_PROFILE = {
13
+ 0: {
14
+ fee: 8534,
15
+ parameters: '0x0000000000000000000000000000000000000000000000000000000000fa00d5',
16
+ },
17
+ };
18
+ export function sortInfinityCurrencies(a, b) {
19
+ return a.toLowerCase() < b.toLowerCase() ? [a, b] : [b, a];
20
+ }
21
+ export function computeInfinityPoolId(key) {
22
+ const coder = AbiCoder.defaultAbiCoder();
23
+ return keccak256(coder.encode(['address', 'address', 'address', 'address', 'uint24', 'bytes32'], [key.currency0, key.currency1, key.hooks, key.poolManager, key.fee, key.parameters]));
24
+ }
25
+ export function buildFlapInfinityPoolKey(params) {
26
+ const chain = String(params.chain || '').toUpperCase();
27
+ if (chain !== 'BSC')
28
+ return null;
29
+ const meta = BSC_INFINITY_POOL_KEY_BY_PROFILE[Number(params.lpFeeProfile ?? 0)] ??
30
+ BSC_INFINITY_POOL_KEY_BY_PROFILE[0];
31
+ const quote = params.quoteTokenAddress &&
32
+ params.quoteTokenAddress.toLowerCase() !== ZERO_ADDRESS
33
+ ? params.quoteTokenAddress
34
+ : '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'; // WBNB
35
+ const [currency0, currency1] = sortInfinityCurrencies(params.tokenAddress, quote);
36
+ return {
37
+ currency0,
38
+ currency1,
39
+ hooks: FLAP_INFINITY_HOOKS_BSC,
40
+ poolManager: PCS_INFINITY_CL_POOL_MANAGER_BSC,
41
+ fee: meta.fee,
42
+ parameters: meta.parameters,
43
+ };
44
+ }
45
+ function formatRatio(n, d, precision = 18) {
46
+ if (d === 0n)
47
+ return '0';
48
+ const scale = 10n ** BigInt(precision);
49
+ const x = (n * scale) / d;
50
+ const s = x.toString().padStart(precision + 1, '0');
51
+ const int = s.slice(0, -precision);
52
+ const frac = s.slice(-precision).replace(/0+$/, '');
53
+ return frac ? `${int}.${frac}` : int;
54
+ }
55
+ /** 由 slot0 计算 quote per token(与 memeweb V3 spot 公式一致) */
56
+ export function infinitySpotPriceQuotePerToken(params) {
57
+ const tokenLower = params.tokenAddress.toLowerCase();
58
+ const quoteLower = params.quoteTokenAddress.toLowerCase();
59
+ const tokenIs0 = params.currency0.toLowerCase() === tokenLower;
60
+ const tokenIs1 = params.currency1.toLowerCase() === tokenLower;
61
+ const quoteIs0 = params.currency0.toLowerCase() === quoteLower;
62
+ const quoteIs1 = params.currency1.toLowerCase() === quoteLower;
63
+ if ((!tokenIs0 && !tokenIs1) || (!quoteIs0 && !quoteIs1))
64
+ return null;
65
+ const dec0 = params.tokenDecimals ?? 18;
66
+ const dec1 = params.quoteDecimals ?? 18;
67
+ const tokenDec = tokenIs0 ? dec0 : dec1;
68
+ const quoteDec = quoteIs0 ? dec0 : dec1;
69
+ const Q192 = 2n ** 192n;
70
+ const num = params.sqrtPriceX96 * params.sqrtPriceX96;
71
+ let n;
72
+ let d;
73
+ if (tokenIs0) {
74
+ n = num * 10n ** BigInt(tokenDec);
75
+ d = Q192 * 10n ** BigInt(quoteDec);
76
+ }
77
+ else {
78
+ n = Q192 * 10n ** BigInt(quoteDec);
79
+ d = num * 10n ** BigInt(tokenDec);
80
+ }
81
+ return formatRatio(n, d, 18);
82
+ }
83
+ /** 用活跃流动性 L 与 sqrtPrice 估算两侧虚拟储备(UI 展示用) */
84
+ export function estimateInfinityReserves(params) {
85
+ const Q96 = 2n ** 96n;
86
+ if (params.liquidity === 0n || params.sqrtPriceX96 === 0n) {
87
+ return { reserveToken: '0', reserveQuote: '0' };
88
+ }
89
+ // float 估算即可满足面板展示
90
+ const sqrtP = Number(params.sqrtPriceX96) / Number(Q96);
91
+ const L = Number(params.liquidity);
92
+ if (!Number.isFinite(sqrtP) || sqrtP <= 0) {
93
+ return { reserveToken: '0', reserveQuote: '0' };
94
+ }
95
+ const amount1 = (L * sqrtP) / 1e18;
96
+ const amount0 = L / sqrtP / 1e18;
97
+ if (params.tokenIsCurrency0) {
98
+ return { reserveToken: String(amount0), reserveQuote: String(amount1) };
99
+ }
100
+ return { reserveToken: String(amount1), reserveQuote: String(amount0) };
101
+ }
102
+ async function quotePortalPrice(portal, tokenAddress, quoteTokenAddress) {
103
+ try {
104
+ const buyAmt = 10n ** 16n; // 0.01 native
105
+ const sellAmt = 10n ** 21n; // 1000 tokens
106
+ const inputQuote = quoteTokenAddress.toLowerCase() === ZERO_ADDRESS
107
+ ? ZERO_ADDRESS
108
+ : quoteTokenAddress;
109
+ const [tokensOut, quoteOut] = await Promise.all([
110
+ portal.quoteExactInput({
111
+ inputToken: inputQuote,
112
+ outputToken: tokenAddress,
113
+ inputAmount: buyAmt,
114
+ }),
115
+ portal.quoteExactInput({
116
+ inputToken: tokenAddress,
117
+ outputToken: inputQuote,
118
+ inputAmount: sellAmt,
119
+ }),
120
+ ]);
121
+ if (tokensOut <= 0n || quoteOut <= 0n)
122
+ return null;
123
+ const buyPrice = Number(formatEther(buyAmt)) / Number(formatEther(tokensOut));
124
+ const sellPrice = Number(formatEther(quoteOut)) / Number(formatEther(sellAmt));
125
+ return String((buyPrice + sellPrice) / 2);
126
+ }
127
+ catch {
128
+ return null;
129
+ }
130
+ }
131
+ /**
132
+ * Flap 毕业后(status=4)外盘:PCS Infinity CL + Portal quote
133
+ * getTokenV7().pool 在 V7 标准币上为 CLPoolManager 合约地址,非 V3 pair。
134
+ */
135
+ export async function getFlapGraduatedDexMetrics(params) {
136
+ const tokenAddress = params.tokenAddress;
137
+ const quoteToken = params.state.quoteTokenAddress &&
138
+ params.state.quoteTokenAddress.toLowerCase() !== ZERO_ADDRESS
139
+ ? params.state.quoteTokenAddress
140
+ : params.wrappedNativeAddress ?? '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
141
+ const progressRaw = params.state.progress ?? 0n;
142
+ const progress = progressRaw > 10n ** 18n
143
+ ? formatUnits(progressRaw, 18)
144
+ : progressRaw >= 100n
145
+ ? '100'
146
+ : String(progressRaw);
147
+ let price = await quotePortalPrice(params.portal, tokenAddress, quoteToken);
148
+ let poolBNBAmount = '0';
149
+ let poolTokenAmount = '0';
150
+ let poolId;
151
+ let infinityFee;
152
+ const poolKey = buildFlapInfinityPoolKey({
153
+ tokenAddress,
154
+ quoteTokenAddress: quoteToken,
155
+ chain: 'BSC',
156
+ lpFeeProfile: params.state.lpFeeProfile,
157
+ });
158
+ if (poolKey) {
159
+ poolId = computeInfinityPoolId(poolKey);
160
+ infinityFee = poolKey.fee;
161
+ try {
162
+ const provider = new JsonRpcProvider(params.rpcUrl);
163
+ const manager = new Contract(poolKey.poolManager, CL_POOL_MANAGER_ABI, provider);
164
+ const [slot0, liquidity] = await Promise.all([
165
+ manager.getSlot0(poolId),
166
+ manager.getLiquidity(poolId),
167
+ ]);
168
+ const sqrtPriceX96 = BigInt(slot0[0]);
169
+ const liq = BigInt(liquidity);
170
+ if (sqrtPriceX96 > 0n) {
171
+ const tokenIs0 = poolKey.currency0.toLowerCase() === tokenAddress.toLowerCase();
172
+ const spot = infinitySpotPriceQuotePerToken({
173
+ sqrtPriceX96,
174
+ tokenAddress,
175
+ currency0: poolKey.currency0,
176
+ currency1: poolKey.currency1,
177
+ quoteTokenAddress: quoteToken,
178
+ });
179
+ if (spot)
180
+ price = spot;
181
+ const reserves = estimateInfinityReserves({
182
+ liquidity: liq,
183
+ sqrtPriceX96,
184
+ tokenIsCurrency0: tokenIs0,
185
+ });
186
+ poolBNBAmount = reserves.reserveQuote;
187
+ poolTokenAmount = reserves.reserveToken;
188
+ }
189
+ }
190
+ catch {
191
+ // slot0 失败时保留 portal quote 价格
192
+ }
193
+ }
194
+ if (!price)
195
+ price = '0';
196
+ if (poolTokenAmount === '0' || poolTokenAmount === '0.0') {
197
+ try {
198
+ const circ = formatEther(params.state.circulatingSupply ?? 0n);
199
+ const total = formatEther(FLAP_TOTAL_SUPPLY);
200
+ poolTokenAmount = String(Math.max(0, Number(total) - Number(circ)));
201
+ }
202
+ catch {
203
+ poolTokenAmount = '0';
204
+ }
205
+ }
206
+ return {
207
+ price,
208
+ progress,
209
+ poolBNBAmount,
210
+ poolTokenAmount,
211
+ poolId,
212
+ infinityFee,
213
+ };
214
+ }
215
+ /** 判断 getTokenV7.pool 是否为 Infinity CL PoolManager(而非 V3 pair) */
216
+ export function isInfinityCLPoolManagerAddress(pool, chain) {
217
+ if (!pool)
218
+ return false;
219
+ const c = String(chain || '').toUpperCase();
220
+ if (c === 'BSC' || c === 'BASE') {
221
+ return pool.toLowerCase() === PCS_INFINITY_CL_POOL_MANAGER_BSC.toLowerCase();
222
+ }
223
+ return false;
224
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "2.2.11",
3
+ "version": "2.2.13",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",