@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/clmm.d.ts +1 -0
- package/lib/clmm.d.ts.map +1 -1
- package/lib/constants.d.ts +1 -0
- package/lib/constants.d.ts.map +1 -1
- package/lib/index.js +582 -138
- package/lib/index.mjs +580 -138
- package/lib/pool-manager.d.ts +1 -0
- package/lib/pool-manager.d.ts.map +1 -1
- package/lib/position-manager.d.ts +25 -4
- package/lib/position-manager.d.ts.map +1 -1
- package/lib/swap.d.ts +1 -0
- package/lib/swap.d.ts.map +1 -1
- package/lib/types.d.ts +9 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/pda.d.ts +19 -10
- package/lib/utils/pda.d.ts.map +1 -1
- package/lib/utils/position.d.ts +191 -0
- package/lib/utils/position.d.ts.map +1 -0
- package/lib/utils/tick.d.ts +1 -0
- package/lib/utils/tick.d.ts.map +1 -1
- package/lib/utils/tickQuery.d.ts +4 -4
- package/lib/utils/tickQuery.d.ts.map +1 -1
- package/package.json +1 -1
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
7679
|
-
new
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
8500
|
-
token1: new
|
|
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
|
-
|
|
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
|
|
8842
|
+
* Get raw positions for a wallet (without pool-state enrichment)
|
|
8522
8843
|
* @param wallet - Wallet address
|
|
8523
|
-
* @returns Array of
|
|
8844
|
+
* @returns Array of raw position states owned by the wallet
|
|
8524
8845
|
*/
|
|
8525
|
-
async
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
9616
|
-
const sqrtPriceCurrentX64 = new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
10138
|
+
sqrtPriceX64: new import_bn8.default(pool.sqrtPriceX64.toString()),
|
|
9700
10139
|
tickCurrent: pool.tickCurrent,
|
|
9701
|
-
liquidity: new
|
|
9702
|
-
feeGrowthGlobal0X64: new
|
|
9703
|
-
feeGrowthGlobal1X64: new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
9777
|
-
const scaled = zeroForOne ? sqrtPriceX64.mul(base.sub(new
|
|
9778
|
-
const min2 = new
|
|
9779
|
-
const max = new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
10470
|
-
if (liquidity.eq(new
|
|
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
|
|
10914
|
+
const roughImpact = amountIn.mul(new import_bn8.default(1e3)).div(liquidity);
|
|
10474
10915
|
let baseArrays;
|
|
10475
|
-
if (roughImpact.lte(new
|
|
10916
|
+
if (roughImpact.lte(new import_bn8.default(1))) {
|
|
10476
10917
|
baseArrays = 2;
|
|
10477
|
-
} else if (roughImpact.lte(new
|
|
10918
|
+
} else if (roughImpact.lte(new import_bn8.default(10))) {
|
|
10478
10919
|
baseArrays = 4;
|
|
10479
|
-
} else if (roughImpact.lte(new
|
|
10920
|
+
} else if (roughImpact.lte(new import_bn8.default(50))) {
|
|
10480
10921
|
baseArrays = 6;
|
|
10481
|
-
} else if (roughImpact.lte(new
|
|
10922
|
+
} else if (roughImpact.lte(new import_bn8.default(100))) {
|
|
10482
10923
|
baseArrays = 8;
|
|
10483
|
-
} else if (roughImpact.lte(new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
10721
|
-
minAmountOut: new
|
|
11162
|
+
amountOut: new import_bn8.default(0),
|
|
11163
|
+
minAmountOut: new import_bn8.default(0),
|
|
10722
11164
|
priceImpact: 0,
|
|
10723
11165
|
route: [],
|
|
10724
|
-
fee: new
|
|
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
|
|
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
|
|
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,
|