@stabbleorg/mclmm-sdk 0.3.2 → 0.3.3

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/lib/index.js CHANGED
@@ -66,6 +66,7 @@ __export(index_exports, {
66
66
  PoolManager: () => PoolManager,
67
67
  PoolUtils: () => PoolUtils,
68
68
  PositionManager: () => PositionManager,
69
+ PositionUtils: () => PositionUtils,
69
70
  PriceApiClient: () => PriceApiClient,
70
71
  Q128: () => Q128,
71
72
  Q64: () => Q64,
@@ -5348,6 +5349,22 @@ var TickUtils = class _TickUtils {
5348
5349
  );
5349
5350
  }
5350
5351
  }
5352
+ static getTickOffsetInArray(tickIndex, tickSpacing) {
5353
+ if (tickIndex % tickSpacing != 0) {
5354
+ throw new Error("tickIndex % tickSpacing not equal 0");
5355
+ }
5356
+ const startTickIndex = _TickUtils.getTickArrayStartIndexByTick(
5357
+ tickIndex,
5358
+ tickSpacing
5359
+ );
5360
+ const offsetInArray = Math.floor(
5361
+ (tickIndex - startTickIndex) / tickSpacing
5362
+ );
5363
+ if (offsetInArray < 0 || offsetInArray >= TICK_ARRAY_SIZE) {
5364
+ throw new Error("tick offset in array overflow");
5365
+ }
5366
+ return offsetInArray;
5367
+ }
5351
5368
  /**
5352
5369
  * Get the start index of the tick array containing a specific tick
5353
5370
  * @param tick - Target tick
@@ -7471,6 +7488,268 @@ var PoolUtils = class {
7471
7488
  }
7472
7489
  };
7473
7490
 
7491
+ // src/utils/position.ts
7492
+ var import_bn5 = __toESM(require("bn.js"));
7493
+ var PositionUtils = class _PositionUtils {
7494
+ /**
7495
+ * Calculate fee growth inside a position's tick range.
7496
+ *
7497
+ * formula:
7498
+ * ```
7499
+ * feeGrowthInside = feeGrowthGlobal - feeGrowthBelow - feeGrowthAbove
7500
+ * ```
7501
+ *
7502
+ * Where feeGrowthBelow and feeGrowthAbove depend on the current tick
7503
+ * relative to the position's tick boundaries.
7504
+ *
7505
+ * @param params - Parameters for fee growth calculation
7506
+ * @returns Fee growth inside for both tokens (X64 fixed-point)
7507
+ */
7508
+ static getFeeGrowthInside(params) {
7509
+ const {
7510
+ tickCurrent,
7511
+ tickLower,
7512
+ tickUpper,
7513
+ tickLowerState,
7514
+ tickUpperState,
7515
+ feeGrowthGlobal0X64,
7516
+ feeGrowthGlobal1X64
7517
+ } = params;
7518
+ const feeGrowthGlobal0 = new import_bn5.default(feeGrowthGlobal0X64.toString());
7519
+ const feeGrowthGlobal1 = new import_bn5.default(feeGrowthGlobal1X64.toString());
7520
+ const tickLowerFeeGrowthOutside0 = new import_bn5.default(
7521
+ tickLowerState.feeGrowthOutside0X64.toString()
7522
+ );
7523
+ const tickLowerFeeGrowthOutside1 = new import_bn5.default(
7524
+ tickLowerState.feeGrowthOutside1X64.toString()
7525
+ );
7526
+ const tickUpperFeeGrowthOutside0 = new import_bn5.default(
7527
+ tickUpperState.feeGrowthOutside0X64.toString()
7528
+ );
7529
+ const tickUpperFeeGrowthOutside1 = new import_bn5.default(
7530
+ tickUpperState.feeGrowthOutside1X64.toString()
7531
+ );
7532
+ let feeGrowthBelow0X64;
7533
+ let feeGrowthBelow1X64;
7534
+ if (tickCurrent >= tickLower) {
7535
+ feeGrowthBelow0X64 = tickLowerFeeGrowthOutside0;
7536
+ feeGrowthBelow1X64 = tickLowerFeeGrowthOutside1;
7537
+ } else {
7538
+ feeGrowthBelow0X64 = MathUtils.wrappingSubU128(
7539
+ feeGrowthGlobal0,
7540
+ tickLowerFeeGrowthOutside0
7541
+ );
7542
+ feeGrowthBelow1X64 = MathUtils.wrappingSubU128(
7543
+ feeGrowthGlobal1,
7544
+ tickLowerFeeGrowthOutside1
7545
+ );
7546
+ }
7547
+ let feeGrowthAbove0X64;
7548
+ let feeGrowthAbove1X64;
7549
+ if (tickCurrent < tickUpper) {
7550
+ feeGrowthAbove0X64 = tickUpperFeeGrowthOutside0;
7551
+ feeGrowthAbove1X64 = tickUpperFeeGrowthOutside1;
7552
+ } else {
7553
+ feeGrowthAbove0X64 = MathUtils.wrappingSubU128(
7554
+ feeGrowthGlobal0,
7555
+ tickUpperFeeGrowthOutside0
7556
+ );
7557
+ feeGrowthAbove1X64 = MathUtils.wrappingSubU128(
7558
+ feeGrowthGlobal1,
7559
+ tickUpperFeeGrowthOutside1
7560
+ );
7561
+ }
7562
+ const feeGrowthInside0X64 = MathUtils.wrappingSubU128(
7563
+ MathUtils.wrappingSubU128(feeGrowthGlobal0, feeGrowthBelow0X64),
7564
+ feeGrowthAbove0X64
7565
+ );
7566
+ const feeGrowthInside1X64 = MathUtils.wrappingSubU128(
7567
+ MathUtils.wrappingSubU128(feeGrowthGlobal1, feeGrowthBelow1X64),
7568
+ feeGrowthAbove1X64
7569
+ );
7570
+ return {
7571
+ feeGrowthInside0X64,
7572
+ feeGrowthInside1X64
7573
+ };
7574
+ }
7575
+ /**
7576
+ * Calculate pending fees for a position.
7577
+ *
7578
+ * Formula:
7579
+ * ```
7580
+ * feeDelta = (feeGrowthInside - feeGrowthInsideLast) × liquidity / 2^64
7581
+ * totalFees = tokenFeesOwed + feeDelta
7582
+ * ```
7583
+ *
7584
+ * @param params - Parameters for fee calculation
7585
+ * @returns Pending fees for both tokens in native units
7586
+ */
7587
+ static getPositionFees(params) {
7588
+ const {
7589
+ liquidity,
7590
+ tickLower,
7591
+ tickUpper,
7592
+ feeGrowthInside0LastX64,
7593
+ feeGrowthInside1LastX64,
7594
+ tokenFeesOwed0,
7595
+ tokenFeesOwed1,
7596
+ tickCurrent,
7597
+ feeGrowthGlobal0X64,
7598
+ feeGrowthGlobal1X64,
7599
+ tickLowerState,
7600
+ tickUpperState
7601
+ } = params;
7602
+ const { feeGrowthInside0X64, feeGrowthInside1X64 } = _PositionUtils.getFeeGrowthInside({
7603
+ tickCurrent,
7604
+ tickLower,
7605
+ tickUpper,
7606
+ tickLowerState,
7607
+ tickUpperState,
7608
+ feeGrowthGlobal0X64,
7609
+ feeGrowthGlobal1X64
7610
+ });
7611
+ const liquidityBN = new import_bn5.default(liquidity.toString());
7612
+ const feeGrowthInside0Last = new import_bn5.default(feeGrowthInside0LastX64.toString());
7613
+ const feeGrowthInside1Last = new import_bn5.default(feeGrowthInside1LastX64.toString());
7614
+ const feesOwed0 = new import_bn5.default(tokenFeesOwed0.toString());
7615
+ const feesOwed1 = new import_bn5.default(tokenFeesOwed1.toString());
7616
+ const feeGrowthDelta0 = MathUtils.wrappingSubU128(
7617
+ feeGrowthInside0X64,
7618
+ feeGrowthInside0Last
7619
+ );
7620
+ const feeGrowthDelta1 = MathUtils.wrappingSubU128(
7621
+ feeGrowthInside1X64,
7622
+ feeGrowthInside1Last
7623
+ );
7624
+ const feeAmount0 = MathUtils.mulDivFloor(feeGrowthDelta0, liquidityBN, Q64);
7625
+ const feeAmount1 = MathUtils.mulDivFloor(feeGrowthDelta1, liquidityBN, Q64);
7626
+ return {
7627
+ tokenFees0: feesOwed0.add(feeAmount0),
7628
+ tokenFees1: feesOwed1.add(feeAmount1)
7629
+ };
7630
+ }
7631
+ /**
7632
+ * Calculate reward growth inside a position's tick range for all reward tokens.
7633
+ *
7634
+ * Formula:
7635
+ * ```
7636
+ * rewardGrowthInside = rewardGrowthGlobal - rewardGrowthBelow - rewardGrowthAbove
7637
+ * ```
7638
+ *
7639
+ * Special cases:
7640
+ * - If tickLower has no liquidity (liquidityGross = 0), rewardGrowthBelow = rewardGrowthGlobal
7641
+ * - If tickUpper has no liquidity (liquidityGross = 0), rewardGrowthAbove = 0
7642
+ *
7643
+ * @param params - Parameters for reward growth calculation
7644
+ * @returns Reward growth inside for each reward token (X64 fixed-point)
7645
+ */
7646
+ static getRewardGrowthInside(params) {
7647
+ const {
7648
+ tickCurrent,
7649
+ tickLower,
7650
+ tickUpper,
7651
+ tickLowerState,
7652
+ tickUpperState,
7653
+ rewardInfos
7654
+ } = params;
7655
+ const rewardGrowthsInside = [];
7656
+ for (let i = 0; i < rewardInfos.length; i++) {
7657
+ const rewardGrowthGlobal = new import_bn5.default(
7658
+ rewardInfos[i].rewardGrowthGlobalX64.toString()
7659
+ );
7660
+ let rewardGrowthBelow;
7661
+ if (tickLowerState.liquidityGross === 0n) {
7662
+ rewardGrowthBelow = rewardGrowthGlobal;
7663
+ } else if (tickCurrent < tickLower) {
7664
+ rewardGrowthBelow = rewardGrowthGlobal.sub(
7665
+ new import_bn5.default(tickLowerState.rewardGrowthsOutsideX64[i].toString())
7666
+ );
7667
+ } else {
7668
+ rewardGrowthBelow = new import_bn5.default(
7669
+ tickLowerState.rewardGrowthsOutsideX64[i].toString()
7670
+ );
7671
+ }
7672
+ let rewardGrowthAbove;
7673
+ if (tickUpperState.liquidityGross === 0n) {
7674
+ rewardGrowthAbove = new import_bn5.default(0);
7675
+ } else if (tickCurrent < tickUpper) {
7676
+ rewardGrowthAbove = new import_bn5.default(
7677
+ tickUpperState.rewardGrowthsOutsideX64[i].toString()
7678
+ );
7679
+ } else {
7680
+ rewardGrowthAbove = rewardGrowthGlobal.sub(
7681
+ new import_bn5.default(tickUpperState.rewardGrowthsOutsideX64[i].toString())
7682
+ );
7683
+ }
7684
+ const rewardGrowthInside = MathUtils.wrappingSubU128(
7685
+ MathUtils.wrappingSubU128(rewardGrowthGlobal, rewardGrowthBelow),
7686
+ rewardGrowthAbove
7687
+ );
7688
+ rewardGrowthsInside.push(rewardGrowthInside);
7689
+ }
7690
+ return rewardGrowthsInside;
7691
+ }
7692
+ /**
7693
+ * Calculate pending rewards for a position.
7694
+ *
7695
+ * Formula:
7696
+ * ```
7697
+ * rewardDelta = (rewardGrowthInside - rewardGrowthInsideLast) × liquidity / 2^64
7698
+ * totalReward = rewardAmountOwed + rewardDelta
7699
+ * ```
7700
+ *
7701
+ * @param params - Parameters for reward calculation
7702
+ * @returns Pending rewards for each reward token in native units
7703
+ */
7704
+ static getPositionRewards(params) {
7705
+ const {
7706
+ liquidity,
7707
+ tickLower,
7708
+ tickUpper,
7709
+ positionRewardInfos,
7710
+ tickCurrent,
7711
+ rewardInfos,
7712
+ tickLowerState,
7713
+ tickUpperState
7714
+ } = params;
7715
+ const rewardGrowthsInside = _PositionUtils.getRewardGrowthInside({
7716
+ tickCurrent,
7717
+ tickLower,
7718
+ tickUpper,
7719
+ tickLowerState,
7720
+ tickUpperState,
7721
+ rewardInfos
7722
+ });
7723
+ const liquidityBN = new import_bn5.default(liquidity.toString());
7724
+ const rewards = [];
7725
+ for (let i = 0; i < rewardGrowthsInside.length; i++) {
7726
+ const rewardGrowthInside = rewardGrowthsInside[i];
7727
+ const positionRewardInfo = positionRewardInfos[i];
7728
+ if (!positionRewardInfo) {
7729
+ rewards.push(new import_bn5.default(0));
7730
+ continue;
7731
+ }
7732
+ const growthInsideLast = new import_bn5.default(
7733
+ positionRewardInfo.growthInsideLastX64.toString()
7734
+ );
7735
+ const rewardAmountOwed = new import_bn5.default(
7736
+ positionRewardInfo.rewardAmountOwed.toString()
7737
+ );
7738
+ const rewardGrowthDelta = MathUtils.wrappingSubU128(
7739
+ rewardGrowthInside,
7740
+ growthInsideLast
7741
+ );
7742
+ const rewardAmountDelta = MathUtils.mulDivFloor(
7743
+ rewardGrowthDelta,
7744
+ liquidityBN,
7745
+ Q64
7746
+ );
7747
+ rewards.push(rewardAmountOwed.add(rewardAmountDelta));
7748
+ }
7749
+ return { rewards };
7750
+ }
7751
+ };
7752
+
7474
7753
  // src/utils/index.ts
