@stabbleorg/mclmm-sdk 0.3.2 → 0.4.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.
package/lib/index.js CHANGED
@@ -66,11 +66,13 @@ __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,
72
73
  SLIPPAGE_CALC: () => SLIPPAGE_CALC,
73
74
  STABBLE_CLMM_PROGRAM_ID: () => STABBLE_CLMM_PROGRAM_ID,
75
+ STABBLE_CLMM_QAS_PROGRAM_ID: () => STABBLE_CLMM_QAS_PROGRAM_ID,
74
76
  SYSTEM_PROGRAM_ID: () => SYSTEM_PROGRAM_ID,
75
77
  SYSVAR_RENT_PROGRAM_ID: () => SYSVAR_RENT_PROGRAM_ID,
76
78
  SqrtPriceMath: () => SqrtPriceMath,
@@ -5183,6 +5185,7 @@ var import_decimal2 = __toESM(require("decimal.js"));
5183
5185
  // src/constants.ts
5184
5186
  var import_bn = __toESM(require("bn.js"));
5185
5187
  var STABBLE_CLMM_PROGRAM_ID = "6dMXqGZ3ga2dikrYS9ovDXgHGh5RUsb2RTUj6hrQXhk6";
5188
+ var STABBLE_CLMM_QAS_PROGRAM_ID = "8896VTm3Z3g8PuktiDdW9JLxZP1ww2r5c9Tz5AbaBjAJ";
5186
5189
  var METADATA_PROGRAM_ID = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s";
5187
5190
  var SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
5188
5191
  var SYSVAR_RENT_PROGRAM_ID = "SysvarRent111111111111111111111111111111111";
@@ -5348,6 +5351,22 @@ var TickUtils = class _TickUtils {
5348
5351
  );
5349
5352
  }
5350
5353
  }
5354
+ static getTickOffsetInArray(tickIndex, tickSpacing) {
5355
+ if (tickIndex % tickSpacing != 0) {
5356
+ throw new Error("tickIndex % tickSpacing not equal 0");
5357
+ }
5358
+ const startTickIndex = _TickUtils.getTickArrayStartIndexByTick(
5359
+ tickIndex,
5360
+ tickSpacing
5361
+ );
5362
+ const offsetInArray = Math.floor(
5363
+ (tickIndex - startTickIndex) / tickSpacing
5364
+ );
5365
+ if (offsetInArray < 0 || offsetInArray >= TICK_ARRAY_SIZE) {
5366
+ throw new Error("tick offset in array overflow");
5367
+ }
5368
+ return offsetInArray;
5369
+ }
5351
5370
  /**
5352
5371
  * Get the start index of the tick array containing a specific tick
5353
5372
  * @param tick - Target tick
@@ -5629,11 +5648,12 @@ var PdaUtils = class {
5629
5648
  * @param ammConfig - AMM config address
5630
5649
  * @param tokenMintA - Token A mint address
5631
5650
  * @param tokenMintB - Token B mint address
5651
+ * @param programId - Program address (defaults to production)
5632
5652
  * @returns Pool state PDA
5633
5653
  */
