@flaunch/sdk 0.9.6 → 0.9.7

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.esm.js CHANGED
@@ -25459,6 +25459,10 @@ function maxLiquidityForAmount0Precise(sqrtRatioAX96, sqrtRatioBX96, amount0) {
25459
25459
  if (sqrtRatioAX96 > sqrtRatioBX96) {
25460
25460
  [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
25461
25461
  }
25462
+ // Handle edge case where sqrt ratios are equal (division by zero)
25463
+ if (sqrtRatioAX96 === sqrtRatioBX96) {
25464
+ return 0n;
25465
+ }
25462
25466
  const Q96 = 2n ** 96n;
25463
25467
  const numerator = amount0 * sqrtRatioAX96 * sqrtRatioBX96;
25464
25468
  const denominator = Q96 * (sqrtRatioBX96 - sqrtRatioAX96);
@@ -25475,6 +25479,10 @@ function maxLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1) {
25475
25479
  if (sqrtRatioAX96 > sqrtRatioBX96) {
25476
25480
  [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
25477
25481
  }
25482
+ // Handle edge case where sqrt ratios are equal (division by zero)
25483
+ if (sqrtRatioAX96 === sqrtRatioBX96) {
25484
+ return 0n;
25485
+ }
25478
25486
  const Q96 = 2n ** 96n;
25479
25487
  return (amount1 * Q96) / (sqrtRatioBX96 - sqrtRatioAX96);
25480
25488
  }
@@ -26386,7 +26394,7 @@ class ReadFlaunchSDK {
26386
26394
  * @returns Promise<number> - The current tick of the pool
26387
26395
  */
26388
26396
  async currentTick(coinAddress, version) {
26389
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26397
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26390
26398
  const poolId = await this.poolId(coinAddress, coinVersion);
26391
26399
  const poolState = await this.readStateView.poolSlot0({ poolId });
26392
26400
  return poolState.tick;
@@ -26398,7 +26406,7 @@ class ReadFlaunchSDK {
26398
26406
  * @returns Promise<string> - The price of the coin in ETH with 18 decimals precision
26399
26407
  */
26400
26408
  async coinPriceInETH(coinAddress, version) {
26401
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26409
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26402
26410
  const isFLETHZero = this.flETHIsCurrencyZero(coinAddress);
26403
26411
  const currentTick = await this.currentTick(coinAddress, coinVersion);
26404
26412
  const price = Math.pow(1.0001, currentTick);
@@ -26418,7 +26426,7 @@ class ReadFlaunchSDK {
26418
26426
  * @returns Promise<string> - The price of the coin in USD with 18 decimal precision
26419
26427
  */
26420
26428
  async coinPriceInUSD({ coinAddress, version, drift, }) {
26421
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26429
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26422
26430
  const ethPerCoin = await this.coinPriceInETH(coinAddress, coinVersion);
26423
26431
  const ethPrice = await this.getETHUSDCPrice(drift);
26424
26432
  return (parseFloat(ethPerCoin) * ethPrice).toFixed(18);
@@ -26466,7 +26474,7 @@ class ReadFlaunchSDK {
26466
26474
  * @returns Fair launch information from the appropriate contract version
26467
26475
  */
26468
26476
  async fairLaunchInfo(coinAddress, version) {
26469
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26477
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26470
26478
  const poolId = await this.poolId(coinAddress, coinVersion);
26471
26479
  return this.getFairLaunch(coinVersion).fairLaunchInfo({ poolId });
26472
26480
  }
@@ -26477,12 +26485,12 @@ class ReadFlaunchSDK {
26477
26485
  * @returns Promise<boolean> - True if fair launch is active, false otherwise
26478
26486
  */
26479
26487
  async isFairLaunchActive(coinAddress, version) {
26480
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26488
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26481
26489
  const poolId = await this.poolId(coinAddress, coinVersion);
26482
26490
  return this.getFairLaunch(coinVersion).isFairLaunchActive({ poolId });
26483
26491
  }
26484
26492
  async trustedPoolKeySignerStatus(coinAddress, version) {
26485
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26493
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26486
26494
  if (coinVersion === FlaunchVersion.ANY) {
26487
26495
  throw new Error("AnyPositionManager is not supported for TrustedSigner");
26488
26496
  }
@@ -26531,7 +26539,7 @@ class ReadFlaunchSDK {
26531
26539
  * @returns Promise<number> - The duration in seconds (30 minutes for V1, variable for V1.1)
26532
26540
  */
26533
26541
  async fairLaunchDuration(coinAddress, version) {
26534
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26542
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26535
26543
  const poolId = await this.poolId(coinAddress, coinVersion);
26536
26544
  return this.getFairLaunch(coinVersion).fairLaunchDuration({ poolId });
26537
26545
  }
@@ -26542,7 +26550,7 @@ class ReadFlaunchSDK {
26542
26550
  * @returns Promise<number> - The initial tick value
26543
26551
  */
26544
26552
  async initialTick(coinAddress, version) {
26545
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26553
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26546
26554
  const poolId = await this.poolId(coinAddress, coinVersion);
26547
26555
  const fairLaunchInfo = await this.getFairLaunch(coinVersion).fairLaunchInfo({ poolId });
26548
26556
  return fairLaunchInfo.initialTick;
@@ -26554,7 +26562,7 @@ class ReadFlaunchSDK {
26554
26562
  * @returns Promise<{flETHAmount: bigint, coinAmount: bigint, tickLower: number, tickUpper: number}> - Position details
26555
26563
  */
26556
26564
  async fairLaunchETHOnlyPosition(coinAddress, version) {
26557
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26565
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26558
26566
  const poolId = await this.poolId(coinAddress, coinVersion);
26559
26567
  const initialTick = await this.initialTick(coinAddress, coinVersion);
26560
26568
  const currentTick = await this.currentTick(coinAddress, coinVersion);
@@ -26602,7 +26610,7 @@ class ReadFlaunchSDK {
26602
26610
  * @returns Promise<{flETHAmount: bigint, coinAmount: bigint, tickLower: number, tickUpper: number}> - Position details
26603
26611
  */
26604
26612
  async fairLaunchCoinOnlyPosition(coinAddress, version) {
26605
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26613
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26606
26614
  const poolId = await this.poolId(coinAddress, coinVersion);
26607
26615
  const initialTick = await this.initialTick(coinAddress, coinVersion);
26608
26616
  const currentTick = await this.currentTick(coinAddress, coinVersion);
@@ -26650,7 +26658,7 @@ class ReadFlaunchSDK {
26650
26658
  * @returns Promise<{flETHAmount: bigint, coinAmount: bigint, pendingEth: bigint, tickLower: number, tickUpper: number}> - Bid wall position details
26651
26659
  */
26652
26660
  async bidWallPosition(coinAddress, version) {
26653
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26661
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26654
26662
  const poolId = await this.poolId(coinAddress, coinVersion);
26655
26663
  const isFLETHZero = this.flETHIsCurrencyZero(coinAddress);
26656
26664
  const { amount0_: amount0, amount1_: amount1, pendingEth_: pendingEth, } = await this.getBidWall(coinVersion).position({ poolId });
@@ -26766,13 +26774,8 @@ class ReadFlaunchSDK {
26766
26774
  */
26767
26775
  async poolId(coinAddress, version) {
26768
26776
  let hookAddress;
26769
- if (version) {
26770
- hookAddress = this.getPositionManagerAddress(version);
26771
- }
26772
- else {
26773
- const coinVersion = await this.getCoinVersion(coinAddress);
26774
- hookAddress = this.getPositionManagerAddress(coinVersion);
26775
- }
26777
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26778
+ hookAddress = this.getPositionManagerAddress(coinVersion);
26776
26779
  return getPoolId(orderPoolKey({
26777
26780
  currency0: FLETHAddress[this.chainId],
26778
26781
  currency1: coinAddress,
@@ -26830,7 +26833,7 @@ class ReadFlaunchSDK {
26830
26833
  * @returns Promise<bigint> - The expected amount of ETH to receive
26831
26834
  */
26832
26835
  async getSellQuoteExactInput({ coinAddress, version, amountIn, intermediatePoolKey, }) {
26833
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26836
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26834
26837
  return this.readQuoter.getSellQuoteExactInput({
26835
26838
  coinAddress,
26836
26839
  amountIn,
@@ -26849,7 +26852,7 @@ class ReadFlaunchSDK {
26849
26852
  * @returns Promise<bigint> - The expected amount of coins to receive
26850
26853
  */
26851
26854
  async getBuyQuoteExactInput({ coinAddress, version, amountIn, intermediatePoolKey, hookData, userWallet, }) {
26852
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26855
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26853
26856
  return this.readQuoter.getBuyQuoteExactInput({
26854
26857
  coinAddress,
26855
26858
  amountIn,
@@ -26870,7 +26873,7 @@ class ReadFlaunchSDK {
26870
26873
  * @returns Promise<bigint> - The required amount of ETH or inputToken to spend
26871
26874
  */
26872
26875
  async getBuyQuoteExactOutput({ coinAddress, amountOut, version, intermediatePoolKey, hookData, userWallet, }) {
26873
- const coinVersion = version || (await this.getCoinVersion(coinAddress));
26876
+ const coinVersion = await this.determineCoinVersion(coinAddress, version);
26874
26877
  return this.readQuoter.getBuyQuoteExactOutput({
26875
26878
  coinAddress,
26876
26879
  coinOut: amountOut,
@@ -27057,24 +27060,9 @@ class ReadFlaunchSDK {
27057
27060
  });
27058
27061
  // If no current tick is provided from the above calculation, get it from the pool state
27059
27062
  if (!currentTick) {
27060
- let version = params.version;
27061
- // if version is not provided, check on existing managers, else default to ANY
27062
- if (!version) {
27063
- try {
27064
- version = await this.getCoinVersion(coinAddress);
27065
- }
27066
- catch {
27067
- version = FlaunchVersion.ANY;
27068
- }
27069
- }
27063
+ const version = await this.determineCoinVersion(coinAddress, params.version);
27070
27064
  const poolState = await this.readStateView.poolSlot0({
27071
- poolId: getPoolId(orderPoolKey({
27072
- currency0: coinAddress,
27073
- currency1: FLETHAddress[this.chainId],
27074
- fee: 0,
27075
- tickSpacing: TICK_SPACING,
27076
- hooks: this.getPositionManagerAddress(version),
27077
- })),
27065
+ poolId: getPoolId(this.createPoolKey(coinAddress, version)),
27078
27066
  });
27079
27067
  currentTick = poolState.tick;
27080
27068
  }
@@ -27148,24 +27136,9 @@ class ReadFlaunchSDK {
27148
27136
  });
27149
27137
  // get the current pool state for the coin
27150
27138
  if (!currentTick) {
27151
- let version = params.version;
27152
- // if version is not provided, check on existing managers, else default to ANY
27153
- if (!version) {
27154
- try {
27155
- version = await this.getCoinVersion(coinAddress);
27156
- }
27157
- catch {
27158
- version = FlaunchVersion.ANY;
27159
- }
27160
- }
27139
+ const version = await this.determineCoinVersion(coinAddress, params.version);
27161
27140
  const poolState = await this.readStateView.poolSlot0({
27162
- poolId: getPoolId(orderPoolKey({
27163
- currency0: coinAddress,
27164
- currency1: FLETHAddress[this.chainId],
27165
- fee: 0,
27166
- tickSpacing: TICK_SPACING,
27167
- hooks: this.getPositionManagerAddress(version),
27168
- })),
27141
+ poolId: getPoolId(this.createPoolKey(coinAddress, version)),
27169
27142
  });
27170
27143
  currentTick = poolState.tick;
27171
27144
  }
@@ -27320,6 +27293,39 @@ class ReadFlaunchSDK {
27320
27293
  args: { owner, operator },
27321
27294
  });
27322
27295
  }
27296
+ /**
27297
+ * Determines the version for a coin, using provided version or fetching it
27298
+ * @param coinAddress - The coin address
27299
+ * @param version - Optional version, if not provided will be fetched
27300
+ * @returns The determined version
27301
+ */
27302
+ async determineCoinVersion(coinAddress, version) {
27303
+ if (!version) {
27304
+ try {
27305
+ version = await this.getCoinVersion(coinAddress);
27306
+ }
27307
+ catch {
27308
+ version = FlaunchVersion.ANY;
27309
+ }
27310
+ }
27311
+ return version;
27312
+ }
27313
+ /**
27314
+ * Creates a pool key for the given coin and version
27315
+ * @param coinAddress - The coin address
27316
+ * @param version - The version to use for position manager
27317
+ * @returns The ordered pool key
27318
+ */
27319
+ createPoolKey(coinAddress, version) {
27320
+ const flethAddress = FLETHAddress[this.chainId];
27321
+ return orderPoolKey({
27322
+ currency0: coinAddress,
27323
+ currency1: flethAddress,
27324
+ fee: 0,
27325
+ tickSpacing: this.TICK_SPACING,
27326
+ hooks: this.getPositionManagerAddress(version),
27327
+ });
27328
+ }
27323
27329
  }
27324
27330
  class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
27325
27331
  constructor(chainId, drift = createDrift$1(), publicClient) {
@@ -27444,7 +27450,7 @@ class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
27444
27450
  * @returns Transaction response for the buy operation
27445
27451
  */
27446
27452
  async buyCoin(params, version) {
27447
- const coinVersion = version || (await this.getCoinVersion(params.coinAddress));
27453
+ const coinVersion = await this.determineCoinVersion(params.coinAddress, version);
27448
27454
  const sender = await this.drift.getSignerAddress();
27449
27455
  let amountIn;
27450
27456
  let amountOutMin;
@@ -27529,7 +27535,7 @@ class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
27529
27535
  * @returns Transaction response for the sell operation
27530
27536
  */
27531
27537
  async sellCoin(params, version) {
27532
- const coinVersion = version || (await this.getCoinVersion(params.coinAddress));
27538
+ const coinVersion = await this.determineCoinVersion(params.coinAddress, version);
27533
27539
  let amountOutMin;
27534
27540
  await this.readQuoter.contract.cache.clear();
27535
27541
  if (params.amountOutMin === undefined) {
@@ -27752,22 +27758,8 @@ class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
27752
27758
  let tickLower;
27753
27759
  let tickUpper;
27754
27760
  let currentTick;
27755
- let version = params.version;
27756
- if (!version) {
27757
- try {
27758
- version = await this.getCoinVersion(coinAddress);
27759
- }
27760
- catch {
27761
- version = FlaunchVersion.ANY;
27762
- }
27763
- }
27764
- const poolKey = orderPoolKey({
27765
- currency0: coinAddress,
27766
- currency1: flethAddress,
27767
- fee: 0,
27768
- tickSpacing: this.TICK_SPACING,
27769
- hooks: this.getPositionManagerAddress(version),
27770
- });
27761
+ const version = await this.determineCoinVersion(coinAddress, params.version);
27762
+ const poolKey = this.createPoolKey(coinAddress, version);
27771
27763
  // Check if we need to calculate values or use direct values
27772
27764
  if ("tickLower" in params) {
27773
27765
  // Use the directly provided values
@@ -27965,6 +27957,173 @@ class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
27965
27957
  // Determine amounts for each currency based on pool key ordering
27966
27958
  const amount0 = poolKey.currency0 === coinAddress ? coinAmount : flethAmount;
27967
27959
  const amount1 = poolKey.currency0 === coinAddress ? flethAmount : coinAmount;
27960
+ // Calculate and constrain liquidity using shared method
27961
+ const { finalLiquidity, finalAmount0, finalAmount1 } = this.calculateConstrainedLiquidity(currentTick, tickLower, tickUpper, amount0, amount1);
27962
+ // 6. Add liquidity
27963
+ calls.push(this.createLiquidityCall(poolKey, tickLower, tickUpper, finalLiquidity, finalAmount0, finalAmount1, userAddress));
27964
+ return calls;
27965
+ }
27966
+ /**
27967
+ * Gets the calls needed to import a memecoin to Flaunch and add liquidity to AnyPositionManager as a batch
27968
+ * @param params - Parameters for importing and adding liquidity
27969
+ * @returns Array of calls with descriptions
27970
+ */
27971
+ async getImportAndAddLiquidityCalls(params) {
27972
+ const importParams = await this.readWriteTokenImporter.getInitializeParams({
27973
+ coinAddress: params.coinAddress,
27974
+ creatorFeeAllocationPercent: params.creatorFeeAllocationPercent,
27975
+ initialMarketCapUSD: params.initialMarketCapUSD,
27976
+ verifier: params.verifier,
27977
+ });
27978
+ const addLiquidityCalls = await this.getAddLiquidityCalls({
27979
+ ...params,
27980
+ version: FlaunchVersion.ANY, // optimize to avoid fetching if not passed
27981
+ });
27982
+ return [
27983
+ {
27984
+ to: this.readWriteTokenImporter.contract.address,
27985
+ data: this.readWriteTokenImporter.contract.encodeFunctionData("initialize", importParams),
27986
+ description: "Import Memecoin to Flaunch",
27987
+ },
27988
+ ...addLiquidityCalls,
27989
+ ];
27990
+ }
27991
+ /**
27992
+ * Gets the calls needed to add single-sided liquidity in coin from current tick to infinity
27993
+ * @param params - Parameters for adding single-sided liquidity
27994
+ * @returns Array of calls with descriptions
27995
+ */
27996
+ async getSingleSidedCoinAddLiquidityCalls(params) {
27997
+ const { coinAddress, coinAmount } = params;
27998
+ const version = await this.determineCoinVersion(coinAddress, params.version);
27999
+ const poolKey = this.createPoolKey(coinAddress, version);
28000
+ // get the current tick from the pool
28001
+ const poolState = await this.readStateView.poolSlot0({
28002
+ poolId: getPoolId(poolKey),
28003
+ });
28004
+ const currentTick = poolState.tick;
28005
+ // We want to add liquidity from current price to infinity (as coin appreciates vs flETH)
28006
+ // This means providing single-sided coin liquidity that becomes active as coin price increases
28007
+ const isFLETHZero = this.flETHIsCurrencyZero(coinAddress);
28008
+ let tickLower;
28009
+ let tickUpper;
28010
+ if (isFLETHZero) {
28011
+ // flETH is currency0, coin is currency1
28012
+ // Price = coin/flETH. As coin appreciates, price and tick increase.
28013
+ // For single-sided coin position, we need the range to end at current tick
28014
+ // so as price increases beyond current, position becomes coin-only
28015
+ tickLower = TickFinder.MIN_TICK;
28016
+ tickUpper = getValidTick({
28017
+ tick: currentTick,
28018
+ tickSpacing: this.TICK_SPACING,
28019
+ roundDown: true,
28020
+ });
28021
+ }
28022
+ else {
28023
+ // coin is currency0, flETH is currency1
28024
+ // Price = flETH/coin. As coin appreciates, price decreases and tick decreases.
28025
+ // For single-sided coin position, we need the range to start at current tick
28026
+ // so as price decreases below current, position becomes coin-only
28027
+ tickLower = getValidTick({
28028
+ tick: currentTick,
28029
+ tickSpacing: this.TICK_SPACING,
28030
+ roundDown: false,
28031
+ });
28032
+ tickUpper = TickFinder.MAX_TICK;
28033
+ }
28034
+ // Fetch approvals via multicall
28035
+ const userAddress = await this.drift.getSignerAddress();
28036
+ const permit2Address = Permit2Address[this.chainId];
28037
+ const results = await this.drift.multicall({
28038
+ calls: [
28039
+ // coin -> permit2
28040
+ {
28041
+ address: coinAddress,
28042
+ abi: erc20Abi,
28043
+ fn: "allowance",
28044
+ args: {
28045
+ owner: userAddress,
28046
+ spender: permit2Address,
28047
+ },
28048
+ },
28049
+ // coin --permit2--> uni position manager
28050
+ {
28051
+ address: permit2Address,
28052
+ abi: Permit2Abi,
28053
+ fn: "allowance",
28054
+ args: {
28055
+ 0: userAddress,
28056
+ 1: coinAddress,
28057
+ 2: UniV4PositionManagerAddress[this.chainId],
28058
+ },
28059
+ },
28060
+ // coin symbol
28061
+ {
28062
+ address: coinAddress,
28063
+ abi: erc20Abi,
28064
+ fn: "symbol",
28065
+ },
28066
+ ],
28067
+ });
28068
+ const coinToPermit2 = results[0].value;
28069
+ const permit2ToUniPosManagerCoinAllowance = results[1].value;
28070
+ const coinSymbol = results[2].value;
28071
+ const needsCoinApproval = coinToPermit2 < coinAmount;
28072
+ const currentTime = Math.floor(Date.now() / 1000);
28073
+ const needsCoinPermit2Approval = permit2ToUniPosManagerCoinAllowance.amount < coinAmount ||
28074
+ permit2ToUniPosManagerCoinAllowance.expiration <= currentTime;
28075
+ const calls = [];
28076
+ // 1. Coin approval to Permit2
28077
+ if (needsCoinApproval) {
28078
+ calls.push({
28079
+ to: coinAddress,
28080
+ description: `Approve ${coinSymbol} for Permit2`,
28081
+ data: encodeFunctionData({
28082
+ abi: erc20Abi,
28083
+ functionName: "approve",
28084
+ args: [permit2Address, coinAmount],
28085
+ }),
28086
+ });
28087
+ }
28088
+ // 2. Permit2 approval for coin to uni position manager
28089
+ const expiration = Math.floor(Date.now() / 1000) + 3600; // 1 hour from now
28090
+ if (needsCoinPermit2Approval) {
28091
+ calls.push({
28092
+ to: permit2Address,
28093
+ description: `Permit2 approval for ${coinSymbol} to UniV4PositionManager`,
28094
+ data: encodeFunctionData({
28095
+ abi: Permit2Abi,
28096
+ functionName: "approve",
28097
+ args: [
28098
+ coinAddress,
28099
+ UniV4PositionManagerAddress[this.chainId],
28100
+ coinAmount,
28101
+ expiration,
28102
+ ],
28103
+ }),
28104
+ });
28105
+ }
28106
+ // === generate add liquidity call ===
28107
+ // Determine amounts for each currency based on pool key ordering
28108
+ const flethAmount = 0n;
28109
+ const amount0 = poolKey.currency0 === coinAddress ? coinAmount : flethAmount;
28110
+ const amount1 = poolKey.currency0 === coinAddress ? flethAmount : coinAmount;
28111
+ // Calculate and constrain liquidity using shared method
28112
+ const { finalLiquidity, finalAmount0, finalAmount1 } = this.calculateConstrainedLiquidity(currentTick, tickLower, tickUpper, amount0, amount1);
28113
+ // 3. Add liquidity
28114
+ calls.push(this.createLiquidityCall(poolKey, tickLower, tickUpper, finalLiquidity, finalAmount0, finalAmount1, userAddress));
28115
+ return calls;
28116
+ }
28117
+ /**
28118
+ * Calculates and constrains liquidity amounts for a position
28119
+ * @param currentTick - Current pool tick
28120
+ * @param tickLower - Lower tick of the position
28121
+ * @param tickUpper - Upper tick of the position
28122
+ * @param amount0 - Amount of currency0
28123
+ * @param amount1 - Amount of currency1
28124
+ * @returns Final liquidity and amounts
28125
+ */
28126
+ calculateConstrainedLiquidity(currentTick, tickLower, tickUpper, amount0, amount1) {
27968
28127
  // Calculate liquidity first using user's input amounts
27969
28128
  const initialLiquidity = getLiquidityFromAmounts({
27970
28129
  currentTick,
@@ -28030,7 +28189,25 @@ class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
28030
28189
  }
28031
28190
  finalAmount0 = amount0; // Use user's full amount as maximum
28032
28191
  finalAmount1 = amount1; // Use user's full amount as maximum
28033
- // Prepare mint position parameters (following swiss-knife pattern)
28192
+ return {
28193
+ finalLiquidity,
28194
+ finalAmount0,
28195
+ finalAmount1,
28196
+ };
28197
+ }
28198
+ /**
28199
+ * Creates the UniV4 Position Manager liquidity call
28200
+ * @param poolKey - The pool key
28201
+ * @param tickLower - Lower tick of the position
28202
+ * @param tickUpper - Upper tick of the position
28203
+ * @param finalLiquidity - Final liquidity amount
28204
+ * @param finalAmount0 - Final amount of currency0
28205
+ * @param finalAmount1 - Final amount of currency1
28206
+ * @param userAddress - User's address
28207
+ * @returns CallWithDescription for adding liquidity
28208
+ */
28209
+ createLiquidityCall(poolKey, tickLower, tickUpper, finalLiquidity, finalAmount0, finalAmount1, userAddress) {
28210
+ // Prepare mint position parameters
28034
28211
  const V4PMActions = {
28035
28212
  MINT_POSITION: "02",
28036
28213
  SETTLE_PAIR: "0d",
@@ -28084,8 +28261,7 @@ class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
28084
28261
  currency1: poolKey.currency1,
28085
28262
  },
28086
28263
  ]);
28087
- // 6. Add liquidity
28088
- calls.push({
28264
+ return {
28089
28265
  to: UniV4PositionManagerAddress[this.chainId],
28090
28266
  data: encodeFunctionData({
28091
28267
  abi: [
@@ -28111,33 +28287,7 @@ class ReadWriteFlaunchSDK extends ReadFlaunchSDK {
28111
28287
  }),
28112
28288
  value: 0n,
28113
28289
  description: "Add Liquidity",
28114
- });
28115
- return calls;
28116
- }
28117
- /**
28118
- * Gets the calls needed to import a memecoin to Flaunch and add liquidity to AnyPositionManager as a batch
28119
- * @param params - Parameters for importing and adding liquidity
28120
- * @returns Array of calls with descriptions
28121
- */
28122
- async getImportAndAddLiquidityCalls(params) {
28123
- const importParams = await this.readWriteTokenImporter.getInitializeParams({
28124
- coinAddress: params.coinAddress,
28125
- creatorFeeAllocationPercent: params.creatorFeeAllocationPercent,
28126
- initialMarketCapUSD: params.initialMarketCapUSD,
28127
- verifier: params.verifier,
28128
- });
28129
- const addLiquidityCalls = await this.getAddLiquidityCalls({
28130
- ...params,
28131
- version: FlaunchVersion.ANY, // optimize to avoid fetching if not passed
28132
- });
28133
- return [
28134
- {
28135
- to: this.readWriteTokenImporter.contract.address,
28136
- data: this.readWriteTokenImporter.contract.encodeFunctionData("initialize", importParams),
28137
- description: "Import Memecoin to Flaunch",
28138
- },
28139
- ...addLiquidityCalls,
28140
- ];
28290
+ };
28141
28291
  }
28142
28292
  }
28143
28293