7475
7754
  var import_kit51 = require("@solana/kit");
7476
7755
  function validateAddress(address6, name = "address") {
@@ -7636,7 +7915,7 @@ var Clmm = class {
7636
7915
  // src/pool-manager.ts
7637
7916
  var import_kit52 = require("@solana/kit");
7638
7917
  var import_token2 = require("@solana-program/token");
7639
- var import_bn5 = __toESM(require("bn.js"));
7918
+ var import_bn6 = __toESM(require("bn.js"));
7640
7919
  var import_decimal3 = __toESM(require("decimal.js"));
7641
7920
 
7642
7921
  // src/utils/token.ts
@@ -7675,8 +7954,8 @@ var PoolManager = class {
7675
7954
  } = params;
7676
7955
  const addressA = (0, import_kit52.address)(tokenMintA);
7677
7956
  const addressB = (0, import_kit52.address)(tokenMintB);
7678
- const isAFirst = new import_bn5.default(Buffer.from(addressB)).gt(
7679
- new import_bn5.default(Buffer.from(addressA))
7957
+ const isAFirst = new import_bn6.default(Buffer.from(addressB)).gt(
7958
+ new import_bn6.default(Buffer.from(addressA))
7680
7959
  );
7681
7960
  const [token0, token1, decimals0, decimals1, priceAdjusted] = isAFirst ? [tokenMintA, tokenMintB, mintADecimals, mintBDecimals, initialPrice] : [
7682
7961
  tokenMintB,
@@ -7858,7 +8137,7 @@ var PoolManager = class {
7858
8137
  getToken(this.config.rpc, poolState.tokenVault1)
7859
8138
  ]);
7860
8139
  const currentPrice = this.calculatePoolPrice(
7861
- new import_bn5.default(poolState.sqrtPriceX64.toString()),
8140
+ new import_bn6.default(poolState.sqrtPriceX64.toString()),
7862
8141
  tokenA.decimals,
7863
8142
  tokenB.decimals
7864
8143
  );
@@ -7903,7 +8182,7 @@ var PoolManager = class {
7903
8182
  var import_kit53 = require("@solana/kit");
7904
8183
  var import_token4 = require("@solana-program/token");
7905
8184
  var import_token_20222 = require("@solana-program/token-2022");
7906
- var import_bn6 = __toESM(require("bn.js"));
8185
+ var import_bn7 = __toESM(require("bn.js"));
7907
8186
 
7908
8187
  // ../node_modules/@solana/spl-token/lib/esm/constants.js
7909
8188
  var import_web3 = require("@solana/web3.js");
@@ -8461,21 +8740,22 @@ var PositionManager = class {
8461
8740
  * Enrich position state with computed fields from pool data
8462
8741
  * @param position - Raw position state from blockchain
8463
8742
  * @param pool - Pool state from blockchain
8743
+ * @param fees - Position fees
8464
8744
  * @returns Enriched position info with calculated amounts and prices
8465
8745
  */
8466
- enrichPositionInfo(position, pool) {
8746
+ enrichPositionInfo(position, pool, fees, rewards) {
8467
8747
  const sqrtPriceLowerX64 = SqrtPriceMath.getSqrtPriceX64FromTick(
8468
8748
  position.tickLowerIndex
8469
8749
  );
8470
8750
  const sqrtPriceUpperX64 = SqrtPriceMath.getSqrtPriceX64FromTick(
8471
8751
  position.tickUpperIndex
8472
8752
  );
8473
- const sqrtPriceCurrentX64 = new import_bn6.default(pool.sqrtPriceX64.toString());
8753
+ const sqrtPriceCurrentX64 = new import_bn7.default(pool.sqrtPriceX64.toString());
8474
8754
  const { amountA, amountB } = LiquidityMath.getAmountsFromLiquidity(
8475
8755
  sqrtPriceCurrentX64,
8476
8756
  sqrtPriceLowerX64,
8477
8757
  sqrtPriceUpperX64,
8478
- new import_bn6.default(position.liquidity.toString()),
8758
+ new import_bn7.default(position.liquidity.toString()),
8479
8759
  true
8480
8760
  );
8481
8761
  const [_amountA, _amountB] = [
@@ -8496,9 +8776,13 @@ var PositionManager = class {
8496
8776
  });
8497
8777
  const inRange = pool.tickCurrent >= position.tickLowerIndex && pool.tickCurrent < position.tickUpperIndex;
8498
8778
  const unclaimedFees = {
8499
- token0: new import_bn6.default(position.tokenFeesOwed0.toString()),
8500
- token1: new import_bn6.default(position.tokenFeesOwed1.toString())
8779
+ token0: fees?.tokenFees0 ? fees?.tokenFees0 : new import_bn7.default(0),
8780
+ token1: fees?.tokenFees1 ? fees?.tokenFees1 : new import_bn7.default(0)
8501
8781
  };
8782
+ const unclaimedRewards = rewards?.rewards ? rewards.rewards.map((amount, i) => ({
8783
+ mint: pool.rewardInfos[i]?.tokenMint,
8784
+ amount
8785
+ })).filter((r) => r.mint !== void 0) : void 0;
8502
8786
  const ageSeconds = 0;
8503
8787
  return {
8504
8788
  ...position,
@@ -8511,10 +8795,8 @@ var PositionManager = class {
8511
8795
  inRange,
8512
8796
  ageSeconds,
8513
8797
  unclaimedFees,
8514
- // valueUsd is optional and requires external price feeds
8515
- valueUsd: void 0,
8516
- // unclaimedRewards is optional
8517
- unclaimedRewards: void 0
8798
+ unclaimedRewards,
8799
+ valueUsd: void 0
8518
8800
  };
8519
8801
  }
8520
8802
  /**
@@ -8554,7 +8836,16 @@ var PositionManager = class {
8554
8836
  console.warn(`Pool ${position.poolId} not found for position`);
8555
8837
  return null;
8556
8838
  }
8557
- return this.enrichPositionInfo(position, poolAccount.data);
8839
+ const { fees, rewards } = await this.getPositionFeeAndRewards(
8840
+ position,
8841
+ poolAccount.data
8842
+ );
8843
+ return this.enrichPositionInfo(
8844
+ position,
8845
+ poolAccount.data,
8846
+ fees,
8847
+ rewards
8848
+ );
8558
8849
  } catch (error) {
8559
8850
  console.error(`Failed to enrich position: ${error}`);
8560
8851
  return null;
@@ -8569,6 +8860,101 @@ var PositionManager = class {
8569
8860
  );
8570
8861
  }
8571
8862
  }
8863
+ /**
8864
+ * Calculate pending fees and rewards for a position.
8865
+ *
8866
+ * @param position - Personal position state
8867
+ * @param pool - Pool state
8868
+ * @returns Pending fees for both tokens and rewards for each reward token (up to 3)
8869
+ */
8870
+ async getPositionFeeAndRewards(position, pool) {
8871
+ const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
8872
+ position.poolId,
8873
+ PdaUtils.getTickArrayStartIndex(
8874
+ position.tickLowerIndex,
8875
+ pool.tickSpacing
8876
+ )
8877
+ );
8878
+ const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
8879
+ position.poolId,
8880
+ PdaUtils.getTickArrayStartIndex(
8881
+ position.tickUpperIndex,
8882
+ pool.tickSpacing
8883
+ )
8884
+ );
8885
+ const tickArrayLowerAccount = await fetchMaybeTickArrayState(
8886
+ this.config.rpc,
8887
+ tickArrayLower
8888
+ );
8889
+ const tickArrayUpperAccount = await fetchMaybeTickArrayState(
8890
+ this.config.rpc,
8891
+ tickArrayUpper
8892
+ );
8893
+ if (!tickArrayLowerAccount.exists || !tickArrayUpperAccount.exists) {
8894
+ console.log(
8895
+ "[getPositionFeeAndRewards] tick array state accounts do not exist."
8896
+ );
8897
+ return {
8898
+ fees: { tokenFees0: new import_bn7.default(0), tokenFees1: new import_bn7.default(0) },
8899
+ rewards: { rewards: [new import_bn7.default(0), new import_bn7.default(0), new import_bn7.default(0)] }
8900
+ };
8901
+ }
8902
+ const tickSpacing = pool.tickSpacing;
8903
+ const tickArrayLowerIndex = TickUtils.getTickOffsetInArray(
8904
+ position.tickLowerIndex,
8905
+ tickSpacing
8906
+ );
8907
+ const tickArrayUpperIndex = TickUtils.getTickOffsetInArray(
8908
+ position.tickUpperIndex,
8909
+ tickSpacing
8910
+ );
8911
+ if (tickArrayLowerIndex < 0 || tickArrayUpperIndex < 0) {
8912
+ console.log("[getPositionFeeAndRewards] tick array indexes < 0.");
8913
+ return {
8914
+ fees: { tokenFees0: new import_bn7.default(0), tokenFees1: new import_bn7.default(0) },
8915
+ rewards: { rewards: [new import_bn7.default(0), new import_bn7.default(0), new import_bn7.default(0)] }
8916
+ };
8917
+ }
8918
+ const lowerTickState = tickArrayLowerAccount.data.ticks[tickArrayLowerIndex];
8919
+ const upperTickState = tickArrayUpperAccount.data.ticks[tickArrayUpperIndex];
8920
+ const fees = PositionUtils.getPositionFees({
8921
+ liquidity: position.liquidity,
8922
+ tickLower: position.tickLowerIndex,
8923
+ tickUpper: position.tickUpperIndex,
8924
+ feeGrowthInside0LastX64: position.feeGrowthInside0LastX64,
8925
+ feeGrowthInside1LastX64: position.feeGrowthInside1LastX64,
8926
+ tokenFeesOwed0: position.tokenFeesOwed0,
8927
+ tokenFeesOwed1: position.tokenFeesOwed1,
8928
+ tickCurrent: pool.tickCurrent,
8929
+ feeGrowthGlobal0X64: pool.feeGrowthGlobal0X64,
8930
+ feeGrowthGlobal1X64: pool.feeGrowthGlobal1X64,
8931
+ tickLowerState: {
8932
+ feeGrowthOutside0X64: lowerTickState.feeGrowthOutside0X64,
8933
+ feeGrowthOutside1X64: lowerTickState.feeGrowthOutside1X64
8934
+ },
8935
+ tickUpperState: {
8936
+ feeGrowthOutside0X64: upperTickState.feeGrowthOutside0X64,
8937
+ feeGrowthOutside1X64: upperTickState.feeGrowthOutside1X64
8938
+ }
8939
+ });
8940
+ const rewards = PositionUtils.getPositionRewards({
8941
+ liquidity: position.liquidity,
8942
+ tickLower: position.tickLowerIndex,
8943
+ tickUpper: position.tickUpperIndex,
8944
+ positionRewardInfos: position.rewardInfos,
8945
+ tickCurrent: pool.tickCurrent,
8946
+ rewardInfos: pool.rewardInfos,
8947
+ tickLowerState: {
8948
+ liquidityGross: lowerTickState.liquidityGross,
8949
+ rewardGrowthsOutsideX64: lowerTickState.rewardGrowthsOutsideX64
8950
+ },
8951
+ tickUpperState: {
8952
+ liquidityGross: upperTickState.liquidityGross,
8953
+ rewardGrowthsOutsideX64: upperTickState.rewardGrowthsOutsideX64
8954
+ }
8955
+ });
8956
+ return { fees, rewards };
8957
+ }
8572
8958
  };
8573
8959
 
8574
8960
  // src/api/config.ts
@@ -9540,7 +9926,7 @@ var PriceApiClient = class _PriceApiClient {
9540
9926
  };
9541
9927
 
9542
9928
  // src/swap.ts
9543
- var import_bn7 = __toESM(require("bn.js"));
9929
+ var import_bn8 = __toESM(require("bn.js"));
9544
9930
  var import_decimal6 = __toESM(require("decimal.js"));
9545
9931
  var DEFAULT_RETRY_CONFIG = {
9546
9932
  maxRetries: 3,
@@ -9600,7 +9986,7 @@ var SwapMathEngine = class {
9600
9986
  slippageTolerance,
9601
9987
  poolAddress
9602
9988
  } = params;
9603
- if (amountIn.lte(new import_bn7.default(0))) {
9989
+ if (amountIn.lte(new import_bn8.default(0))) {
9604
9990
  throw new ClmmError(
9605
9991
  "SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
9606
9992
  "Swap amount must be greater than zero"
@@ -9612,8 +9998,8 @@ var SwapMathEngine = class {
9612
9998
  `Slippage tolerance must be between 0 and 1, got ${slippageTolerance}`
9613
9999
  );
9614
10000
  }
9615
- const liquidity = new import_bn7.default(pool.liquidity.toString());
9616
- const sqrtPriceCurrentX64 = new import_bn7.default(pool.sqrtPriceX64.toString());
10001
+ const liquidity = new import_bn8.default(pool.liquidity.toString());
10002
+ const sqrtPriceCurrentX64 = new import_bn8.default(pool.sqrtPriceX64.toString());
9617
10003
  const feeRate = ammConfig.tradeFeeRate;
9618
10004
  const sqrtPriceTargetX64 = this.calculateSqrtPriceLimit(
9619
10005
  sqrtPriceCurrentX64,
@@ -9641,9 +10027,9 @@ var SwapMathEngine = class {
9641
10027
  pool.mintDecimals1
9642
10028
  );
9643
10029
  const priceImpact = priceAfter.minus(priceBefore).div(priceBefore).abs().toNumber();
9644
- const slippageBN = new import_bn7.default(Math.floor(slippageTolerance * 1e4));
10030
+ const slippageBN = new import_bn8.default(Math.floor(slippageTolerance * 1e4));
9645
10031
  const minAmountOut = step.amountOut.sub(
9646
- step.amountOut.mul(slippageBN).div(new import_bn7.default(1e4))
10032
+ step.amountOut.mul(slippageBN).div(new import_bn8.default(1e4))
9647
10033
  );
9648
10034
  return {
9649
10035
  amountIn,
@@ -9690,17 +10076,17 @@ var SwapMathEngine = class {
9690
10076
  tickArrayCache
9691
10077
  } = params;
9692
10078
  const sqrtPriceLimitX64 = this.calculateSqrtPriceLimit(
9693
- new import_bn7.default(pool.sqrtPriceX64.toString()),
10079
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
9694
10080
  zeroForOne,
9695
10081
  slippageTolerance
9696
10082
  );
9697
10083
  const result = await SwapMath.swapCompute({
9698
10084
  poolState: {
9699
- sqrtPriceX64: new import_bn7.default(pool.sqrtPriceX64.toString()),
10085
+ sqrtPriceX64: new import_bn8.default(pool.sqrtPriceX64.toString()),
9700
10086
  tickCurrent: pool.tickCurrent,
9701
- liquidity: new import_bn7.default(pool.liquidity.toString()),
9702
- feeGrowthGlobal0X64: new import_bn7.default(pool.feeGrowthGlobal0X64.toString()),
9703
- feeGrowthGlobal1X64: new import_bn7.default(pool.feeGrowthGlobal1X64.toString())
10087
+ liquidity: new import_bn8.default(pool.liquidity.toString()),
10088
+ feeGrowthGlobal0X64: new import_bn8.default(pool.feeGrowthGlobal0X64.toString()),
10089
+ feeGrowthGlobal1X64: new import_bn8.default(pool.feeGrowthGlobal1X64.toString())
9704
10090
  },
9705
10091
  tickArrayCache,
9706
10092
  tickSpacing: pool.tickSpacing,
@@ -9717,7 +10103,7 @@ var SwapMathEngine = class {
9717
10103
  poolId: poolAddress
9718
10104
  });
9719
10105
  const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
9720
- new import_bn7.default(pool.sqrtPriceX64.toString()),
10106
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
9721
10107
  pool.mintDecimals0,
9722
10108
  pool.mintDecimals1
9723
10109
  );
@@ -9727,9 +10113,9 @@ var SwapMathEngine = class {
9727
10113
  pool.mintDecimals1
9728
10114
  );
9729
10115
  const priceImpact = priceAfter.minus(priceBefore).div(priceBefore).abs().toNumber();
9730
- const slippageBN = new import_bn7.default(Math.floor(slippageTolerance * 1e4));
10116
+ const slippageBN = new import_bn8.default(Math.floor(slippageTolerance * 1e4));
9731
10117
  const minAmountOut = result.amountOut.sub(
9732
- result.amountOut.mul(slippageBN).div(new import_bn7.default(1e4))
10118
+ result.amountOut.mul(slippageBN).div(new import_bn8.default(1e4))
9733
10119
  );
9734
10120
  const feeImpact = ammConfig.tradeFeeRate / FEE_RATE_DENOMINATOR_NUMBER;
9735
10121
  return {
@@ -9773,10 +10159,10 @@ var SwapMathEngine = class {
9773
10159
  */
9774
10160
  calculateSqrtPriceLimit(sqrtPriceX64, zeroForOne, slippageTolerance) {
9775
10161
  const bps = Math.floor(slippageTolerance * 1e4);
9776
- const base = new import_bn7.default(1e4);
9777
- const scaled = zeroForOne ? sqrtPriceX64.mul(base.sub(new import_bn7.default(bps))).div(base) : sqrtPriceX64.mul(base.add(new import_bn7.default(bps))).div(base);
9778
- const min2 = new import_bn7.default(MIN_SQRT_PRICE_X64);
9779
- const max = new import_bn7.default(MAX_SQRT_PRICE_X64);
10162
+ const base = new import_bn8.default(1e4);
10163
+ const scaled = zeroForOne ? sqrtPriceX64.mul(base.sub(new import_bn8.default(bps))).div(base) : sqrtPriceX64.mul(base.add(new import_bn8.default(bps))).div(base);
10164
+ const min2 = new import_bn8.default(MIN_SQRT_PRICE_X64);
10165
+ const max = new import_bn8.default(MAX_SQRT_PRICE_X64);
9780
10166
  if (scaled.lt(min2)) return min2;
9781
10167
  if (scaled.gt(max)) return max;
9782
10168
  return scaled;
@@ -10200,7 +10586,7 @@ var SwapManager = class {
10200
10586
  `Invalid slippage tolerance: ${slippageTolerance}. Must be between 0 and 1.`
10201
10587
  );
10202
10588
  }
10203
- if (amountIn.lte(new import_bn7.default(0))) {
10589
+ if (amountIn.lte(new import_bn8.default(0))) {
10204
10590
  throw new ClmmError(
10205
10591
  "SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
10206
10592
  "Swap amount must be greater than zero."
@@ -10302,7 +10688,7 @@ var SwapManager = class {
10302
10688
  `Invalid slippage tolerance: ${slippageTolerance}. Must be between 0 and 1.`
10303
10689
  );
10304
10690
  }
10305
- if (amountIn.lte(new import_bn7.default(0))) {
10691
+ if (amountIn.lte(new import_bn8.default(0))) {
10306
10692
  throw new ClmmError(
10307
10693
  "SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
10308
10694
  "Swap amount must be greater than zero."
@@ -10356,7 +10742,7 @@ var SwapManager = class {
10356
10742
  poolAddress
10357
10743
  });
10358
10744
  const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
10359
- new import_bn7.default(pool.sqrtPriceX64.toString()),
10745
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10360
10746
  pool.mintDecimals0,
10361
10747
  pool.mintDecimals1
10362
10748
  );
@@ -10466,21 +10852,21 @@ var SwapManager = class {
10466
10852
  * @returns Number of tick arrays to fetch (includes safety buffer)
10467
10853
  */
10468
10854
  estimateTickArrayCount(pool, amountIn) {
10469
- const liquidity = new import_bn7.default(pool.liquidity.toString());
10470
- if (liquidity.eq(new import_bn7.default(0)) || liquidity.lt(new import_bn7.default(1e3))) {
10855
+ const liquidity = new import_bn8.default(pool.liquidity.toString());
10856
+ if (liquidity.eq(new import_bn8.default(0)) || liquidity.lt(new import_bn8.default(1e3))) {
10471
10857
  return 10;
10472
10858
  }
10473
- const roughImpact = amountIn.mul(new import_bn7.default(1e3)).div(liquidity);
10859
+ const roughImpact = amountIn.mul(new import_bn8.default(1e3)).div(liquidity);
10474
10860
  let baseArrays;
10475
- if (roughImpact.lte(new import_bn7.default(1))) {
10861
+ if (roughImpact.lte(new import_bn8.default(1))) {
10476
10862
  baseArrays = 2;
10477
- } else if (roughImpact.lte(new import_bn7.default(10))) {
10863
+ } else if (roughImpact.lte(new import_bn8.default(10))) {
10478
10864
  baseArrays = 4;
10479
- } else if (roughImpact.lte(new import_bn7.default(50))) {
10865
+ } else if (roughImpact.lte(new import_bn8.default(50))) {
10480
10866
  baseArrays = 6;
10481
- } else if (roughImpact.lte(new import_bn7.default(100))) {
10867
+ } else if (roughImpact.lte(new import_bn8.default(100))) {
10482
10868
  baseArrays = 8;
10483
- } else if (roughImpact.lte(new import_bn7.default(200))) {
10869
+ } else if (roughImpact.lte(new import_bn8.default(200))) {
10484
10870
  baseArrays = 12;
10485
10871
  } else {
10486
10872
  baseArrays = 15;
@@ -10525,7 +10911,7 @@ var SwapManager = class {
10525
10911
  const decOut = zeroForOne ? pool.mintDecimals1 : pool.mintDecimals0;
10526
10912
  const promises = params.amounts.map(async (amountIn) => {
10527
10913
  try {
10528
- if (amountIn.lte(new import_bn7.default(0))) return;
10914
+ if (amountIn.lte(new import_bn8.default(0))) return;
10529
10915
  const quote = await this.mathEngine.calculateSimpleSwap({
10530
10916
  pool,
10531
10917
  ammConfig,
@@ -10567,7 +10953,7 @@ var SwapManager = class {
10567
10953
  options
10568
10954
  );
10569
10955
  const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
10570
- new import_bn7.default(pool.sqrtPriceX64.toString()),
10956
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10571
10957
  pool.mintDecimals0,
10572
10958
  pool.mintDecimals1
10573
10959
  );
@@ -10690,13 +11076,13 @@ var SwapManager = class {
10690
11076
  `Extremely high price impact: ${(quote.priceImpact * 100).toFixed(2)}%. Swap likely to fail or result in significant slippage.`
10691
11077
  );
10692
11078
  }
10693
- const oneUnit = new import_bn7.default(10).pow(new import_bn7.default(outputDecimals));
11079
+ const oneUnit = new import_bn8.default(10).pow(new import_bn8.default(outputDecimals));
10694
11080
  if (quote.amountOut.lt(oneUnit)) {
10695
11081
  warnings.push(
10696
11082
  `Output amount is less than 1 unit of the output token. Consider increasing input amount or slippage tolerance.`
10697
11083
  );
10698
11084
  }
10699
- if (quote.amountOut.lte(new import_bn7.default(0))) {
11085
+ if (quote.amountOut.lte(new import_bn8.default(0))) {
10700
11086
  errors.push(
10701
11087
  "Swap would result in zero output. Amount may be too small."
10702
11088
  );
@@ -10717,11 +11103,11 @@ var SwapManager = class {
10717
11103
  return {
10718
11104
  quote: {
10719
11105
  amountIn: params.amountIn,
10720
- amountOut: new import_bn7.default(0),
10721
- minAmountOut: new import_bn7.default(0),
11106
+ amountOut: new import_bn8.default(0),
11107
+ minAmountOut: new import_bn8.default(0),
10722
11108
  priceImpact: 0,
10723
11109
  route: [],
10724
- fee: new import_bn7.default(0)
11110
+ fee: new import_bn8.default(0)
10725
11111
  },
10726
11112
  willSucceed: false,
10727
11113
  errors,
@@ -10821,7 +11207,7 @@ var SwapManager = class {
10821
11207
  tokenProgram: import_token5.TOKEN_PROGRAM_ADDRESS
10822
11208
  });
10823
11209
  const sqrtPriceLimitX64 = params.sqrtPriceLimitX64 || this.mathEngine.calculateSqrtPriceLimit(
10824
- new import_bn7.default(pool.sqrtPriceX64.toString()),
11210
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10825
11211
  zeroForOne,
10826
11212
  params.slippageTolerance || DEFAULT_SLIPPAGE_TOLERANCE
10827
11213
  );
@@ -10846,7 +11232,7 @@ var SwapManager = class {
10846
11232
  async getCurrentPrice(poolAddress, options) {
10847
11233
  const pool = await this.poolDataManager.getPoolState(poolAddress, options);
10848
11234
  return SqrtPriceMath.sqrtPriceX64ToPrice(
10849
- new import_bn7.default(pool.sqrtPriceX64.toString()),
11235
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10850
11236
  pool.mintDecimals0,
10851
11237
  pool.mintDecimals1
10852
11238
  );
@@ -11059,6 +11445,7 @@ var DEFAULT_SDK_CONFIG = {
11059
11445
  PoolManager,
11060
11446
  PoolUtils,
11061
11447
  PositionManager,
11448
+ PositionUtils,
11062
11449
  PriceApiClient,
11063
11450
  Q128,
11064
11451
  Q64,