5634
- static async getPoolStatePda(ammConfig, tokenMintA, tokenMintB) {
5654
+ static async getPoolStatePda(ammConfig, tokenMintA, tokenMintB, programId = STABBLE_CLMM_PROGRAM_ID) {
5635
5655
  return await (0, import_kit50.getProgramDerivedAddress)({
5636
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5656
+ programAddress: programId,
5637
5657
  seeds: [
5638
5658
  PDA_SEEDS.POOL_STATE,
5639
5659
  addressEncoder.encode(ammConfig),
@@ -5645,22 +5665,24 @@ var PdaUtils = class {
5645
5665
  /**
5646
5666
  * Derive AMM config PDA
5647
5667
  * @param index - Config index
5668
+ * @param programId - Program address (defaults to production)
5648
5669
  * @returns AMM config PDA
5649
5670
  */
5650
- static async getAmmConfigPda(index) {
5671
+ static async getAmmConfigPda(index, programId = STABBLE_CLMM_PROGRAM_ID) {
5651
5672
  return await (0, import_kit50.getProgramDerivedAddress)({
5652
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5673
+ programAddress: programId,
5653
5674
  seeds: [PDA_SEEDS.AMM_CONFIG, (0, import_kit50.getU16Encoder)().encode(index)]
5654
5675
  });
5655
5676
  }
5656
5677
  /**
5657
5678
  * Derive position state PDA
5658
5679
  * @param nftMint - Position NFT mint address
5680
+ * @param programId - Program address (defaults to production)
5659
5681
  * @returns Position state PDA
5660
5682
  */
5661
- static async getPositionStatePda(nftMint) {
5683
+ static async getPositionStatePda(nftMint, programId = STABBLE_CLMM_PROGRAM_ID) {
5662
5684
  return await (0, import_kit50.getProgramDerivedAddress)({
5663
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5685
+ programAddress: programId,
5664
5686
  seeds: [PDA_SEEDS.POSITION_STATE, addressEncoder.encode(nftMint)]
5665
5687
  });
5666
5688
  }
@@ -5668,11 +5690,12 @@ var PdaUtils = class {
5668
5690
  * Derive tick array state PDA
5669
5691
  * @param poolState - Pool state address
5670
5692
  * @param startTickIndex - Starting tick index of the array
5693
+ * @param programId - Program address (defaults to production)
5671
5694
  * @returns Tick array state PDA
5672
5695
  */
5673
- static async getTickArrayStatePda(poolState, startTickIndex) {
5696
+ static async getTickArrayStatePda(poolState, startTickIndex, programId = STABBLE_CLMM_PROGRAM_ID) {
5674
5697
  return await (0, import_kit50.getProgramDerivedAddress)({
5675
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5698
+ programAddress: programId,
5676
5699
  seeds: [
5677
5700
  PDA_SEEDS.TICK_ARRAY_STATE,
5678
5701
  addressEncoder.encode(poolState),
@@ -5683,32 +5706,34 @@ var PdaUtils = class {
5683
5706
  /**
5684
5707
  * Derive observation state PDA
5685
5708
  * @param poolState - Pool state address
5709
+ * @param programId - Program address (defaults to production)
5686
5710
  * @returns Observation state PDA
5687
5711
  */
5688
- static async getObservationStatePda(poolState) {
5712
+ static async getObservationStatePda(poolState, programId = STABBLE_CLMM_PROGRAM_ID) {
5689
5713
  return await (0, import_kit50.getProgramDerivedAddress)({
5690
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5714
+ programAddress: programId,
5691
5715
  seeds: [PDA_SEEDS.OBSERVATION_STATE, addressEncoder.encode(poolState)]
5692
5716
  });
5693
5717
  }
5694
- static async getPoolVaultIdPda(poolAddress, vaultAddress) {
5718
+ static async getPoolVaultIdPda(poolAddress, vaultAddress, programId = STABBLE_CLMM_PROGRAM_ID) {
5695
5719
  return await (0, import_kit50.getProgramDerivedAddress)({
5696
5720
  seeds: [
5697
5721
  PDA_SEEDS.POOL_VAULT,
5698
5722
  addressEncoder.encode(poolAddress),
5699
5723
  addressEncoder.encode(vaultAddress)
5700
5724
  ],
5701
- programAddress: STABBLE_CLMM_PROGRAM_ID
5725
+ programAddress: programId
5702
5726
  });
5703
5727
  }
5704
5728
  /**
5705
5729
  * Derive tick array bitmap extension PDA
5706
5730
  * @param poolState - Pool state address
5731
+ * @param programId - Program address (defaults to production)
5707
5732
  * @returns Tick array bitmap extension PDA
5708
5733
  */
5709
- static async getTickArrayBitmapExtensionPda(poolState) {
5734
+ static async getTickArrayBitmapExtensionPda(poolState, programId = STABBLE_CLMM_PROGRAM_ID) {
5710
5735
  return await (0, import_kit50.getProgramDerivedAddress)({
5711
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5736
+ programAddress: programId,
5712
5737
  seeds: [PDA_SEEDS.BITMAP_EXTENSION, addressEncoder.encode(poolState)]
5713
5738
  });
5714
5739
  }
@@ -5731,9 +5756,10 @@ var PdaUtils = class {
5731
5756
  * @param tickUpper - Upper tick of range
5732
5757
  * @param tickSpacing - Tick spacing of the pool
5733
5758
  * @param tickCurrent - Current pool tick
5759
+ * @param programId - Program address (defaults to production)
5734
5760
  * @returns Array of tick array PDAs
5735
5761
  */
5736
- static async getTickArrayPdasForRange(poolState, tickLower, tickUpper, tickSpacing, tickCurrent) {
5762
+ static async getTickArrayPdasForRange(poolState, tickLower, tickUpper, tickSpacing, tickCurrent, programId = STABBLE_CLMM_PROGRAM_ID) {
5737
5763
  const startIndexLower = this.getTickArrayStartIndex(tickLower, tickSpacing);
5738
5764
  const startIndexUpper = this.getTickArrayStartIndex(tickUpper, tickSpacing);
5739
5765
  const startIndexCurrent = this.getTickArrayStartIndex(
@@ -5747,7 +5773,7 @@ var PdaUtils = class {
5747
5773
  ]);
5748
5774
  return await Promise.all(
5749
5775
  Array.from(indices).map(
5750
- (index) => this.getTickArrayStatePda(poolState, index)
5776
+ (index) => this.getTickArrayStatePda(poolState, index, programId)
5751
5777
  )
5752
5778
  );
5753
5779
  }
@@ -5756,11 +5782,12 @@ var PdaUtils = class {
5756
5782
  * @param poolState - Pool state address
5757
5783
  * @param tickLowerIndex - Lower tick index
5758
5784
  * @param tickUpperIndex - Upper tick index
5785
+ * @param programId - Program address (defaults to production)
5759
5786
  * @returns Protocol position state PDA
5760
5787
  */
5761
- static async getProtocolPositionStatePda(poolState, tickLowerIndex, tickUpperIndex) {
5788
+ static async getProtocolPositionStatePda(poolState, tickLowerIndex, tickUpperIndex, programId = STABBLE_CLMM_PROGRAM_ID) {
5762
5789
  return await (0, import_kit50.getProgramDerivedAddress)({
5763
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5790
+ programAddress: programId,
5764
5791
  seeds: [
5765
5792
  PDA_SEEDS.POSITION_STATE,
5766
5793
  addressEncoder.encode(poolState),
@@ -5772,11 +5799,12 @@ var PdaUtils = class {
5772
5799
  /**
5773
5800
  * Derive operation state PDA
5774
5801
  * @param poolState - Pool state address
5802
+ * @param programId - Program address (defaults to production)
5775
5803
  * @returns Operation state PDA
5776
5804
  */
5777
- static async getOperationStatePda(poolState) {
5805
+ static async getOperationStatePda(poolState, programId = STABBLE_CLMM_PROGRAM_ID) {
5778
5806
  return await (0, import_kit50.getProgramDerivedAddress)({
5779
- programAddress: STABBLE_CLMM_PROGRAM_ID,
5807
+ programAddress: programId,
5780
5808
  seeds: [PDA_SEEDS.OPERATION, addressEncoder.encode(poolState)]
5781
5809
  });
5782
5810
  }
@@ -5795,7 +5823,7 @@ async function getMetadataPda(mint) {
5795
5823
  // src/utils/tickQuery.ts
5796
5824
  var FETCH_TICKARRAY_COUNT = 15;
5797
5825
  var TickQuery = class _TickQuery {
5798
- static async getTickArrays(rpc, poolId, tickCurrent, tickSpacing, tickArrayBitmapArray, exTickArrayBitmap) {
5826
+ static async getTickArrays(rpc, poolId, tickCurrent, tickSpacing, tickArrayBitmapArray, exTickArrayBitmap, programId = STABBLE_CLMM_PROGRAM_ID) {
5799
5827
  const tickArraysToFetch = [];
5800
5828
  const currentTickArrayStartIndex = TickUtils.getTickArrayStartIndexByTick(
5801
5829
  tickCurrent,
@@ -5811,7 +5839,8 @@ var TickQuery = class _TickQuery {
5811
5839
  for (let i = 0; i < startIndexArray.length; i++) {
5812
5840
  const [tickArrayAddress] = await PdaUtils.getTickArrayStatePda(
5813
5841
  poolId,
5814
- startIndexArray[i]
5842
+ startIndexArray[i],
5843
+ programId
5815
5844
  );
5816
5845
  tickArraysToFetch.push(tickArrayAddress);
5817
5846
  }
@@ -5866,7 +5895,7 @@ var TickQuery = class _TickQuery {
5866
5895
  * @param zeroForOne - Search direction
5867
5896
  * @returns First initialized tick, tick array address, and start index
5868
5897
  */
5869
- static async firstInitializedTickInOneArray(poolId, tickArray, zeroForOne) {
5898
+ static async firstInitializedTickInOneArray(poolId, tickArray, zeroForOne, programId = STABBLE_CLMM_PROGRAM_ID) {
5870
5899
  let nextInitializedTick = void 0;
5871
5900
  if (zeroForOne) {
5872
5901
  for (let i = TICK_ARRAY_SIZE - 1; i >= 0; i--) {
@@ -5887,7 +5916,8 @@ var TickQuery = class _TickQuery {
5887
5916
  }
5888
5917
  const [tickArrayAddress] = await PdaUtils.getTickArrayStatePda(
5889
5918
  poolId,
5890
- tickArray.data.startTickIndex
5919
+ tickArray.data.startTickIndex,
5920
+ programId
5891
5921
  );
5892
5922
  return {
5893
5923
  nextTick: nextInitializedTick,
@@ -5905,7 +5935,7 @@ var TickQuery = class _TickQuery {
5905
5935
  * @param zeroForOne - Search direction
5906
5936
  * @returns Next initialized tick info
5907
5937
  */
5908
- static async nextInitializedTickInOneArray(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne) {
5938
+ static async nextInitializedTickInOneArray(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne, programId = STABBLE_CLMM_PROGRAM_ID) {
5909
5939
  const startIndex = TickUtils.getTickArrayStartIndexByTick(
5910
5940
  tickIndex,
5911
5941
  tickSpacing
@@ -5944,7 +5974,8 @@ var TickQuery = class _TickQuery {
5944
5974
  }
5945
5975
  const [tickArrayAddress] = await PdaUtils.getTickArrayStatePda(
5946
5976
  poolId,
5947
- startIndex
5977
+ startIndex,
5978
+ programId
5948
5979
  );
5949
5980
  return {
5950
5981
  initializedTick: nextInitializedTick,
@@ -5962,7 +5993,7 @@ var TickQuery = class _TickQuery {
5962
5993
  * @param zeroForOne - Search direction
5963
5994
  * @returns Next initialized tick info
5964
5995
  */
5965
- static async nextInitializedTick(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne) {
5996
+ static async nextInitializedTick(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne, programId = STABBLE_CLMM_PROGRAM_ID) {
5966
5997
  let {
5967
5998
  initializedTick: nextTick,
5968
5999
  tickArrayAddress,
@@ -5972,7 +6003,8 @@ var TickQuery = class _TickQuery {
5972
6003
  tickArrayCache,
5973
6004
  tickIndex,
5974
6005
  tickSpacing,
5975
- zeroForOne
6006
+ zeroForOne,
6007
+ programId
5976
6008
  );
5977
6009
  while (nextTick === void 0 || nextTick.liquidityGross <= 0n) {
5978
6010
  const nextArrayStartIndex = zeroForOne ? tickArrayStartTickIndex - this.tickCount(tickSpacing) : tickArrayStartTickIndex + this.tickCount(tickSpacing);
@@ -5989,7 +6021,8 @@ var TickQuery = class _TickQuery {
5989
6021
  const result = await this.firstInitializedTickInOneArray(
5990
6022
  poolId,
5991
6023
  cachedTickArray,
5992
- zeroForOne
6024
+ zeroForOne,
6025
+ programId
5993
6026
  );
5994
6027
  nextTick = result.nextTick;
5995
6028
  tickArrayAddress = result.tickArrayAddress;
@@ -7471,6 +7504,268 @@ var PoolUtils = class {
7471
7504
  }
7472
7505
  };
7473
7506
 
7507
+ // src/utils/position.ts
7508
+ var import_bn5 = __toESM(require("bn.js"));
7509
+ var PositionUtils = class _PositionUtils {
7510
+ /**
7511
+ * Calculate fee growth inside a position's tick range.
7512
+ *
7513
+ * formula:
7514
+ * ```
7515
+ * feeGrowthInside = feeGrowthGlobal - feeGrowthBelow - feeGrowthAbove
7516
+ * ```
7517
+ *
7518
+ * Where feeGrowthBelow and feeGrowthAbove depend on the current tick
7519
+ * relative to the position's tick boundaries.
7520
+ *
7521
+ * @param params - Parameters for fee growth calculation
7522
+ * @returns Fee growth inside for both tokens (X64 fixed-point)
7523
+ */
7524
+ static getFeeGrowthInside(params) {
7525
+ const {
7526
+ tickCurrent,
7527
+ tickLower,
7528
+ tickUpper,
7529
+ tickLowerState,
7530
+ tickUpperState,
7531
+ feeGrowthGlobal0X64,
7532
+ feeGrowthGlobal1X64
7533
+ } = params;
7534
+ const feeGrowthGlobal0 = new import_bn5.default(feeGrowthGlobal0X64.toString());
7535
+ const feeGrowthGlobal1 = new import_bn5.default(feeGrowthGlobal1X64.toString());
7536
+ const tickLowerFeeGrowthOutside0 = new import_bn5.default(
7537
+ tickLowerState.feeGrowthOutside0X64.toString()
7538
+ );
7539
+ const tickLowerFeeGrowthOutside1 = new import_bn5.default(
7540
+ tickLowerState.feeGrowthOutside1X64.toString()
7541
+ );
7542
+ const tickUpperFeeGrowthOutside0 = new import_bn5.default(
7543
+ tickUpperState.feeGrowthOutside0X64.toString()
7544
+ );
7545
+ const tickUpperFeeGrowthOutside1 = new import_bn5.default(
7546
+ tickUpperState.feeGrowthOutside1X64.toString()
7547
+ );
7548
+ let feeGrowthBelow0X64;
7549
+ let feeGrowthBelow1X64;
7550
+ if (tickCurrent >= tickLower) {
7551
+ feeGrowthBelow0X64 = tickLowerFeeGrowthOutside0;
7552
+ feeGrowthBelow1X64 = tickLowerFeeGrowthOutside1;
7553
+ } else {
7554
+ feeGrowthBelow0X64 = MathUtils.wrappingSubU128(
7555
+ feeGrowthGlobal0,
7556
+ tickLowerFeeGrowthOutside0
7557
+ );
7558
+ feeGrowthBelow1X64 = MathUtils.wrappingSubU128(
7559
+ feeGrowthGlobal1,
7560
+ tickLowerFeeGrowthOutside1
7561
+ );
7562
+ }
7563
+ let feeGrowthAbove0X64;
7564
+ let feeGrowthAbove1X64;
7565
+ if (tickCurrent < tickUpper) {
7566
+ feeGrowthAbove0X64 = tickUpperFeeGrowthOutside0;
7567
+ feeGrowthAbove1X64 = tickUpperFeeGrowthOutside1;
7568
+ } else {
7569
+ feeGrowthAbove0X64 = MathUtils.wrappingSubU128(
7570
+ feeGrowthGlobal0,
7571
+ tickUpperFeeGrowthOutside0
7572
+ );
7573
+ feeGrowthAbove1X64 = MathUtils.wrappingSubU128(
7574
+ feeGrowthGlobal1,
7575
+ tickUpperFeeGrowthOutside1
7576
+ );
7577
+ }
7578
+ const feeGrowthInside0X64 = MathUtils.wrappingSubU128(
7579
+ MathUtils.wrappingSubU128(feeGrowthGlobal0, feeGrowthBelow0X64),
7580
+ feeGrowthAbove0X64
7581
+ );
7582
+ const feeGrowthInside1X64 = MathUtils.wrappingSubU128(
7583
+ MathUtils.wrappingSubU128(feeGrowthGlobal1, feeGrowthBelow1X64),
7584
+ feeGrowthAbove1X64
7585
+ );
7586
+ return {
7587
+ feeGrowthInside0X64,
7588
+ feeGrowthInside1X64
7589
+ };
7590
+ }
7591
+ /**
7592
+ * Calculate pending fees for a position.
7593
+ *
7594
+ * Formula:
7595
+ * ```
7596
+ * feeDelta = (feeGrowthInside - feeGrowthInsideLast) × liquidity / 2^64
7597
+ * totalFees = tokenFeesOwed + feeDelta
7598
+ * ```
7599
+ *
7600
+ * @param params - Parameters for fee calculation
7601
+ * @returns Pending fees for both tokens in native units
7602
+ */
7603
+ static getPositionFees(params) {
7604
+ const {
7605
+ liquidity,
7606
+ tickLower,
7607
+ tickUpper,
7608
+ feeGrowthInside0LastX64,
7609
+ feeGrowthInside1LastX64,
7610
+ tokenFeesOwed0,
7611
+ tokenFeesOwed1,
7612
+ tickCurrent,
7613
+ feeGrowthGlobal0X64,
7614
+ feeGrowthGlobal1X64,
7615
+ tickLowerState,
7616
+ tickUpperState
7617
+ } = params;
7618
+ const { feeGrowthInside0X64, feeGrowthInside1X64 } = _PositionUtils.getFeeGrowthInside({
7619
+ tickCurrent,
7620
+ tickLower,
7621
+ tickUpper,
7622
+ tickLowerState,
7623
+ tickUpperState,
7624
+ feeGrowthGlobal0X64,
7625
+ feeGrowthGlobal1X64
7626
+ });
7627
+ const liquidityBN = new import_bn5.default(liquidity.toString());
7628
+ const feeGrowthInside0Last = new import_bn5.default(feeGrowthInside0LastX64.toString());
7629
+ const feeGrowthInside1Last = new import_bn5.default(feeGrowthInside1LastX64.toString());
7630
+ const feesOwed0 = new import_bn5.default(tokenFeesOwed0.toString());
7631
+ const feesOwed1 = new import_bn5.default(tokenFeesOwed1.toString());
7632
+ const feeGrowthDelta0 = MathUtils.wrappingSubU128(
7633
+ feeGrowthInside0X64,
7634
+ feeGrowthInside0Last
7635
+ );
7636
+ const feeGrowthDelta1 = MathUtils.wrappingSubU128(
7637
+ feeGrowthInside1X64,
7638
+ feeGrowthInside1Last
7639
+ );
7640
+ const feeAmount0 = MathUtils.mulDivFloor(feeGrowthDelta0, liquidityBN, Q64);
7641
+ const feeAmount1 = MathUtils.mulDivFloor(feeGrowthDelta1, liquidityBN, Q64);
7642
+ return {
7643
+ tokenFees0: feesOwed0.add(feeAmount0),
7644
+ tokenFees1: feesOwed1.add(feeAmount1)
7645
+ };
7646
+ }
7647
+ /**
7648
+ * Calculate reward growth inside a position's tick range for all reward tokens.
7649
+ *
7650
+ * Formula:
7651
+ * ```
7652
+ * rewardGrowthInside = rewardGrowthGlobal - rewardGrowthBelow - rewardGrowthAbove
7653
+ * ```
7654
+ *
7655
+ * Special cases:
7656
+ * - If tickLower has no liquidity (liquidityGross = 0), rewardGrowthBelow = rewardGrowthGlobal
7657
+ * - If tickUpper has no liquidity (liquidityGross = 0), rewardGrowthAbove = 0
7658
+ *
7659
+ * @param params - Parameters for reward growth calculation
7660
+ * @returns Reward growth inside for each reward token (X64 fixed-point)
7661
+ */
7662
+ static getRewardGrowthInside(params) {
7663
+ const {
7664
+ tickCurrent,
7665
+ tickLower,
7666
+ tickUpper,
7667
+ tickLowerState,
7668
+ tickUpperState,
7669
+ rewardInfos
7670
+ } = params;
7671
+ const rewardGrowthsInside = [];
7672
+ for (let i = 0; i < rewardInfos.length; i++) {
7673
+ const rewardGrowthGlobal = new import_bn5.default(
7674
+ rewardInfos[i].rewardGrowthGlobalX64.toString()
7675
+ );
7676
+ let rewardGrowthBelow;
7677
+ if (tickLowerState.liquidityGross === 0n) {
7678
+ rewardGrowthBelow = rewardGrowthGlobal;
7679
+ } else if (tickCurrent < tickLower) {
7680
+ rewardGrowthBelow = rewardGrowthGlobal.sub(
7681
+ new import_bn5.default(tickLowerState.rewardGrowthsOutsideX64[i].toString())
7682
+ );
7683
+ } else {
7684
+ rewardGrowthBelow = new import_bn5.default(
7685
+ tickLowerState.rewardGrowthsOutsideX64[i].toString()
7686
+ );
7687
+ }
7688
+ let rewardGrowthAbove;
7689
+ if (tickUpperState.liquidityGross === 0n) {
7690
+ rewardGrowthAbove = new import_bn5.default(0);
7691
+ } else if (tickCurrent < tickUpper) {
7692
+ rewardGrowthAbove = new import_bn5.default(
7693
+ tickUpperState.rewardGrowthsOutsideX64[i].toString()
7694
+ );
7695
+ } else {
7696
+ rewardGrowthAbove = rewardGrowthGlobal.sub(
7697
+ new import_bn5.default(tickUpperState.rewardGrowthsOutsideX64[i].toString())
7698
+ );
7699
+ }
7700
+ const rewardGrowthInside = MathUtils.wrappingSubU128(
7701
+ MathUtils.wrappingSubU128(rewardGrowthGlobal, rewardGrowthBelow),
7702
+ rewardGrowthAbove
7703
+ );
7704
+ rewardGrowthsInside.push(rewardGrowthInside);
7705
+ }
7706
+ return rewardGrowthsInside;
7707
+ }
7708
+ /**
7709
+ * Calculate pending rewards for a position.
7710
+ *
7711
+ * Formula:
7712
+ * ```
7713
+ * rewardDelta = (rewardGrowthInside - rewardGrowthInsideLast) × liquidity / 2^64
7714
+ * totalReward = rewardAmountOwed + rewardDelta
7715
+ * ```
7716
+ *
7717
+ * @param params - Parameters for reward calculation
7718
+ * @returns Pending rewards for each reward token in native units
7719
+ */
7720
+ static getPositionRewards(params) {
7721
+ const {
7722
+ liquidity,
7723
+ tickLower,
7724
+ tickUpper,
7725
+ positionRewardInfos,
7726
+ tickCurrent,
7727
+ rewardInfos,
7728
+ tickLowerState,
7729
+ tickUpperState
7730
+ } = params;
7731
+ const rewardGrowthsInside = _PositionUtils.getRewardGrowthInside({
7732
+ tickCurrent,
7733
+ tickLower,
7734
+ tickUpper,
7735
+ tickLowerState,
7736
+ tickUpperState,
7737
+ rewardInfos
7738
+ });
7739
+ const liquidityBN = new import_bn5.default(liquidity.toString());
7740
+ const rewards = [];
7741
+ for (let i = 0; i < rewardGrowthsInside.length; i++) {
7742
+ const rewardGrowthInside = rewardGrowthsInside[i];
7743
+ const positionRewardInfo = positionRewardInfos[i];
7744
+ if (!positionRewardInfo) {
7745
+ rewards.push(new import_bn5.default(0));
7746
+ continue;
7747
+ }
7748
+ const growthInsideLast = new import_bn5.default(
7749
+ positionRewardInfo.growthInsideLastX64.toString()
7750
+ );
7751
+ const rewardAmountOwed = new import_bn5.default(
7752
+ positionRewardInfo.rewardAmountOwed.toString()
7753
+ );
7754
+ const rewardGrowthDelta = MathUtils.wrappingSubU128(
7755
+ rewardGrowthInside,
7756
+ growthInsideLast
7757
+ );
7758
+ const rewardAmountDelta = MathUtils.mulDivFloor(
7759
+ rewardGrowthDelta,
7760
+ liquidityBN,
7761
+ Q64
7762
+ );
7763
+ rewards.push(rewardAmountOwed.add(rewardAmountDelta));
7764
+ }
7765
+ return { rewards };
7766
+ }
7767
+ };
7768
+
7474
7769
  // src/utils/index.ts
7475
7770
  var import_kit51 = require("@solana/kit");
7476
7771
  function validateAddress(address6, name = "address") {
@@ -7568,7 +7863,9 @@ function getApisFromEndpoint(rpc) {
7568
7863
  var Clmm = class {
7569
7864
  constructor(config) {
7570
7865
  this.config = config;
7866
+ this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
7571
7867
  }
7868
+ programId;
7572
7869
  /**
7573
7870
  * Create a new AMM configuration
7574
7871
  * @param params - Configuration parameters
@@ -7583,7 +7880,7 @@ var Clmm = class {
7583
7880
  protocolFeeRate,
7584
7881
  fundFeeRate
7585
7882
  } = params;
7586
- const ammConfigPda = await PdaUtils.getAmmConfigPda(index);
7883
+ const ammConfigPda = await PdaUtils.getAmmConfigPda(index, this.programId);
7587
7884
  const instruction = await getCreateAmmConfigInstructionAsync({
7588
7885
  owner,
7589
7886
  ammConfig: ammConfigPda[0],
@@ -7636,7 +7933,7 @@ var Clmm = class {
7636
7933
  // src/pool-manager.ts
7637
7934
  var import_kit52 = require("@solana/kit");
7638
7935
  var import_token2 = require("@solana-program/token");
7639
- var import_bn5 = __toESM(require("bn.js"));
7936
+ var import_bn6 = __toESM(require("bn.js"));
7640
7937
  var import_decimal3 = __toESM(require("decimal.js"));
7641
7938
 
7642
7939
  // src/utils/token.ts
@@ -7657,7 +7954,9 @@ async function getToken(rpc, tokenAccount) {
7657
7954
  var PoolManager = class {
7658
7955
  constructor(config) {
7659
7956
  this.config = config;
7957
+ this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
7660
7958
  }
7959
+ programId;
7661
7960
  /**
7662
7961
  * Make create pool instructions
7663
7962
  * @param params - Pool creation parameters
@@ -7675,8 +7974,8 @@ var PoolManager = class {
7675
7974
  } = params;
7676
7975
  const addressA = (0, import_kit52.address)(tokenMintA);
7677
7976
  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))
7977
+ const isAFirst = new import_bn6.default(Buffer.from(addressB)).gt(
7978
+ new import_bn6.default(Buffer.from(addressA))
7680
7979
  );
7681
7980
  const [token0, token1, decimals0, decimals1, priceAdjusted] = isAFirst ? [tokenMintA, tokenMintB, mintADecimals, mintBDecimals, initialPrice] : [
7682
7981
  tokenMintB,
@@ -7693,12 +7992,13 @@ var PoolManager = class {
7693
7992
  const [poolPda] = await PdaUtils.getPoolStatePda(
7694
7993
  ammConfigId,
7695
7994
  token0,
7696
- token1
7995
+ token1,
7996
+ this.programId
7697
7997
  );
7698
- const [observationPda] = await PdaUtils.getObservationStatePda(poolPda);
7699
- const [tickArrayBitmapPda] = await PdaUtils.getTickArrayBitmapExtensionPda(poolPda);
7700
- const [tokenVault0] = await PdaUtils.getPoolVaultIdPda(poolPda, token0);
7701
- const [tokenVault1] = await PdaUtils.getPoolVaultIdPda(poolPda, token1);
7998
+ const [observationPda] = await PdaUtils.getObservationStatePda(poolPda, this.programId);
7999
+ const [tickArrayBitmapPda] = await PdaUtils.getTickArrayBitmapExtensionPda(poolPda, this.programId);
8000
+ const [tokenVault0] = await PdaUtils.getPoolVaultIdPda(poolPda, token0, this.programId);
8001
+ const [tokenVault1] = await PdaUtils.getPoolVaultIdPda(poolPda, token1, this.programId);
7702
8002
  const instruction = await getCreatePoolInstructionAsync({
7703
8003
  poolCreator: owner,
7704
8004
  ammConfig: ammConfigId,
@@ -7743,7 +8043,7 @@ var PoolManager = class {
7743
8043
  protocolFeeRate,
7744
8044
  fundFeeRate
7745
8045
  } = params;
7746
- const ammConfigPda = await PdaUtils.getAmmConfigPda(index);
8046
+ const ammConfigPda = await PdaUtils.getAmmConfigPda(index, this.programId);
7747
8047
  const instruction = getCreateAmmConfigInstruction({
7748
8048
  owner,
7749
8049
  ammConfig: ammConfigPda[0],
@@ -7795,17 +8095,18 @@ var PoolManager = class {
7795
8095
  * @returns Pool information if found
7796
8096
  */
7797
8097
  async getPoolByTokenPairAndConfig(tokenA, tokenB, ammConfigIndex = 0) {
7798
- const ammConfigPda = await PdaUtils.getAmmConfigPda(ammConfigIndex);
8098
+ const ammConfigPda = await PdaUtils.getAmmConfigPda(ammConfigIndex, this.programId);
7799
8099
  const poolPda = await PdaUtils.getPoolStatePda(
7800
8100
  ammConfigPda[0],
7801
8101
  tokenA,
7802
- tokenB
8102
+ tokenB,
8103
+ this.programId
7803
8104
  );
7804
8105
  return this.getPool(poolPda[0]);
7805
8106
  }
7806
8107
  async getAllPools(rpc) {
7807
8108
  try {
7808
- let accounts = await rpc.getProgramAccounts(STABBLE_CLMM_PROGRAM_ID, {
8109
+ let accounts = await rpc.getProgramAccounts(this.programId, {
7809
8110
  commitment: "finalized",
7810
8111
  encoding: "base64",
7811
8112
  filters: [
@@ -7858,7 +8159,7 @@ var PoolManager = class {
7858
8159
  getToken(this.config.rpc, poolState.tokenVault1)
7859
8160
  ]);
7860
8161
  const currentPrice = this.calculatePoolPrice(
7861
- new import_bn5.default(poolState.sqrtPriceX64.toString()),
8162
+ new import_bn6.default(poolState.sqrtPriceX64.toString()),
7862
8163
  tokenA.decimals,
7863
8164
  tokenB.decimals
7864
8165
  );
@@ -7903,7 +8204,7 @@ var PoolManager = class {
7903
8204
  var import_kit53 = require("@solana/kit");
7904
8205
  var import_token4 = require("@solana-program/token");
7905
8206
  var import_token_20222 = require("@solana-program/token-2022");
7906
- var import_bn6 = __toESM(require("bn.js"));
8207
+ var import_bn7 = __toESM(require("bn.js"));
7907
8208
 
7908
8209
  // ../node_modules/@solana/spl-token/lib/esm/constants.js
7909
8210
  var import_web3 = require("@solana/web3.js");
@@ -7920,7 +8221,9 @@ var TOKEN_ACCOUNT_SIZE = 165n;
7920
8221
  var PositionManager = class {
7921
8222
  constructor(config) {
7922
8223
  this.config = config;
8224
+ this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
7923
8225
  }
8226
+ programId;
7924
8227
  buildWrapSolInstructions(params) {
7925
8228
  const { payer, ata, owner, amount } = params;
7926
8229
  return [
@@ -8022,7 +8325,8 @@ var PositionManager = class {
8022
8325
  poolAccount.data.tickSpacing
8023
8326
  );
8024
8327
  const [positionStatePda] = await PdaUtils.getPositionStatePda(
8025
- nftMintAccount.address
8328
+ nftMintAccount.address,
8329
+ this.programId
8026
8330
  );
8027
8331
  const [metadataPda] = await getMetadataPda(nftMintAccount.address);
8028
8332
  const [positionNftAccountPda] = await (0, import_token4.findAssociatedTokenPda)({
@@ -8033,7 +8337,8 @@ var PositionManager = class {
8033
8337
  const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
8034
8338
  poolAccount.address,
8035
8339
  tickLower,
8036
- tickUpper
8340
+ tickUpper,
8341
+ this.programId
8037
8342
  );
8038
8343
  const instruction = await getOpenPositionWithToken22NftInstructionAsync({
8039
8344
  payer: ownerInfo.feePayer,
@@ -8108,14 +8413,17 @@ var PositionManager = class {
8108
8413
  );
8109
8414
  const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
8110
8415
  poolAccount.address,
8111
- tickArrayLowerStartIndex
8416
+ tickArrayLowerStartIndex,
8417
+ this.programId
8112
8418
  );
8113
8419
  const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
8114
8420
  poolAccount.address,
8115
- tickArrayUpperStartIndex
8421
+ tickArrayUpperStartIndex,
8422
+ this.programId
8116
8423
  );
8117
8424
  const [positionStatePda] = await PdaUtils.getPositionStatePda(
8118
- nftMintAccount.address
8425
+ nftMintAccount.address,
8426
+ this.programId
8119
8427
  );
8120
8428
  const [metadataPda] = await getMetadataPda(nftMintAccount.address);
8121
8429
  const [positionNftAccountPda] = await (0, import_token4.findAssociatedTokenPda)({
@@ -8126,7 +8434,8 @@ var PositionManager = class {
8126
8434
  const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
8127
8435
  poolAccount.address,
8128
8436
  tickLower,
8129
- tickUpper
8437
+ tickUpper,
8438
+ this.programId
8130
8439
  );
8131
8440
  const amount0Max = base === "MintA" ? baseAmount : otherAmountMax;
8132
8441
  const amount1Max = base === "MintA" ? otherAmountMax : baseAmount;
@@ -8134,7 +8443,7 @@ var PositionManager = class {
8134
8443
  poolAccount.data.tickSpacing,
8135
8444
  [tickArrayLowerStartIndex, tickArrayUpperStartIndex]
8136
8445
  );
8137
- const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolAccount.address) : void 0;
8446
+ const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolAccount.address, this.programId) : void 0;
8138
8447
  const remAccounts = extBitmapAccount ? [{ address: extBitmapAccount[0], role: import_kit53.AccountRole.WRITABLE }] : [];
8139
8448
  let wrapSolInstructions = [];
8140
8449
  if (poolAccount.data.tokenMint0.toString() === NATIVE_MINT.toString()) {
@@ -8210,7 +8519,8 @@ var PositionManager = class {
8210
8519
  amountMaxB
8211
8520
  } = params;
8212
8521
  const [personalPosition] = await PdaUtils.getPositionStatePda(
8213
- ownerPosition.nftMint
8522
+ ownerPosition.nftMint,
8523
+ this.programId
8214
8524
  );
8215
8525
  const [positionNftAccount] = await (0, import_token4.findAssociatedTokenPda)({
8216
8526
  mint: ownerPosition.nftMint,
@@ -8220,27 +8530,30 @@ var PositionManager = class {
8220
8530
  const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
8221
8531
  poolState.address,
8222
8532
  ownerPosition.tickLowerIndex,
8223
- ownerPosition.tickUpperIndex
8533
+ ownerPosition.tickUpperIndex,
8534
+ this.programId
8224
8535
  );
8225
8536
  const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
8226
8537
  poolState.address,
8227
8538
  PdaUtils.getTickArrayStartIndex(
8228
8539
  ownerPosition.tickLowerIndex,
8229
8540
  poolState.data.tickSpacing
8230
- )
8541
+ ),
8542
+ this.programId
8231
8543
  );
8232
8544
  const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
8233
8545
  poolState.address,
8234
8546
  PdaUtils.getTickArrayStartIndex(
8235
8547
  ownerPosition.tickUpperIndex,
8236
8548
  poolState.data.tickSpacing
8237
- )
8549
+ ),
8550
+ this.programId
8238
8551
  );
8239
8552
  const isOverflow = PoolUtils.isOverflowDefaultTickArrayBitmap(
8240
8553
  poolState.data.tickSpacing,
8241
8554
  [ownerPosition.tickLowerIndex, ownerPosition.tickUpperIndex]
8242
8555
  );
8243
- const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address) : void 0;
8556
+ const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address, this.programId) : void 0;
8244
8557
  const remAccounts = extBitmapAccount ? [{ address: extBitmapAccount[0], role: import_kit53.AccountRole.WRITABLE }] : [];
8245
8558
  const instruction = getIncreaseLiquidityV2Instruction({
8246
8559
  nftOwner: ownerInfo.wallet,
@@ -8298,7 +8611,8 @@ var PositionManager = class {
8298
8611
  } = params;
8299
8612
  const signers = [];
8300
8613
  const [personalPosition] = await PdaUtils.getPositionStatePda(
8301
- ownerPosition.nftMint
8614
+ ownerPosition.nftMint,
8615
+ this.programId
8302
8616
  );
8303
8617
  const [positionNftAccount] = await (0, import_token4.findAssociatedTokenPda)({
8304
8618
  mint: ownerPosition.nftMint,
@@ -8308,27 +8622,30 @@ var PositionManager = class {
8308
8622
  const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
8309
8623
  poolState.address,
8310
8624
  ownerPosition.tickLowerIndex,
8311
- ownerPosition.tickUpperIndex
8625
+ ownerPosition.tickUpperIndex,
8626
+ this.programId
8312
8627
  );
8313
8628
  const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
8314
8629
  poolState.address,
8315
8630
  PdaUtils.getTickArrayStartIndex(
8316
8631
  ownerPosition.tickLowerIndex,
8317
8632
  poolState.data.tickSpacing
8318
- )
8633
+ ),
8634
+ this.programId
8319
8635
  );
8320
8636
  const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
8321
8637
  poolState.address,
8322
8638
  PdaUtils.getTickArrayStartIndex(
8323
8639
  ownerPosition.tickUpperIndex,
8324
8640
  poolState.data.tickSpacing
8325
- )
8641
+ ),
8642
+ this.programId
8326
8643
  );
8327
8644
  const isOverflow = PoolUtils.isOverflowDefaultTickArrayBitmap(
8328
8645
  poolState.data.tickSpacing,
8329
8646
  [ownerPosition.tickLowerIndex, ownerPosition.tickUpperIndex]
8330
8647
  );
8331
- const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address) : void 0;
8648
+ const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address, this.programId) : void 0;
8332
8649
  const remAccounts = extBitmapAccount ? [{ address: extBitmapAccount[0], role: import_kit53.AccountRole.WRITABLE }] : [];
8333
8650
  const createRecipientAta0Ix = (0, import_token4.getCreateAssociatedTokenIdempotentInstruction)(
8334
8651
  {
@@ -8411,7 +8728,8 @@ var PositionManager = class {
8411
8728
  async makeClosePositionInstructions(params) {
8412
8729
  const { ownerPosition, ownerInfo } = params;
8413
8730
  const [personalPosition] = await PdaUtils.getPositionStatePda(
8414
- ownerPosition.nftMint
8731
+ ownerPosition.nftMint,
8732
+ this.programId
8415
8733
  );
8416
8734
  const [positionNftAccount] = await (0, import_token4.findAssociatedTokenPda)({
8417
8735
  mint: ownerPosition.nftMint,
@@ -8440,7 +8758,7 @@ var PositionManager = class {
8440
8758
  */
8441
8759
  async getPosition(positionMint) {
8442
8760
  try {
8443
- const positionStatePda = await PdaUtils.getPositionStatePda(positionMint);
8761
+ const positionStatePda = await PdaUtils.getPositionStatePda(positionMint, this.programId);
8444
8762
  const positionState = await fetchMaybePersonalPositionState(
8445
8763
  this.config.rpc,
8446
8764
  positionStatePda[0],
@@ -8461,21 +8779,22 @@ var PositionManager = class {
8461
8779
  * Enrich position state with computed fields from pool data
8462
8780
  * @param position - Raw position state from blockchain
8463
8781
  * @param pool - Pool state from blockchain
8782
+ * @param fees - Position fees
8464
8783
  * @returns Enriched position info with calculated amounts and prices
8465
8784
  */
8466
- enrichPositionInfo(position, pool) {
8785
+ enrichPositionInfo(position, pool, fees, rewards) {
8467
8786
  const sqrtPriceLowerX64 = SqrtPriceMath.getSqrtPriceX64FromTick(
8468
8787
  position.tickLowerIndex
8469
8788
  );
8470
8789
  const sqrtPriceUpperX64 = SqrtPriceMath.getSqrtPriceX64FromTick(
8471
8790
  position.tickUpperIndex
8472
8791
  );
8473
- const sqrtPriceCurrentX64 = new import_bn6.default(pool.sqrtPriceX64.toString());
8792
+ const sqrtPriceCurrentX64 = new import_bn7.default(pool.sqrtPriceX64.toString());
8474
8793
  const { amountA, amountB } = LiquidityMath.getAmountsFromLiquidity(
8475
8794
  sqrtPriceCurrentX64,
8476
8795
  sqrtPriceLowerX64,
8477
8796
  sqrtPriceUpperX64,
8478
- new import_bn6.default(position.liquidity.toString()),
8797
+ new import_bn7.default(position.liquidity.toString()),
8479
8798
  true
8480
8799
  );
8481
8800
  const [_amountA, _amountB] = [
@@ -8496,9 +8815,13 @@ var PositionManager = class {
8496
8815
  });
8497
8816
  const inRange = pool.tickCurrent >= position.tickLowerIndex && pool.tickCurrent < position.tickUpperIndex;
8498
8817
  const unclaimedFees = {
8499
- token0: new import_bn6.default(position.tokenFeesOwed0.toString()),
8500
- token1: new import_bn6.default(position.tokenFeesOwed1.toString())
8818
+ token0: fees?.tokenFees0 ? fees?.tokenFees0 : new import_bn7.default(0),
8819
+ token1: fees?.tokenFees1 ? fees?.tokenFees1 : new import_bn7.default(0)
8501
8820
  };
8821
+ const unclaimedRewards = rewards?.rewards ? rewards.rewards.map((amount, i) => ({
8822
+ mint: pool.rewardInfos[i]?.tokenMint,
8823
+ amount
8824
+ })).filter((r) => r.mint !== void 0) : void 0;
8502
8825
  const ageSeconds = 0;
8503
8826
  return {
8504
8827
  ...position,
@@ -8511,18 +8834,16 @@ var PositionManager = class {
8511
8834
  inRange,
8512
8835
  ageSeconds,
8513
8836
  unclaimedFees,
8514
- // valueUsd is optional and requires external price feeds
8515
- valueUsd: void 0,
8516
- // unclaimedRewards is optional
8517
- unclaimedRewards: void 0
8837
+ unclaimedRewards,
8838
+ valueUsd: void 0
8518
8839
  };
8519
8840
  }
8520
8841
  /**
8521
- * Get all positions for a wallet
8842
+ * Get raw positions for a wallet (without pool-state enrichment)
8522
8843
  * @param wallet - Wallet address
8523
- * @returns Array of positions owned by the wallet
8844
+ * @returns Array of raw position states owned by the wallet
8524
8845
  */
8525
- async getPositionsForWallet(wallet) {
8846
+ async getRawPositionsForWallet(wallet) {
8526
8847
  try {
8527
8848
  const response22 = await this.config.rpc.getTokenAccountsByOwner(
8528
8849
  wallet,
@@ -8539,29 +8860,7 @@ var PositionManager = class {
8539
8860
  (ta) => this.getPosition(ta.account.data.parsed.info.mint)
8540
8861
  )
8541
8862
  );
8542
- const validPositions = positions.filter(
8543
- (p) => !!p
8544
- );
8545
- const enrichedPositions = await Promise.all(
8546
- validPositions.map(async (position) => {
8547
- try {
8548
- const poolAccount = await fetchMaybePoolState(
8549
- this.config.rpc,
8550
- position.poolId,
8551
- { commitment: this.config.commitment }
8552
- );
8553
- if (!poolAccount.exists) {
8554
- console.warn(`Pool ${position.poolId} not found for position`);
8555
- return null;
8556
- }
8557
- return this.enrichPositionInfo(position, poolAccount.data);
8558
- } catch (error) {
8559
- console.error(`Failed to enrich position: ${error}`);
8560
- return null;
8561
- }
8562
- })
8563
- );
8564
- return enrichedPositions.filter((p) => !!p);
8863
+ return positions.filter((p) => !!p);
8565
8864
  } catch (error) {
8566
8865
  throw new ClmmError(
8567
8866
  "POSITION_NOT_FOUND" /* POSITION_NOT_FOUND */,
@@ -8569,6 +8868,146 @@ var PositionManager = class {
8569
8868
  );
8570
8869
  }
8571
8870
  }
8871
+ /**
8872
+ * Get all positions for a wallet, enriched with pool data
8873
+ * @param wallet - Wallet address
8874
+ * @returns Structured result with enriched positions and any failures
8875
+ */
8876
+ async getPositionsForWallet(wallet) {
8877
+ const rawPositions = await this.getRawPositionsForWallet(wallet);
8878
+ const results = await Promise.allSettled(
8879
+ rawPositions.map(async (position) => {
8880
+ const poolAccount = await fetchMaybePoolState(
8881
+ this.config.rpc,
8882
+ position.poolId,
8883
+ { commitment: this.config.commitment }
8884
+ );
8885
+ if (!poolAccount.exists) {
8886
+ throw new Error(`Pool ${position.poolId} not found for position`);
8887
+ }
8888
+ const { fees, rewards } = await this.getPositionFeeAndRewards(
8889
+ position,
8890
+ poolAccount.data
8891
+ );
8892
+ return this.enrichPositionInfo(
8893
+ position,
8894
+ poolAccount.data,
8895
+ fees,
8896
+ rewards
8897
+ );
8898
+ })
8899
+ );
8900
+ const positions = [];
8901
+ const failed = [];
8902
+ results.forEach((result, index) => {
8903
+ if (result.status === "fulfilled") {
8904
+ positions.push(result.value);
8905
+ } else {
8906
+ failed.push({
8907
+ position: rawPositions[index],
8908
+ error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
8909
+ });
8910
+ }
8911
+ });
8912
+ return { positions, failed };
8913
+ }
8914
+ /**
8915
+ * Calculate pending fees and rewards for a position.
8916
+ *
8917
+ * @param position - Personal position state
8918
+ * @param pool - Pool state
8919
+ * @returns Pending fees for both tokens and rewards for each reward token (up to 3)
8920
+ */
8921
+ async getPositionFeeAndRewards(position, pool) {
8922
+ const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
8923
+ position.poolId,
8924
+ PdaUtils.getTickArrayStartIndex(
8925
+ position.tickLowerIndex,
8926
+ pool.tickSpacing
8927
+ ),
8928
+ this.programId
8929
+ );
8930
+ const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
8931
+ position.poolId,
8932
+ PdaUtils.getTickArrayStartIndex(
8933
+ position.tickUpperIndex,
8934
+ pool.tickSpacing
8935
+ ),
8936
+ this.programId
8937
+ );
8938
+ const tickArrayLowerAccount = await fetchMaybeTickArrayState(
8939
+ this.config.rpc,
8940
+ tickArrayLower
8941
+ );
8942
+ const tickArrayUpperAccount = await fetchMaybeTickArrayState(
8943
+ this.config.rpc,
8944
+ tickArrayUpper
8945
+ );
8946
+ if (!tickArrayLowerAccount.exists || !tickArrayUpperAccount.exists) {
8947
+ console.log(
8948
+ "[getPositionFeeAndRewards] tick array state accounts do not exist."
8949
+ );
8950
+ return {
8951
+ fees: { tokenFees0: new import_bn7.default(0), tokenFees1: new import_bn7.default(0) },
8952
+ rewards: { rewards: [new import_bn7.default(0), new import_bn7.default(0), new import_bn7.default(0)] }
8953
+ };
8954
+ }
8955
+ const tickSpacing = pool.tickSpacing;
8956
+ const tickArrayLowerIndex = TickUtils.getTickOffsetInArray(
8957
+ position.tickLowerIndex,
8958
+ tickSpacing
8959
+ );
8960
+ const tickArrayUpperIndex = TickUtils.getTickOffsetInArray(
8961
+ position.tickUpperIndex,
8962
+ tickSpacing
8963
+ );
8964
+ if (tickArrayLowerIndex < 0 || tickArrayUpperIndex < 0) {
8965
+ console.log("[getPositionFeeAndRewards] tick array indexes < 0.");
8966
+ return {
8967
+ fees: { tokenFees0: new import_bn7.default(0), tokenFees1: new import_bn7.default(0) },
8968
+ rewards: { rewards: [new import_bn7.default(0), new import_bn7.default(0), new import_bn7.default(0)] }
8969
+ };
8970
+ }
8971
+ const lowerTickState = tickArrayLowerAccount.data.ticks[tickArrayLowerIndex];
8972
+ const upperTickState = tickArrayUpperAccount.data.ticks[tickArrayUpperIndex];
8973
+ const fees = PositionUtils.getPositionFees({
8974
+ liquidity: position.liquidity,
8975
+ tickLower: position.tickLowerIndex,
8976
+ tickUpper: position.tickUpperIndex,
8977
+ feeGrowthInside0LastX64: position.feeGrowthInside0LastX64,
8978
+ feeGrowthInside1LastX64: position.feeGrowthInside1LastX64,
8979
+ tokenFeesOwed0: position.tokenFeesOwed0,
8980
+ tokenFeesOwed1: position.tokenFeesOwed1,
8981
+ tickCurrent: pool.tickCurrent,
8982
+ feeGrowthGlobal0X64: pool.feeGrowthGlobal0X64,
8983
+ feeGrowthGlobal1X64: pool.feeGrowthGlobal1X64,
8984
+ tickLowerState: {
8985
+ feeGrowthOutside0X64: lowerTickState.feeGrowthOutside0X64,
8986
+ feeGrowthOutside1X64: lowerTickState.feeGrowthOutside1X64
8987
+ },
8988
+ tickUpperState: {
8989
+ feeGrowthOutside0X64: upperTickState.feeGrowthOutside0X64,
8990
+ feeGrowthOutside1X64: upperTickState.feeGrowthOutside1X64
8991
+ }
8992
+ });
8993
+ const rewards = PositionUtils.getPositionRewards({
8994
+ liquidity: position.liquidity,
8995
+ tickLower: position.tickLowerIndex,
8996
+ tickUpper: position.tickUpperIndex,
8997
+ positionRewardInfos: position.rewardInfos,
8998
+ tickCurrent: pool.tickCurrent,
8999
+ rewardInfos: pool.rewardInfos,
9000
+ tickLowerState: {
9001
+ liquidityGross: lowerTickState.liquidityGross,
9002
+ rewardGrowthsOutsideX64: lowerTickState.rewardGrowthsOutsideX64
9003
+ },
9004
+ tickUpperState: {
9005
+ liquidityGross: upperTickState.liquidityGross,
9006
+ rewardGrowthsOutsideX64: upperTickState.rewardGrowthsOutsideX64
9007
+ }
9008
+ });
9009
+ return { fees, rewards };
9010
+ }
8572
9011
  };
8573
9012
 
8574
9013
  // src/api/config.ts
@@ -9540,7 +9979,7 @@ var PriceApiClient = class _PriceApiClient {
9540
9979
  };
9541
9980
 
9542
9981
  // src/swap.ts
9543
- var import_bn7 = __toESM(require("bn.js"));
9982
+ var import_bn8 = __toESM(require("bn.js"));
9544
9983
  var import_decimal6 = __toESM(require("decimal.js"));
9545
9984
  var DEFAULT_RETRY_CONFIG = {
9546
9985
  maxRetries: 3,
@@ -9600,7 +10039,7 @@ var SwapMathEngine = class {
9600
10039
  slippageTolerance,
9601
10040
  poolAddress
9602
10041
  } = params;
9603
- if (amountIn.lte(new import_bn7.default(0))) {
10042
+ if (amountIn.lte(new import_bn8.default(0))) {
9604
10043
  throw new ClmmError(
9605
10044
  "SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
9606
10045
  "Swap amount must be greater than zero"
@@ -9612,8 +10051,8 @@ var SwapMathEngine = class {
9612
10051
  `Slippage tolerance must be between 0 and 1, got ${slippageTolerance}`
9613
10052
  );
9614
10053
  }
9615
- const liquidity = new import_bn7.default(pool.liquidity.toString());
9616
- const sqrtPriceCurrentX64 = new import_bn7.default(pool.sqrtPriceX64.toString());
10054
+ const liquidity = new import_bn8.default(pool.liquidity.toString());
10055
+ const sqrtPriceCurrentX64 = new import_bn8.default(pool.sqrtPriceX64.toString());
9617
10056
  const feeRate = ammConfig.tradeFeeRate;
9618
10057
  const sqrtPriceTargetX64 = this.calculateSqrtPriceLimit(
9619
10058
  sqrtPriceCurrentX64,
@@ -9641,9 +10080,9 @@ var SwapMathEngine = class {
9641
10080
  pool.mintDecimals1
9642
10081
  );
9643
10082
  const priceImpact = priceAfter.minus(priceBefore).div(priceBefore).abs().toNumber();
9644
- const slippageBN = new import_bn7.default(Math.floor(slippageTolerance * 1e4));
10083
+ const slippageBN = new import_bn8.default(Math.floor(slippageTolerance * 1e4));
9645
10084
  const minAmountOut = step.amountOut.sub(
9646
- step.amountOut.mul(slippageBN).div(new import_bn7.default(1e4))
10085
+ step.amountOut.mul(slippageBN).div(new import_bn8.default(1e4))
9647
10086
  );
9648
10087
  return {
9649
10088
  amountIn,
@@ -9690,17 +10129,17 @@ var SwapMathEngine = class {
9690
10129
  tickArrayCache
9691
10130
  } = params;
9692
10131
  const sqrtPriceLimitX64 = this.calculateSqrtPriceLimit(
9693
- new import_bn7.default(pool.sqrtPriceX64.toString()),
10132
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
9694
10133
  zeroForOne,
9695
10134
  slippageTolerance
9696
10135
  );
9697
10136
  const result = await SwapMath.swapCompute({
9698
10137
  poolState: {
9699
- sqrtPriceX64: new import_bn7.default(pool.sqrtPriceX64.toString()),
10138
+ sqrtPriceX64: new import_bn8.default(pool.sqrtPriceX64.toString()),
9700
10139
  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())
10140
+ liquidity: new import_bn8.default(pool.liquidity.toString()),
10141
+ feeGrowthGlobal0X64: new import_bn8.default(pool.feeGrowthGlobal0X64.toString()),
10142
+ feeGrowthGlobal1X64: new import_bn8.default(pool.feeGrowthGlobal1X64.toString())
9704
10143
  },
9705
10144
  tickArrayCache,
9706
10145
  tickSpacing: pool.tickSpacing,
@@ -9717,7 +10156,7 @@ var SwapMathEngine = class {
9717
10156
  poolId: poolAddress
9718
10157
  });
9719
10158
  const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
9720
- new import_bn7.default(pool.sqrtPriceX64.toString()),
10159
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
9721
10160
  pool.mintDecimals0,
9722
10161
  pool.mintDecimals1
9723
10162
  );
@@ -9727,9 +10166,9 @@ var SwapMathEngine = class {
9727
10166
  pool.mintDecimals1
9728
10167
  );
9729
10168
  const priceImpact = priceAfter.minus(priceBefore).div(priceBefore).abs().toNumber();
9730
- const slippageBN = new import_bn7.default(Math.floor(slippageTolerance * 1e4));
10169
+ const slippageBN = new import_bn8.default(Math.floor(slippageTolerance * 1e4));
9731
10170
  const minAmountOut = result.amountOut.sub(
9732
- result.amountOut.mul(slippageBN).div(new import_bn7.default(1e4))
10171
+ result.amountOut.mul(slippageBN).div(new import_bn8.default(1e4))
9733
10172
  );
9734
10173
  const feeImpact = ammConfig.tradeFeeRate / FEE_RATE_DENOMINATOR_NUMBER;
9735
10174
  return {
@@ -9773,10 +10212,10 @@ var SwapMathEngine = class {
9773
10212
  */
9774
10213
  calculateSqrtPriceLimit(sqrtPriceX64, zeroForOne, slippageTolerance) {
9775
10214
  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);
10215
+ const base = new import_bn8.default(1e4);
10216
+ 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);
10217
+ const min2 = new import_bn8.default(MIN_SQRT_PRICE_X64);
10218
+ const max = new import_bn8.default(MAX_SQRT_PRICE_X64);
9780
10219
  if (scaled.lt(min2)) return min2;
9781
10220
  if (scaled.gt(max)) return max;
9782
10221
  return scaled;
@@ -9869,6 +10308,7 @@ var SwapManager = class {
9869
10308
  constructor(config, managerConfig) {
9870
10309
  this.config = config;
9871
10310
  this.managerConfig = managerConfig;
10311
+ this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
9872
10312
  this.poolDataManager = new PoolDataManager(config, {
9873
10313
  cacheTTL: 2e3,
9874
10314
  immutability: "freeze",
@@ -9889,6 +10329,7 @@ var SwapManager = class {
9889
10329
  );
9890
10330
  }
9891
10331
  }
10332
+ programId;
9892
10333
  poolDataManager;
9893
10334
  mathEngine;
9894
10335
  priceApiClient;
@@ -10200,7 +10641,7 @@ var SwapManager = class {
10200
10641
  `Invalid slippage tolerance: ${slippageTolerance}. Must be between 0 and 1.`
10201
10642
  );
10202
10643
  }
10203
- if (amountIn.lte(new import_bn7.default(0))) {
10644
+ if (amountIn.lte(new import_bn8.default(0))) {
10204
10645
  throw new ClmmError(
10205
10646
  "SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
10206
10647
  "Swap amount must be greater than zero."
@@ -10302,7 +10743,7 @@ var SwapManager = class {
10302
10743
  `Invalid slippage tolerance: ${slippageTolerance}. Must be between 0 and 1.`
10303
10744
  );
10304
10745
  }
10305
- if (amountIn.lte(new import_bn7.default(0))) {
10746
+ if (amountIn.lte(new import_bn8.default(0))) {
10306
10747
  throw new ClmmError(
10307
10748
  "SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
10308
10749
  "Swap amount must be greater than zero."
@@ -10356,7 +10797,7 @@ var SwapManager = class {
10356
10797
  poolAddress
10357
10798
  });
10358
10799
  const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
10359
- new import_bn7.default(pool.sqrtPriceX64.toString()),
10800
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10360
10801
  pool.mintDecimals0,
10361
10802
  pool.mintDecimals1
10362
10803
  );
@@ -10466,21 +10907,21 @@ var SwapManager = class {
10466
10907
  * @returns Number of tick arrays to fetch (includes safety buffer)
10467
10908
  */
10468
10909
  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))) {
10910
+ const liquidity = new import_bn8.default(pool.liquidity.toString());
10911
+ if (liquidity.eq(new import_bn8.default(0)) || liquidity.lt(new import_bn8.default(1e3))) {
10471
10912
  return 10;
10472
10913
  }
10473
- const roughImpact = amountIn.mul(new import_bn7.default(1e3)).div(liquidity);
10914
+ const roughImpact = amountIn.mul(new import_bn8.default(1e3)).div(liquidity);
10474
10915
  let baseArrays;
10475
- if (roughImpact.lte(new import_bn7.default(1))) {
10916
+ if (roughImpact.lte(new import_bn8.default(1))) {
10476
10917
  baseArrays = 2;
10477
- } else if (roughImpact.lte(new import_bn7.default(10))) {
10918
+ } else if (roughImpact.lte(new import_bn8.default(10))) {
10478
10919
  baseArrays = 4;
10479
- } else if (roughImpact.lte(new import_bn7.default(50))) {
10920
+ } else if (roughImpact.lte(new import_bn8.default(50))) {
10480
10921
  baseArrays = 6;
10481
- } else if (roughImpact.lte(new import_bn7.default(100))) {
10922
+ } else if (roughImpact.lte(new import_bn8.default(100))) {
10482
10923
  baseArrays = 8;
10483
- } else if (roughImpact.lte(new import_bn7.default(200))) {
10924
+ } else if (roughImpact.lte(new import_bn8.default(200))) {
10484
10925
  baseArrays = 12;
10485
10926
  } else {
10486
10927
  baseArrays = 15;
@@ -10499,7 +10940,8 @@ var SwapManager = class {
10499
10940
  const startIndex = currentStartIndex + offset * TICKS_PER_ARRAY * tickSpacing;
10500
10941
  const [tickArrayPda] = await PdaUtils.getTickArrayStatePda(
10501
10942
  poolAddress,
10502
- startIndex
10943
+ startIndex,
10944
+ this.programId
10503
10945
  );
10504
10946
  tickArrayAddresses.push(tickArrayPda);
10505
10947
  }
@@ -10525,7 +10967,7 @@ var SwapManager = class {
10525
10967
  const decOut = zeroForOne ? pool.mintDecimals1 : pool.mintDecimals0;
10526
10968
  const promises = params.amounts.map(async (amountIn) => {
10527
10969
  try {
10528
- if (amountIn.lte(new import_bn7.default(0))) return;
10970
+ if (amountIn.lte(new import_bn8.default(0))) return;
10529
10971
  const quote = await this.mathEngine.calculateSimpleSwap({
10530
10972
  pool,
10531
10973
  ammConfig,
@@ -10567,7 +11009,7 @@ var SwapManager = class {
10567
11009
  options
10568
11010
  );
10569
11011
  const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
10570
- new import_bn7.default(pool.sqrtPriceX64.toString()),
11012
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10571
11013
  pool.mintDecimals0,
10572
11014
  pool.mintDecimals1
10573
11015
  );
@@ -10690,13 +11132,13 @@ var SwapManager = class {
10690
11132
  `Extremely high price impact: ${(quote.priceImpact * 100).toFixed(2)}%. Swap likely to fail or result in significant slippage.`
10691
11133
  );
10692
11134
  }
10693
- const oneUnit = new import_bn7.default(10).pow(new import_bn7.default(outputDecimals));
11135
+ const oneUnit = new import_bn8.default(10).pow(new import_bn8.default(outputDecimals));
10694
11136
  if (quote.amountOut.lt(oneUnit)) {
10695
11137
  warnings.push(
10696
11138
  `Output amount is less than 1 unit of the output token. Consider increasing input amount or slippage tolerance.`
10697
11139
  );
10698
11140
  }
10699
- if (quote.amountOut.lte(new import_bn7.default(0))) {
11141
+ if (quote.amountOut.lte(new import_bn8.default(0))) {
10700
11142
  errors.push(
10701
11143
  "Swap would result in zero output. Amount may be too small."
10702
11144
  );
@@ -10717,11 +11159,11 @@ var SwapManager = class {
10717
11159
  return {
10718
11160
  quote: {
10719
11161
  amountIn: params.amountIn,
10720
- amountOut: new import_bn7.default(0),
10721
- minAmountOut: new import_bn7.default(0),
11162
+ amountOut: new import_bn8.default(0),
11163
+ minAmountOut: new import_bn8.default(0),
10722
11164
  priceImpact: 0,
10723
11165
  route: [],
10724
- fee: new import_bn7.default(0)
11166
+ fee: new import_bn8.default(0)
10725
11167
  },
10726
11168
  willSucceed: false,
10727
11169
  errors,
@@ -10809,7 +11251,7 @@ var SwapManager = class {
10809
11251
  }
10810
11252
  const pool = await this.poolDataManager.getPoolState(poolAddress, options);
10811
11253
  const zeroForOne = params.tokenIn === pool.tokenMint0;
10812
- const [observationState] = await PdaUtils.getObservationStatePda(poolAddress);
11254
+ const [observationState] = await PdaUtils.getObservationStatePda(poolAddress, this.programId);
10813
11255
  const [inputTokenAccount] = await (0, import_token5.findAssociatedTokenPda)({
10814
11256
  mint: params.tokenIn,
10815
11257
  owner: payer.address,
@@ -10821,7 +11263,7 @@ var SwapManager = class {
10821
11263
  tokenProgram: import_token5.TOKEN_PROGRAM_ADDRESS
10822
11264
  });
10823
11265
  const sqrtPriceLimitX64 = params.sqrtPriceLimitX64 || this.mathEngine.calculateSqrtPriceLimit(
10824
- new import_bn7.default(pool.sqrtPriceX64.toString()),
11266
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10825
11267
  zeroForOne,
10826
11268
  params.slippageTolerance || DEFAULT_SLIPPAGE_TOLERANCE
10827
11269
  );
@@ -10846,7 +11288,7 @@ var SwapManager = class {
10846
11288
  async getCurrentPrice(poolAddress, options) {
10847
11289
  const pool = await this.poolDataManager.getPoolState(poolAddress, options);
10848
11290
  return SqrtPriceMath.sqrtPriceX64ToPrice(
10849
- new import_bn7.default(pool.sqrtPriceX64.toString()),
11291
+ new import_bn8.default(pool.sqrtPriceX64.toString()),
10850
11292
  pool.mintDecimals0,
10851
11293
  pool.mintDecimals1
10852
11294
  );
@@ -11059,11 +11501,13 @@ var DEFAULT_SDK_CONFIG = {
11059
11501
  PoolManager,
11060
11502
  PoolUtils,
11061
11503
  PositionManager,
11504
+ PositionUtils,
11062
11505
  PriceApiClient,
11063
11506
  Q128,
11064
11507
  Q64,
11065
11508
  SLIPPAGE_CALC,
11066
11509
  STABBLE_CLMM_PROGRAM_ID,
11510
+ STABBLE_CLMM_QAS_PROGRAM_ID,
11067
11511
  SYSTEM_PROGRAM_ID,
11068
11512
  SYSVAR_RENT_PROGRAM_ID,
11069
11513
  SqrtPriceMath,