@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.mjs
CHANGED
|
@@ -5733,6 +5733,7 @@ import Decimal2 from "decimal.js";
|
|
|
5733
5733
|
// src/constants.ts
|
|
5734
5734
|
import BN from "bn.js";
|
|
5735
5735
|
var STABBLE_CLMM_PROGRAM_ID = "6dMXqGZ3ga2dikrYS9ovDXgHGh5RUsb2RTUj6hrQXhk6";
|
|
5736
|
+
var STABBLE_CLMM_QAS_PROGRAM_ID = "8896VTm3Z3g8PuktiDdW9JLxZP1ww2r5c9Tz5AbaBjAJ";
|
|
5736
5737
|
var METADATA_PROGRAM_ID = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s";
|
|
5737
5738
|
var SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
|
|
5738
5739
|
var SYSVAR_RENT_PROGRAM_ID = "SysvarRent111111111111111111111111111111111";
|
|
@@ -5898,6 +5899,22 @@ var TickUtils = class _TickUtils {
|
|
|
5898
5899
|
);
|
|
5899
5900
|
}
|
|
5900
5901
|
}
|
|
5902
|
+
static getTickOffsetInArray(tickIndex, tickSpacing) {
|
|
5903
|
+
if (tickIndex % tickSpacing != 0) {
|
|
5904
|
+
throw new Error("tickIndex % tickSpacing not equal 0");
|
|
5905
|
+
}
|
|
5906
|
+
const startTickIndex = _TickUtils.getTickArrayStartIndexByTick(
|
|
5907
|
+
tickIndex,
|
|
5908
|
+
tickSpacing
|
|
5909
|
+
);
|
|
5910
|
+
const offsetInArray = Math.floor(
|
|
5911
|
+
(tickIndex - startTickIndex) / tickSpacing
|
|
5912
|
+
);
|
|
5913
|
+
if (offsetInArray < 0 || offsetInArray >= TICK_ARRAY_SIZE) {
|
|
5914
|
+
throw new Error("tick offset in array overflow");
|
|
5915
|
+
}
|
|
5916
|
+
return offsetInArray;
|
|
5917
|
+
}
|
|
5901
5918
|
/**
|
|
5902
5919
|
* Get the start index of the tick array containing a specific tick
|
|
5903
5920
|
* @param tick - Target tick
|
|
@@ -6186,11 +6203,12 @@ var PdaUtils = class {
|
|
|
6186
6203
|
* @param ammConfig - AMM config address
|
|
6187
6204
|
* @param tokenMintA - Token A mint address
|
|
6188
6205
|
* @param tokenMintB - Token B mint address
|
|
6206
|
+
* @param programId - Program address (defaults to production)
|
|
6189
6207
|
* @returns Pool state PDA
|
|
6190
6208
|
*/
|
|
6191
|
-
static async getPoolStatePda(ammConfig, tokenMintA, tokenMintB) {
|
|
6209
|
+
static async getPoolStatePda(ammConfig, tokenMintA, tokenMintB, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6192
6210
|
return await getProgramDerivedAddress10({
|
|
6193
|
-
programAddress:
|
|
6211
|
+
programAddress: programId,
|
|
6194
6212
|
seeds: [
|
|
6195
6213
|
PDA_SEEDS.POOL_STATE,
|
|
6196
6214
|
addressEncoder.encode(ammConfig),
|
|
@@ -6202,22 +6220,24 @@ var PdaUtils = class {
|
|
|
6202
6220
|
/**
|
|
6203
6221
|
* Derive AMM config PDA
|
|
6204
6222
|
* @param index - Config index
|
|
6223
|
+
* @param programId - Program address (defaults to production)
|
|
6205
6224
|
* @returns AMM config PDA
|
|
6206
6225
|
*/
|
|
6207
|
-
static async getAmmConfigPda(index) {
|
|
6226
|
+
static async getAmmConfigPda(index, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6208
6227
|
return await getProgramDerivedAddress10({
|
|
6209
|
-
programAddress:
|
|
6228
|
+
programAddress: programId,
|
|
6210
6229
|
seeds: [PDA_SEEDS.AMM_CONFIG, getU16Encoder7().encode(index)]
|
|
6211
6230
|
});
|
|
6212
6231
|
}
|
|
6213
6232
|
/**
|
|
6214
6233
|
* Derive position state PDA
|
|
6215
6234
|
* @param nftMint - Position NFT mint address
|
|
6235
|
+
* @param programId - Program address (defaults to production)
|
|
6216
6236
|
* @returns Position state PDA
|
|
6217
6237
|
*/
|
|
6218
|
-
static async getPositionStatePda(nftMint) {
|
|
6238
|
+
static async getPositionStatePda(nftMint, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6219
6239
|
return await getProgramDerivedAddress10({
|
|
6220
|
-
programAddress:
|
|
6240
|
+
programAddress: programId,
|
|
6221
6241
|
seeds: [PDA_SEEDS.POSITION_STATE, addressEncoder.encode(nftMint)]
|
|
6222
6242
|
});
|
|
6223
6243
|
}
|
|
@@ -6225,11 +6245,12 @@ var PdaUtils = class {
|
|
|
6225
6245
|
* Derive tick array state PDA
|
|
6226
6246
|
* @param poolState - Pool state address
|
|
6227
6247
|
* @param startTickIndex - Starting tick index of the array
|
|
6248
|
+
* @param programId - Program address (defaults to production)
|
|
6228
6249
|
* @returns Tick array state PDA
|
|
6229
6250
|
*/
|
|
6230
|
-
static async getTickArrayStatePda(poolState, startTickIndex) {
|
|
6251
|
+
static async getTickArrayStatePda(poolState, startTickIndex, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6231
6252
|
return await getProgramDerivedAddress10({
|
|
6232
|
-
programAddress:
|
|
6253
|
+
programAddress: programId,
|
|
6233
6254
|
seeds: [
|
|
6234
6255
|
PDA_SEEDS.TICK_ARRAY_STATE,
|
|
6235
6256
|
addressEncoder.encode(poolState),
|
|
@@ -6240,32 +6261,34 @@ var PdaUtils = class {
|
|
|
6240
6261
|
/**
|
|
6241
6262
|
* Derive observation state PDA
|
|
6242
6263
|
* @param poolState - Pool state address
|
|
6264
|
+
* @param programId - Program address (defaults to production)
|
|
6243
6265
|
* @returns Observation state PDA
|
|
6244
6266
|
*/
|
|
6245
|
-
static async getObservationStatePda(poolState) {
|
|
6267
|
+
static async getObservationStatePda(poolState, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6246
6268
|
return await getProgramDerivedAddress10({
|
|
6247
|
-
programAddress:
|
|
6269
|
+
programAddress: programId,
|
|
6248
6270
|
seeds: [PDA_SEEDS.OBSERVATION_STATE, addressEncoder.encode(poolState)]
|
|
6249
6271
|
});
|
|
6250
6272
|
}
|
|
6251
|
-
static async getPoolVaultIdPda(poolAddress, vaultAddress) {
|
|
6273
|
+
static async getPoolVaultIdPda(poolAddress, vaultAddress, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6252
6274
|
return await getProgramDerivedAddress10({
|
|
6253
6275
|
seeds: [
|
|
6254
6276
|
PDA_SEEDS.POOL_VAULT,
|
|
6255
6277
|
addressEncoder.encode(poolAddress),
|
|
6256
6278
|
addressEncoder.encode(vaultAddress)
|
|
6257
6279
|
],
|
|
6258
|
-
programAddress:
|
|
6280
|
+
programAddress: programId
|
|
6259
6281
|
});
|
|
6260
6282
|
}
|
|
6261
6283
|
/**
|
|
6262
6284
|
* Derive tick array bitmap extension PDA
|
|
6263
6285
|
* @param poolState - Pool state address
|
|
6286
|
+
* @param programId - Program address (defaults to production)
|
|
6264
6287
|
* @returns Tick array bitmap extension PDA
|
|
6265
6288
|
*/
|
|
6266
|
-
static async getTickArrayBitmapExtensionPda(poolState) {
|
|
6289
|
+
static async getTickArrayBitmapExtensionPda(poolState, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6267
6290
|
return await getProgramDerivedAddress10({
|
|
6268
|
-
programAddress:
|
|
6291
|
+
programAddress: programId,
|
|
6269
6292
|
seeds: [PDA_SEEDS.BITMAP_EXTENSION, addressEncoder.encode(poolState)]
|
|
6270
6293
|
});
|
|
6271
6294
|
}
|
|
@@ -6288,9 +6311,10 @@ var PdaUtils = class {
|
|
|
6288
6311
|
* @param tickUpper - Upper tick of range
|
|
6289
6312
|
* @param tickSpacing - Tick spacing of the pool
|
|
6290
6313
|
* @param tickCurrent - Current pool tick
|
|
6314
|
+
* @param programId - Program address (defaults to production)
|
|
6291
6315
|
* @returns Array of tick array PDAs
|
|
6292
6316
|
*/
|
|
6293
|
-
static async getTickArrayPdasForRange(poolState, tickLower, tickUpper, tickSpacing, tickCurrent) {
|
|
6317
|
+
static async getTickArrayPdasForRange(poolState, tickLower, tickUpper, tickSpacing, tickCurrent, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6294
6318
|
const startIndexLower = this.getTickArrayStartIndex(tickLower, tickSpacing);
|
|
6295
6319
|
const startIndexUpper = this.getTickArrayStartIndex(tickUpper, tickSpacing);
|
|
6296
6320
|
const startIndexCurrent = this.getTickArrayStartIndex(
|
|
@@ -6304,7 +6328,7 @@ var PdaUtils = class {
|
|
|
6304
6328
|
]);
|
|
6305
6329
|
return await Promise.all(
|
|
6306
6330
|
Array.from(indices).map(
|
|
6307
|
-
(index) => this.getTickArrayStatePda(poolState, index)
|
|
6331
|
+
(index) => this.getTickArrayStatePda(poolState, index, programId)
|
|
6308
6332
|
)
|
|
6309
6333
|
);
|
|
6310
6334
|
}
|
|
@@ -6313,11 +6337,12 @@ var PdaUtils = class {
|
|
|
6313
6337
|
* @param poolState - Pool state address
|
|
6314
6338
|
* @param tickLowerIndex - Lower tick index
|
|
6315
6339
|
* @param tickUpperIndex - Upper tick index
|
|
6340
|
+
* @param programId - Program address (defaults to production)
|
|
6316
6341
|
* @returns Protocol position state PDA
|
|
6317
6342
|
*/
|
|
6318
|
-
static async getProtocolPositionStatePda(poolState, tickLowerIndex, tickUpperIndex) {
|
|
6343
|
+
static async getProtocolPositionStatePda(poolState, tickLowerIndex, tickUpperIndex, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6319
6344
|
return await getProgramDerivedAddress10({
|
|
6320
|
-
programAddress:
|
|
6345
|
+
programAddress: programId,
|
|
6321
6346
|
seeds: [
|
|
6322
6347
|
PDA_SEEDS.POSITION_STATE,
|
|
6323
6348
|
addressEncoder.encode(poolState),
|
|
@@ -6329,11 +6354,12 @@ var PdaUtils = class {
|
|
|
6329
6354
|
/**
|
|
6330
6355
|
* Derive operation state PDA
|
|
6331
6356
|
* @param poolState - Pool state address
|
|
6357
|
+
* @param programId - Program address (defaults to production)
|
|
6332
6358
|
* @returns Operation state PDA
|
|
6333
6359
|
*/
|
|
6334
|
-
static async getOperationStatePda(poolState) {
|
|
6360
|
+
static async getOperationStatePda(poolState, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6335
6361
|
return await getProgramDerivedAddress10({
|
|
6336
|
-
programAddress:
|
|
6362
|
+
programAddress: programId,
|
|
6337
6363
|
seeds: [PDA_SEEDS.OPERATION, addressEncoder.encode(poolState)]
|
|
6338
6364
|
});
|
|
6339
6365
|
}
|
|
@@ -6352,7 +6378,7 @@ async function getMetadataPda(mint) {
|
|
|
6352
6378
|
// src/utils/tickQuery.ts
|
|
6353
6379
|
var FETCH_TICKARRAY_COUNT = 15;
|
|
6354
6380
|
var TickQuery = class _TickQuery {
|
|
6355
|
-
static async getTickArrays(rpc, poolId, tickCurrent, tickSpacing, tickArrayBitmapArray, exTickArrayBitmap) {
|
|
6381
|
+
static async getTickArrays(rpc, poolId, tickCurrent, tickSpacing, tickArrayBitmapArray, exTickArrayBitmap, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6356
6382
|
const tickArraysToFetch = [];
|
|
6357
6383
|
const currentTickArrayStartIndex = TickUtils.getTickArrayStartIndexByTick(
|
|
6358
6384
|
tickCurrent,
|
|
@@ -6368,7 +6394,8 @@ var TickQuery = class _TickQuery {
|
|
|
6368
6394
|
for (let i = 0; i < startIndexArray.length; i++) {
|
|
6369
6395
|
const [tickArrayAddress] = await PdaUtils.getTickArrayStatePda(
|
|
6370
6396
|
poolId,
|
|
6371
|
-
startIndexArray[i]
|
|
6397
|
+
startIndexArray[i],
|
|
6398
|
+
programId
|
|
6372
6399
|
);
|
|
6373
6400
|
tickArraysToFetch.push(tickArrayAddress);
|
|
6374
6401
|
}
|
|
@@ -6423,7 +6450,7 @@ var TickQuery = class _TickQuery {
|
|
|
6423
6450
|
* @param zeroForOne - Search direction
|
|
6424
6451
|
* @returns First initialized tick, tick array address, and start index
|
|
6425
6452
|
*/
|
|
6426
|
-
static async firstInitializedTickInOneArray(poolId, tickArray, zeroForOne) {
|
|
6453
|
+
static async firstInitializedTickInOneArray(poolId, tickArray, zeroForOne, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6427
6454
|
let nextInitializedTick = void 0;
|
|
6428
6455
|
if (zeroForOne) {
|
|
6429
6456
|
for (let i = TICK_ARRAY_SIZE - 1; i >= 0; i--) {
|
|
@@ -6444,7 +6471,8 @@ var TickQuery = class _TickQuery {
|
|
|
6444
6471
|
}
|
|
6445
6472
|
const [tickArrayAddress] = await PdaUtils.getTickArrayStatePda(
|
|
6446
6473
|
poolId,
|
|
6447
|
-
tickArray.data.startTickIndex
|
|
6474
|
+
tickArray.data.startTickIndex,
|
|
6475
|
+
programId
|
|
6448
6476
|
);
|
|
6449
6477
|
return {
|
|
6450
6478
|
nextTick: nextInitializedTick,
|
|
@@ -6462,7 +6490,7 @@ var TickQuery = class _TickQuery {
|
|
|
6462
6490
|
* @param zeroForOne - Search direction
|
|
6463
6491
|
* @returns Next initialized tick info
|
|
6464
6492
|
*/
|
|
6465
|
-
static async nextInitializedTickInOneArray(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne) {
|
|
6493
|
+
static async nextInitializedTickInOneArray(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6466
6494
|
const startIndex = TickUtils.getTickArrayStartIndexByTick(
|
|
6467
6495
|
tickIndex,
|
|
6468
6496
|
tickSpacing
|
|
@@ -6501,7 +6529,8 @@ var TickQuery = class _TickQuery {
|
|
|
6501
6529
|
}
|
|
6502
6530
|
const [tickArrayAddress] = await PdaUtils.getTickArrayStatePda(
|
|
6503
6531
|
poolId,
|
|
6504
|
-
startIndex
|
|
6532
|
+
startIndex,
|
|
6533
|
+
programId
|
|
6505
6534
|
);
|
|
6506
6535
|
return {
|
|
6507
6536
|
initializedTick: nextInitializedTick,
|
|
@@ -6519,7 +6548,7 @@ var TickQuery = class _TickQuery {
|
|
|
6519
6548
|
* @param zeroForOne - Search direction
|
|
6520
6549
|
* @returns Next initialized tick info
|
|
6521
6550
|
*/
|
|
6522
|
-
static async nextInitializedTick(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne) {
|
|
6551
|
+
static async nextInitializedTick(poolId, tickArrayCache, tickIndex, tickSpacing, zeroForOne, programId = STABBLE_CLMM_PROGRAM_ID) {
|
|
6523
6552
|
let {
|
|
6524
6553
|
initializedTick: nextTick,
|
|
6525
6554
|
tickArrayAddress,
|
|
@@ -6529,7 +6558,8 @@ var TickQuery = class _TickQuery {
|
|
|
6529
6558
|
tickArrayCache,
|
|
6530
6559
|
tickIndex,
|
|
6531
6560
|
tickSpacing,
|
|
6532
|
-
zeroForOne
|
|
6561
|
+
zeroForOne,
|
|
6562
|
+
programId
|
|
6533
6563
|
);
|
|
6534
6564
|
while (nextTick === void 0 || nextTick.liquidityGross <= 0n) {
|
|
6535
6565
|
const nextArrayStartIndex = zeroForOne ? tickArrayStartTickIndex - this.tickCount(tickSpacing) : tickArrayStartTickIndex + this.tickCount(tickSpacing);
|
|
@@ -6546,7 +6576,8 @@ var TickQuery = class _TickQuery {
|
|
|
6546
6576
|
const result = await this.firstInitializedTickInOneArray(
|
|
6547
6577
|
poolId,
|
|
6548
6578
|
cachedTickArray,
|
|
6549
|
-
zeroForOne
|
|
6579
|
+
zeroForOne,
|
|
6580
|
+
programId
|
|
6550
6581
|
);
|
|
6551
6582
|
nextTick = result.nextTick;
|
|
6552
6583
|
tickArrayAddress = result.tickArrayAddress;
|
|
@@ -8028,6 +8059,268 @@ var PoolUtils = class {
|
|
|
8028
8059
|
}
|
|
8029
8060
|
};
|
|
8030
8061
|
|
|
8062
|
+
// src/utils/position.ts
|
|
8063
|
+
import BN5 from "bn.js";
|
|
8064
|
+
var PositionUtils = class _PositionUtils {
|
|
8065
|
+
/**
|
|
8066
|
+
* Calculate fee growth inside a position's tick range.
|
|
8067
|
+
*
|
|
8068
|
+
* formula:
|
|
8069
|
+
* ```
|
|
8070
|
+
* feeGrowthInside = feeGrowthGlobal - feeGrowthBelow - feeGrowthAbove
|
|
8071
|
+
* ```
|
|
8072
|
+
*
|
|
8073
|
+
* Where feeGrowthBelow and feeGrowthAbove depend on the current tick
|
|
8074
|
+
* relative to the position's tick boundaries.
|
|
8075
|
+
*
|
|
8076
|
+
* @param params - Parameters for fee growth calculation
|
|
8077
|
+
* @returns Fee growth inside for both tokens (X64 fixed-point)
|
|
8078
|
+
*/
|
|
8079
|
+
static getFeeGrowthInside(params) {
|
|
8080
|
+
const {
|
|
8081
|
+
tickCurrent,
|
|
8082
|
+
tickLower,
|
|
8083
|
+
tickUpper,
|
|
8084
|
+
tickLowerState,
|
|
8085
|
+
tickUpperState,
|
|
8086
|
+
feeGrowthGlobal0X64,
|
|
8087
|
+
feeGrowthGlobal1X64
|
|
8088
|
+
} = params;
|
|
8089
|
+
const feeGrowthGlobal0 = new BN5(feeGrowthGlobal0X64.toString());
|
|
8090
|
+
const feeGrowthGlobal1 = new BN5(feeGrowthGlobal1X64.toString());
|
|
8091
|
+
const tickLowerFeeGrowthOutside0 = new BN5(
|
|
8092
|
+
tickLowerState.feeGrowthOutside0X64.toString()
|
|
8093
|
+
);
|
|
8094
|
+
const tickLowerFeeGrowthOutside1 = new BN5(
|
|
8095
|
+
tickLowerState.feeGrowthOutside1X64.toString()
|
|
8096
|
+
);
|
|
8097
|
+
const tickUpperFeeGrowthOutside0 = new BN5(
|
|
8098
|
+
tickUpperState.feeGrowthOutside0X64.toString()
|
|
8099
|
+
);
|
|
8100
|
+
const tickUpperFeeGrowthOutside1 = new BN5(
|
|
8101
|
+
tickUpperState.feeGrowthOutside1X64.toString()
|
|
8102
|
+
);
|
|
8103
|
+
let feeGrowthBelow0X64;
|
|
8104
|
+
let feeGrowthBelow1X64;
|
|
8105
|
+
if (tickCurrent >= tickLower) {
|
|
8106
|
+
feeGrowthBelow0X64 = tickLowerFeeGrowthOutside0;
|
|
8107
|
+
feeGrowthBelow1X64 = tickLowerFeeGrowthOutside1;
|
|
8108
|
+
} else {
|
|
8109
|
+
feeGrowthBelow0X64 = MathUtils.wrappingSubU128(
|
|
8110
|
+
feeGrowthGlobal0,
|
|
8111
|
+
tickLowerFeeGrowthOutside0
|
|
8112
|
+
);
|
|
8113
|
+
feeGrowthBelow1X64 = MathUtils.wrappingSubU128(
|
|
8114
|
+
feeGrowthGlobal1,
|
|
8115
|
+
tickLowerFeeGrowthOutside1
|
|
8116
|
+
);
|
|
8117
|
+
}
|
|
8118
|
+
let feeGrowthAbove0X64;
|
|
8119
|
+
let feeGrowthAbove1X64;
|
|
8120
|
+
if (tickCurrent < tickUpper) {
|
|
8121
|
+
feeGrowthAbove0X64 = tickUpperFeeGrowthOutside0;
|
|
8122
|
+
feeGrowthAbove1X64 = tickUpperFeeGrowthOutside1;
|
|
8123
|
+
} else {
|
|
8124
|
+
feeGrowthAbove0X64 = MathUtils.wrappingSubU128(
|
|
8125
|
+
feeGrowthGlobal0,
|
|
8126
|
+
tickUpperFeeGrowthOutside0
|
|
8127
|
+
);
|
|
8128
|
+
feeGrowthAbove1X64 = MathUtils.wrappingSubU128(
|
|
8129
|
+
feeGrowthGlobal1,
|
|
8130
|
+
tickUpperFeeGrowthOutside1
|
|
8131
|
+
);
|
|
8132
|
+
}
|
|
8133
|
+
const feeGrowthInside0X64 = MathUtils.wrappingSubU128(
|
|
8134
|
+
MathUtils.wrappingSubU128(feeGrowthGlobal0, feeGrowthBelow0X64),
|
|
8135
|
+
feeGrowthAbove0X64
|
|
8136
|
+
);
|
|
8137
|
+
const feeGrowthInside1X64 = MathUtils.wrappingSubU128(
|
|
8138
|
+
MathUtils.wrappingSubU128(feeGrowthGlobal1, feeGrowthBelow1X64),
|
|
8139
|
+
feeGrowthAbove1X64
|
|
8140
|
+
);
|
|
8141
|
+
return {
|
|
8142
|
+
feeGrowthInside0X64,
|
|
8143
|
+
feeGrowthInside1X64
|
|
8144
|
+
};
|
|
8145
|
+
}
|
|
8146
|
+
/**
|
|
8147
|
+
* Calculate pending fees for a position.
|
|
8148
|
+
*
|
|
8149
|
+
* Formula:
|
|
8150
|
+
* ```
|
|
8151
|
+
* feeDelta = (feeGrowthInside - feeGrowthInsideLast) × liquidity / 2^64
|
|
8152
|
+
* totalFees = tokenFeesOwed + feeDelta
|
|
8153
|
+
* ```
|
|
8154
|
+
*
|
|
8155
|
+
* @param params - Parameters for fee calculation
|
|
8156
|
+
* @returns Pending fees for both tokens in native units
|
|
8157
|
+
*/
|
|
8158
|
+
static getPositionFees(params) {
|
|
8159
|
+
const {
|
|
8160
|
+
liquidity,
|
|
8161
|
+
tickLower,
|
|
8162
|
+
tickUpper,
|
|
8163
|
+
feeGrowthInside0LastX64,
|
|
8164
|
+
feeGrowthInside1LastX64,
|
|
8165
|
+
tokenFeesOwed0,
|
|
8166
|
+
tokenFeesOwed1,
|
|
8167
|
+
tickCurrent,
|
|
8168
|
+
feeGrowthGlobal0X64,
|
|
8169
|
+
feeGrowthGlobal1X64,
|
|
8170
|
+
tickLowerState,
|
|
8171
|
+
tickUpperState
|
|
8172
|
+
} = params;
|
|
8173
|
+
const { feeGrowthInside0X64, feeGrowthInside1X64 } = _PositionUtils.getFeeGrowthInside({
|
|
8174
|
+
tickCurrent,
|
|
8175
|
+
tickLower,
|
|
8176
|
+
tickUpper,
|
|
8177
|
+
tickLowerState,
|
|
8178
|
+
tickUpperState,
|
|
8179
|
+
feeGrowthGlobal0X64,
|
|
8180
|
+
feeGrowthGlobal1X64
|
|
8181
|
+
});
|
|
8182
|
+
const liquidityBN = new BN5(liquidity.toString());
|
|
8183
|
+
const feeGrowthInside0Last = new BN5(feeGrowthInside0LastX64.toString());
|
|
8184
|
+
const feeGrowthInside1Last = new BN5(feeGrowthInside1LastX64.toString());
|
|
8185
|
+
const feesOwed0 = new BN5(tokenFeesOwed0.toString());
|
|
8186
|
+
const feesOwed1 = new BN5(tokenFeesOwed1.toString());
|
|
8187
|
+
const feeGrowthDelta0 = MathUtils.wrappingSubU128(
|
|
8188
|
+
feeGrowthInside0X64,
|
|
8189
|
+
feeGrowthInside0Last
|
|
8190
|
+
);
|
|
8191
|
+
const feeGrowthDelta1 = MathUtils.wrappingSubU128(
|
|
8192
|
+
feeGrowthInside1X64,
|
|
8193
|
+
feeGrowthInside1Last
|
|
8194
|
+
);
|
|
8195
|
+
const feeAmount0 = MathUtils.mulDivFloor(feeGrowthDelta0, liquidityBN, Q64);
|
|
8196
|
+
const feeAmount1 = MathUtils.mulDivFloor(feeGrowthDelta1, liquidityBN, Q64);
|
|
8197
|
+
return {
|
|
8198
|
+
tokenFees0: feesOwed0.add(feeAmount0),
|
|
8199
|
+
tokenFees1: feesOwed1.add(feeAmount1)
|
|
8200
|
+
};
|
|
8201
|
+
}
|
|
8202
|
+
/**
|
|
8203
|
+
* Calculate reward growth inside a position's tick range for all reward tokens.
|
|
8204
|
+
*
|
|
8205
|
+
* Formula:
|
|
8206
|
+
* ```
|
|
8207
|
+
* rewardGrowthInside = rewardGrowthGlobal - rewardGrowthBelow - rewardGrowthAbove
|
|
8208
|
+
* ```
|
|
8209
|
+
*
|
|
8210
|
+
* Special cases:
|
|
8211
|
+
* - If tickLower has no liquidity (liquidityGross = 0), rewardGrowthBelow = rewardGrowthGlobal
|
|
8212
|
+
* - If tickUpper has no liquidity (liquidityGross = 0), rewardGrowthAbove = 0
|
|
8213
|
+
*
|
|
8214
|
+
* @param params - Parameters for reward growth calculation
|
|
8215
|
+
* @returns Reward growth inside for each reward token (X64 fixed-point)
|
|
8216
|
+
*/
|
|
8217
|
+
static getRewardGrowthInside(params) {
|
|
8218
|
+
const {
|
|
8219
|
+
tickCurrent,
|
|
8220
|
+
tickLower,
|
|
8221
|
+
tickUpper,
|
|
8222
|
+
tickLowerState,
|
|
8223
|
+
tickUpperState,
|
|
8224
|
+
rewardInfos
|
|
8225
|
+
} = params;
|
|
8226
|
+
const rewardGrowthsInside = [];
|
|
8227
|
+
for (let i = 0; i < rewardInfos.length; i++) {
|
|
8228
|
+
const rewardGrowthGlobal = new BN5(
|
|
8229
|
+
rewardInfos[i].rewardGrowthGlobalX64.toString()
|
|
8230
|
+
);
|
|
8231
|
+
let rewardGrowthBelow;
|
|
8232
|
+
if (tickLowerState.liquidityGross === 0n) {
|
|
8233
|
+
rewardGrowthBelow = rewardGrowthGlobal;
|
|
8234
|
+
} else if (tickCurrent < tickLower) {
|
|
8235
|
+
rewardGrowthBelow = rewardGrowthGlobal.sub(
|
|
8236
|
+
new BN5(tickLowerState.rewardGrowthsOutsideX64[i].toString())
|
|
8237
|
+
);
|
|
8238
|
+
} else {
|
|
8239
|
+
rewardGrowthBelow = new BN5(
|
|
8240
|
+
tickLowerState.rewardGrowthsOutsideX64[i].toString()
|
|
8241
|
+
);
|
|
8242
|
+
}
|
|
8243
|
+
let rewardGrowthAbove;
|
|
8244
|
+
if (tickUpperState.liquidityGross === 0n) {
|
|
8245
|
+
rewardGrowthAbove = new BN5(0);
|
|
8246
|
+
} else if (tickCurrent < tickUpper) {
|
|
8247
|
+
rewardGrowthAbove = new BN5(
|
|
8248
|
+
tickUpperState.rewardGrowthsOutsideX64[i].toString()
|
|
8249
|
+
);
|
|
8250
|
+
} else {
|
|
8251
|
+
rewardGrowthAbove = rewardGrowthGlobal.sub(
|
|
8252
|
+
new BN5(tickUpperState.rewardGrowthsOutsideX64[i].toString())
|
|
8253
|
+
);
|
|
8254
|
+
}
|
|
8255
|
+
const rewardGrowthInside = MathUtils.wrappingSubU128(
|
|
8256
|
+
MathUtils.wrappingSubU128(rewardGrowthGlobal, rewardGrowthBelow),
|
|
8257
|
+
rewardGrowthAbove
|
|
8258
|
+
);
|
|
8259
|
+
rewardGrowthsInside.push(rewardGrowthInside);
|
|
8260
|
+
}
|
|
8261
|
+
return rewardGrowthsInside;
|
|
8262
|
+
}
|
|
8263
|
+
/**
|
|
8264
|
+
* Calculate pending rewards for a position.
|
|
8265
|
+
*
|
|
8266
|
+
* Formula:
|
|
8267
|
+
* ```
|
|
8268
|
+
* rewardDelta = (rewardGrowthInside - rewardGrowthInsideLast) × liquidity / 2^64
|
|
8269
|
+
* totalReward = rewardAmountOwed + rewardDelta
|
|
8270
|
+
* ```
|
|
8271
|
+
*
|
|
8272
|
+
* @param params - Parameters for reward calculation
|
|
8273
|
+
* @returns Pending rewards for each reward token in native units
|
|
8274
|
+
*/
|
|
8275
|
+
static getPositionRewards(params) {
|
|
8276
|
+
const {
|
|
8277
|
+
liquidity,
|
|
8278
|
+
tickLower,
|
|
8279
|
+
tickUpper,
|
|
8280
|
+
positionRewardInfos,
|
|
8281
|
+
tickCurrent,
|
|
8282
|
+
rewardInfos,
|
|
8283
|
+
tickLowerState,
|
|
8284
|
+
tickUpperState
|
|
8285
|
+
} = params;
|
|
8286
|
+
const rewardGrowthsInside = _PositionUtils.getRewardGrowthInside({
|
|
8287
|
+
tickCurrent,
|
|
8288
|
+
tickLower,
|
|
8289
|
+
tickUpper,
|
|
8290
|
+
tickLowerState,
|
|
8291
|
+
tickUpperState,
|
|
8292
|
+
rewardInfos
|
|
8293
|
+
});
|
|
8294
|
+
const liquidityBN = new BN5(liquidity.toString());
|
|
8295
|
+
const rewards = [];
|
|
8296
|
+
for (let i = 0; i < rewardGrowthsInside.length; i++) {
|
|
8297
|
+
const rewardGrowthInside = rewardGrowthsInside[i];
|
|
8298
|
+
const positionRewardInfo = positionRewardInfos[i];
|
|
8299
|
+
if (!positionRewardInfo) {
|
|
8300
|
+
rewards.push(new BN5(0));
|
|
8301
|
+
continue;
|
|
8302
|
+
}
|
|
8303
|
+
const growthInsideLast = new BN5(
|
|
8304
|
+
positionRewardInfo.growthInsideLastX64.toString()
|
|
8305
|
+
);
|
|
8306
|
+
const rewardAmountOwed = new BN5(
|
|
8307
|
+
positionRewardInfo.rewardAmountOwed.toString()
|
|
8308
|
+
);
|
|
8309
|
+
const rewardGrowthDelta = MathUtils.wrappingSubU128(
|
|
8310
|
+
rewardGrowthInside,
|
|
8311
|
+
growthInsideLast
|
|
8312
|
+
);
|
|
8313
|
+
const rewardAmountDelta = MathUtils.mulDivFloor(
|
|
8314
|
+
rewardGrowthDelta,
|
|
8315
|
+
liquidityBN,
|
|
8316
|
+
Q64
|
|
8317
|
+
);
|
|
8318
|
+
rewards.push(rewardAmountOwed.add(rewardAmountDelta));
|
|
8319
|
+
}
|
|
8320
|
+
return { rewards };
|
|
8321
|
+
}
|
|
8322
|
+
};
|
|
8323
|
+
|
|
8031
8324
|
// src/utils/index.ts
|
|
8032
8325
|
import {
|
|
8033
8326
|
getAddressEncoder as getAddressEncoder29
|
|
@@ -8127,7 +8420,9 @@ function getApisFromEndpoint(rpc) {
|
|
|
8127
8420
|
var Clmm = class {
|
|
8128
8421
|
constructor(config) {
|
|
8129
8422
|
this.config = config;
|
|
8423
|
+
this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
|
|
8130
8424
|
}
|
|
8425
|
+
programId;
|
|
8131
8426
|
/**
|
|
8132
8427
|
* Create a new AMM configuration
|
|
8133
8428
|
* @param params - Configuration parameters
|
|
@@ -8142,7 +8437,7 @@ var Clmm = class {
|
|
|
8142
8437
|
protocolFeeRate,
|
|
8143
8438
|
fundFeeRate
|
|
8144
8439
|
} = params;
|
|
8145
|
-
const ammConfigPda = await PdaUtils.getAmmConfigPda(index);
|
|
8440
|
+
const ammConfigPda = await PdaUtils.getAmmConfigPda(index, this.programId);
|
|
8146
8441
|
const instruction = await getCreateAmmConfigInstructionAsync({
|
|
8147
8442
|
owner,
|
|
8148
8443
|
ammConfig: ammConfigPda[0],
|
|
@@ -8197,7 +8492,7 @@ import {
|
|
|
8197
8492
|
address as address3
|
|
8198
8493
|
} from "@solana/kit";
|
|
8199
8494
|
import { TOKEN_PROGRAM_ADDRESS as TOKEN_PROGRAM_ADDRESS2 } from "@solana-program/token";
|
|
8200
|
-
import
|
|
8495
|
+
import BN6 from "bn.js";
|
|
8201
8496
|
import Decimal3 from "decimal.js";
|
|
8202
8497
|
|
|
8203
8498
|
// src/utils/token.ts
|
|
@@ -8221,7 +8516,9 @@ async function getToken(rpc, tokenAccount) {
|
|
|
8221
8516
|
var PoolManager = class {
|
|
8222
8517
|
constructor(config) {
|
|
8223
8518
|
this.config = config;
|
|
8519
|
+
this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
|
|
8224
8520
|
}
|
|
8521
|
+
programId;
|
|
8225
8522
|
/**
|
|
8226
8523
|
* Make create pool instructions
|
|
8227
8524
|
* @param params - Pool creation parameters
|
|
@@ -8239,8 +8536,8 @@ var PoolManager = class {
|
|
|
8239
8536
|
} = params;
|
|
8240
8537
|
const addressA = address3(tokenMintA);
|
|
8241
8538
|
const addressB = address3(tokenMintB);
|
|
8242
|
-
const isAFirst = new
|
|
8243
|
-
new
|
|
8539
|
+
const isAFirst = new BN6(Buffer.from(addressB)).gt(
|
|
8540
|
+
new BN6(Buffer.from(addressA))
|
|
8244
8541
|
);
|
|
8245
8542
|
const [token0, token1, decimals0, decimals1, priceAdjusted] = isAFirst ? [tokenMintA, tokenMintB, mintADecimals, mintBDecimals, initialPrice] : [
|
|
8246
8543
|
tokenMintB,
|
|
@@ -8257,12 +8554,13 @@ var PoolManager = class {
|
|
|
8257
8554
|
const [poolPda] = await PdaUtils.getPoolStatePda(
|
|
8258
8555
|
ammConfigId,
|
|
8259
8556
|
token0,
|
|
8260
|
-
token1
|
|
8557
|
+
token1,
|
|
8558
|
+
this.programId
|
|
8261
8559
|
);
|
|
8262
|
-
const [observationPda] = await PdaUtils.getObservationStatePda(poolPda);
|
|
8263
|
-
const [tickArrayBitmapPda] = await PdaUtils.getTickArrayBitmapExtensionPda(poolPda);
|
|
8264
|
-
const [tokenVault0] = await PdaUtils.getPoolVaultIdPda(poolPda, token0);
|
|
8265
|
-
const [tokenVault1] = await PdaUtils.getPoolVaultIdPda(poolPda, token1);
|
|
8560
|
+
const [observationPda] = await PdaUtils.getObservationStatePda(poolPda, this.programId);
|
|
8561
|
+
const [tickArrayBitmapPda] = await PdaUtils.getTickArrayBitmapExtensionPda(poolPda, this.programId);
|
|
8562
|
+
const [tokenVault0] = await PdaUtils.getPoolVaultIdPda(poolPda, token0, this.programId);
|
|
8563
|
+
const [tokenVault1] = await PdaUtils.getPoolVaultIdPda(poolPda, token1, this.programId);
|
|
8266
8564
|
const instruction = await getCreatePoolInstructionAsync({
|
|
8267
8565
|
poolCreator: owner,
|
|
8268
8566
|
ammConfig: ammConfigId,
|
|
@@ -8307,7 +8605,7 @@ var PoolManager = class {
|
|
|
8307
8605
|
protocolFeeRate,
|
|
8308
8606
|
fundFeeRate
|
|
8309
8607
|
} = params;
|
|
8310
|
-
const ammConfigPda = await PdaUtils.getAmmConfigPda(index);
|
|
8608
|
+
const ammConfigPda = await PdaUtils.getAmmConfigPda(index, this.programId);
|
|
8311
8609
|
const instruction = getCreateAmmConfigInstruction({
|
|
8312
8610
|
owner,
|
|
8313
8611
|
ammConfig: ammConfigPda[0],
|
|
@@ -8359,17 +8657,18 @@ var PoolManager = class {
|
|
|
8359
8657
|
* @returns Pool information if found
|
|
8360
8658
|
*/
|
|
8361
8659
|
async getPoolByTokenPairAndConfig(tokenA, tokenB, ammConfigIndex = 0) {
|
|
8362
|
-
const ammConfigPda = await PdaUtils.getAmmConfigPda(ammConfigIndex);
|
|
8660
|
+
const ammConfigPda = await PdaUtils.getAmmConfigPda(ammConfigIndex, this.programId);
|
|
8363
8661
|
const poolPda = await PdaUtils.getPoolStatePda(
|
|
8364
8662
|
ammConfigPda[0],
|
|
8365
8663
|
tokenA,
|
|
8366
|
-
tokenB
|
|
8664
|
+
tokenB,
|
|
8665
|
+
this.programId
|
|
8367
8666
|
);
|
|
8368
8667
|
return this.getPool(poolPda[0]);
|
|
8369
8668
|
}
|
|
8370
8669
|
async getAllPools(rpc) {
|
|
8371
8670
|
try {
|
|
8372
|
-
let accounts = await rpc.getProgramAccounts(
|
|
8671
|
+
let accounts = await rpc.getProgramAccounts(this.programId, {
|
|
8373
8672
|
commitment: "finalized",
|
|
8374
8673
|
encoding: "base64",
|
|
8375
8674
|
filters: [
|
|
@@ -8422,7 +8721,7 @@ var PoolManager = class {
|
|
|
8422
8721
|
getToken(this.config.rpc, poolState.tokenVault1)
|
|
8423
8722
|
]);
|
|
8424
8723
|
const currentPrice = this.calculatePoolPrice(
|
|
8425
|
-
new
|
|
8724
|
+
new BN6(poolState.sqrtPriceX64.toString()),
|
|
8426
8725
|
tokenA.decimals,
|
|
8427
8726
|
tokenB.decimals
|
|
8428
8727
|
);
|
|
@@ -8479,7 +8778,7 @@ import {
|
|
|
8479
8778
|
getTransferCheckedInstruction
|
|
8480
8779
|
} from "@solana-program/token";
|
|
8481
8780
|
import { TOKEN_2022_PROGRAM_ADDRESS as TOKEN_2022_PROGRAM_ADDRESS2 } from "@solana-program/token-2022";
|
|
8482
|
-
import
|
|
8781
|
+
import BN7 from "bn.js";
|
|
8483
8782
|
|
|
8484
8783
|
// ../node_modules/@solana/spl-token/lib/esm/constants.js
|
|
8485
8784
|
import { PublicKey } from "@solana/web3.js";
|
|
@@ -8499,7 +8798,9 @@ var TOKEN_ACCOUNT_SIZE = 165n;
|
|
|
8499
8798
|
var PositionManager = class {
|
|
8500
8799
|
constructor(config) {
|
|
8501
8800
|
this.config = config;
|
|
8801
|
+
this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
|
|
8502
8802
|
}
|
|
8803
|
+
programId;
|
|
8503
8804
|
buildWrapSolInstructions(params) {
|
|
8504
8805
|
const { payer, ata, owner, amount } = params;
|
|
8505
8806
|
return [
|
|
@@ -8601,7 +8902,8 @@ var PositionManager = class {
|
|
|
8601
8902
|
poolAccount.data.tickSpacing
|
|
8602
8903
|
);
|
|
8603
8904
|
const [positionStatePda] = await PdaUtils.getPositionStatePda(
|
|
8604
|
-
nftMintAccount.address
|
|
8905
|
+
nftMintAccount.address,
|
|
8906
|
+
this.programId
|
|
8605
8907
|
);
|
|
8606
8908
|
const [metadataPda] = await getMetadataPda(nftMintAccount.address);
|
|
8607
8909
|
const [positionNftAccountPda] = await findAssociatedTokenPda({
|
|
@@ -8612,7 +8914,8 @@ var PositionManager = class {
|
|
|
8612
8914
|
const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
|
|
8613
8915
|
poolAccount.address,
|
|
8614
8916
|
tickLower,
|
|
8615
|
-
tickUpper
|
|
8917
|
+
tickUpper,
|
|
8918
|
+
this.programId
|
|
8616
8919
|
);
|
|
8617
8920
|
const instruction = await getOpenPositionWithToken22NftInstructionAsync({
|
|
8618
8921
|
payer: ownerInfo.feePayer,
|
|
@@ -8687,14 +8990,17 @@ var PositionManager = class {
|
|
|
8687
8990
|
);
|
|
8688
8991
|
const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
|
|
8689
8992
|
poolAccount.address,
|
|
8690
|
-
tickArrayLowerStartIndex
|
|
8993
|
+
tickArrayLowerStartIndex,
|
|
8994
|
+
this.programId
|
|
8691
8995
|
);
|
|
8692
8996
|
const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
|
|
8693
8997
|
poolAccount.address,
|
|
8694
|
-
tickArrayUpperStartIndex
|
|
8998
|
+
tickArrayUpperStartIndex,
|
|
8999
|
+
this.programId
|
|
8695
9000
|
);
|
|
8696
9001
|
const [positionStatePda] = await PdaUtils.getPositionStatePda(
|
|
8697
|
-
nftMintAccount.address
|
|
9002
|
+
nftMintAccount.address,
|
|
9003
|
+
this.programId
|
|
8698
9004
|
);
|
|
8699
9005
|
const [metadataPda] = await getMetadataPda(nftMintAccount.address);
|
|
8700
9006
|
const [positionNftAccountPda] = await findAssociatedTokenPda({
|
|
@@ -8705,7 +9011,8 @@ var PositionManager = class {
|
|
|
8705
9011
|
const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
|
|
8706
9012
|
poolAccount.address,
|
|
8707
9013
|
tickLower,
|
|
8708
|
-
tickUpper
|
|
9014
|
+
tickUpper,
|
|
9015
|
+
this.programId
|
|
8709
9016
|
);
|
|
8710
9017
|
const amount0Max = base === "MintA" ? baseAmount : otherAmountMax;
|
|
8711
9018
|
const amount1Max = base === "MintA" ? otherAmountMax : baseAmount;
|
|
@@ -8713,7 +9020,7 @@ var PositionManager = class {
|
|
|
8713
9020
|
poolAccount.data.tickSpacing,
|
|
8714
9021
|
[tickArrayLowerStartIndex, tickArrayUpperStartIndex]
|
|
8715
9022
|
);
|
|
8716
|
-
const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolAccount.address) : void 0;
|
|
9023
|
+
const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolAccount.address, this.programId) : void 0;
|
|
8717
9024
|
const remAccounts = extBitmapAccount ? [{ address: extBitmapAccount[0], role: AccountRole2.WRITABLE }] : [];
|
|
8718
9025
|
let wrapSolInstructions = [];
|
|
8719
9026
|
if (poolAccount.data.tokenMint0.toString() === NATIVE_MINT.toString()) {
|
|
@@ -8789,7 +9096,8 @@ var PositionManager = class {
|
|
|
8789
9096
|
amountMaxB
|
|
8790
9097
|
} = params;
|
|
8791
9098
|
const [personalPosition] = await PdaUtils.getPositionStatePda(
|
|
8792
|
-
ownerPosition.nftMint
|
|
9099
|
+
ownerPosition.nftMint,
|
|
9100
|
+
this.programId
|
|
8793
9101
|
);
|
|
8794
9102
|
const [positionNftAccount] = await findAssociatedTokenPda({
|
|
8795
9103
|
mint: ownerPosition.nftMint,
|
|
@@ -8799,27 +9107,30 @@ var PositionManager = class {
|
|
|
8799
9107
|
const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
|
|
8800
9108
|
poolState.address,
|
|
8801
9109
|
ownerPosition.tickLowerIndex,
|
|
8802
|
-
ownerPosition.tickUpperIndex
|
|
9110
|
+
ownerPosition.tickUpperIndex,
|
|
9111
|
+
this.programId
|
|
8803
9112
|
);
|
|
8804
9113
|
const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
|
|
8805
9114
|
poolState.address,
|
|
8806
9115
|
PdaUtils.getTickArrayStartIndex(
|
|
8807
9116
|
ownerPosition.tickLowerIndex,
|
|
8808
9117
|
poolState.data.tickSpacing
|
|
8809
|
-
)
|
|
9118
|
+
),
|
|
9119
|
+
this.programId
|
|
8810
9120
|
);
|
|
8811
9121
|
const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
|
|
8812
9122
|
poolState.address,
|
|
8813
9123
|
PdaUtils.getTickArrayStartIndex(
|
|
8814
9124
|
ownerPosition.tickUpperIndex,
|
|
8815
9125
|
poolState.data.tickSpacing
|
|
8816
|
-
)
|
|
9126
|
+
),
|
|
9127
|
+
this.programId
|
|
8817
9128
|
);
|
|
8818
9129
|
const isOverflow = PoolUtils.isOverflowDefaultTickArrayBitmap(
|
|
8819
9130
|
poolState.data.tickSpacing,
|
|
8820
9131
|
[ownerPosition.tickLowerIndex, ownerPosition.tickUpperIndex]
|
|
8821
9132
|
);
|
|
8822
|
-
const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address) : void 0;
|
|
9133
|
+
const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address, this.programId) : void 0;
|
|
8823
9134
|
const remAccounts = extBitmapAccount ? [{ address: extBitmapAccount[0], role: AccountRole2.WRITABLE }] : [];
|
|
8824
9135
|
const instruction = getIncreaseLiquidityV2Instruction({
|
|
8825
9136
|
nftOwner: ownerInfo.wallet,
|
|
@@ -8877,7 +9188,8 @@ var PositionManager = class {
|
|
|
8877
9188
|
} = params;
|
|
8878
9189
|
const signers = [];
|
|
8879
9190
|
const [personalPosition] = await PdaUtils.getPositionStatePda(
|
|
8880
|
-
ownerPosition.nftMint
|
|
9191
|
+
ownerPosition.nftMint,
|
|
9192
|
+
this.programId
|
|
8881
9193
|
);
|
|
8882
9194
|
const [positionNftAccount] = await findAssociatedTokenPda({
|
|
8883
9195
|
mint: ownerPosition.nftMint,
|
|
@@ -8887,27 +9199,30 @@ var PositionManager = class {
|
|
|
8887
9199
|
const [protocolPositionPda] = await PdaUtils.getProtocolPositionStatePda(
|
|
8888
9200
|
poolState.address,
|
|
8889
9201
|
ownerPosition.tickLowerIndex,
|
|
8890
|
-
ownerPosition.tickUpperIndex
|
|
9202
|
+
ownerPosition.tickUpperIndex,
|
|
9203
|
+
this.programId
|
|
8891
9204
|
);
|
|
8892
9205
|
const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
|
|
8893
9206
|
poolState.address,
|
|
8894
9207
|
PdaUtils.getTickArrayStartIndex(
|
|
8895
9208
|
ownerPosition.tickLowerIndex,
|
|
8896
9209
|
poolState.data.tickSpacing
|
|
8897
|
-
)
|
|
9210
|
+
),
|
|
9211
|
+
this.programId
|
|
8898
9212
|
);
|
|
8899
9213
|
const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
|
|
8900
9214
|
poolState.address,
|
|
8901
9215
|
PdaUtils.getTickArrayStartIndex(
|
|
8902
9216
|
ownerPosition.tickUpperIndex,
|
|
8903
9217
|
poolState.data.tickSpacing
|
|
8904
|
-
)
|
|
9218
|
+
),
|
|
9219
|
+
this.programId
|
|
8905
9220
|
);
|
|
8906
9221
|
const isOverflow = PoolUtils.isOverflowDefaultTickArrayBitmap(
|
|
8907
9222
|
poolState.data.tickSpacing,
|
|
8908
9223
|
[ownerPosition.tickLowerIndex, ownerPosition.tickUpperIndex]
|
|
8909
9224
|
);
|
|
8910
|
-
const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address) : void 0;
|
|
9225
|
+
const extBitmapAccount = isOverflow ? await PdaUtils.getTickArrayBitmapExtensionPda(poolState.address, this.programId) : void 0;
|
|
8911
9226
|
const remAccounts = extBitmapAccount ? [{ address: extBitmapAccount[0], role: AccountRole2.WRITABLE }] : [];
|
|
8912
9227
|
const createRecipientAta0Ix = getCreateAssociatedTokenIdempotentInstruction(
|
|
8913
9228
|
{
|
|
@@ -8990,7 +9305,8 @@ var PositionManager = class {
|
|
|
8990
9305
|
async makeClosePositionInstructions(params) {
|
|
8991
9306
|
const { ownerPosition, ownerInfo } = params;
|
|
8992
9307
|
const [personalPosition] = await PdaUtils.getPositionStatePda(
|
|
8993
|
-
ownerPosition.nftMint
|
|
9308
|
+
ownerPosition.nftMint,
|
|
9309
|
+
this.programId
|
|
8994
9310
|
);
|
|
8995
9311
|
const [positionNftAccount] = await findAssociatedTokenPda({
|
|
8996
9312
|
mint: ownerPosition.nftMint,
|
|
@@ -9019,7 +9335,7 @@ var PositionManager = class {
|
|
|
9019
9335
|
*/
|
|
9020
9336
|
async getPosition(positionMint) {
|
|
9021
9337
|
try {
|
|
9022
|
-
const positionStatePda = await PdaUtils.getPositionStatePda(positionMint);
|
|
9338
|
+
const positionStatePda = await PdaUtils.getPositionStatePda(positionMint, this.programId);
|
|
9023
9339
|
const positionState = await fetchMaybePersonalPositionState(
|
|
9024
9340
|
this.config.rpc,
|
|
9025
9341
|
positionStatePda[0],
|
|
@@ -9040,21 +9356,22 @@ var PositionManager = class {
|
|
|
9040
9356
|
* Enrich position state with computed fields from pool data
|
|
9041
9357
|
* @param position - Raw position state from blockchain
|
|
9042
9358
|
* @param pool - Pool state from blockchain
|
|
9359
|
+
* @param fees - Position fees
|
|
9043
9360
|
* @returns Enriched position info with calculated amounts and prices
|
|
9044
9361
|
*/
|
|
9045
|
-
enrichPositionInfo(position, pool) {
|
|
9362
|
+
enrichPositionInfo(position, pool, fees, rewards) {
|
|
9046
9363
|
const sqrtPriceLowerX64 = SqrtPriceMath.getSqrtPriceX64FromTick(
|
|
9047
9364
|
position.tickLowerIndex
|
|
9048
9365
|
);
|
|
9049
9366
|
const sqrtPriceUpperX64 = SqrtPriceMath.getSqrtPriceX64FromTick(
|
|
9050
9367
|
position.tickUpperIndex
|
|
9051
9368
|
);
|
|
9052
|
-
const sqrtPriceCurrentX64 = new
|
|
9369
|
+
const sqrtPriceCurrentX64 = new BN7(pool.sqrtPriceX64.toString());
|
|
9053
9370
|
const { amountA, amountB } = LiquidityMath.getAmountsFromLiquidity(
|
|
9054
9371
|
sqrtPriceCurrentX64,
|
|
9055
9372
|
sqrtPriceLowerX64,
|
|
9056
9373
|
sqrtPriceUpperX64,
|
|
9057
|
-
new
|
|
9374
|
+
new BN7(position.liquidity.toString()),
|
|
9058
9375
|
true
|
|
9059
9376
|
);
|
|
9060
9377
|
const [_amountA, _amountB] = [
|
|
@@ -9075,9 +9392,13 @@ var PositionManager = class {
|
|
|
9075
9392
|
});
|
|
9076
9393
|
const inRange = pool.tickCurrent >= position.tickLowerIndex && pool.tickCurrent < position.tickUpperIndex;
|
|
9077
9394
|
const unclaimedFees = {
|
|
9078
|
-
token0: new
|
|
9079
|
-
token1: new
|
|
9395
|
+
token0: fees?.tokenFees0 ? fees?.tokenFees0 : new BN7(0),
|
|
9396
|
+
token1: fees?.tokenFees1 ? fees?.tokenFees1 : new BN7(0)
|
|
9080
9397
|
};
|
|
9398
|
+
const unclaimedRewards = rewards?.rewards ? rewards.rewards.map((amount, i) => ({
|
|
9399
|
+
mint: pool.rewardInfos[i]?.tokenMint,
|
|
9400
|
+
amount
|
|
9401
|
+
})).filter((r) => r.mint !== void 0) : void 0;
|
|
9081
9402
|
const ageSeconds = 0;
|
|
9082
9403
|
return {
|
|
9083
9404
|
...position,
|
|
@@ -9090,18 +9411,16 @@ var PositionManager = class {
|
|
|
9090
9411
|
inRange,
|
|
9091
9412
|
ageSeconds,
|
|
9092
9413
|
unclaimedFees,
|
|
9093
|
-
|
|
9094
|
-
valueUsd: void 0
|
|
9095
|
-
// unclaimedRewards is optional
|
|
9096
|
-
unclaimedRewards: void 0
|
|
9414
|
+
unclaimedRewards,
|
|
9415
|
+
valueUsd: void 0
|
|
9097
9416
|
};
|
|
9098
9417
|
}
|
|
9099
9418
|
/**
|
|
9100
|
-
* Get
|
|
9419
|
+
* Get raw positions for a wallet (without pool-state enrichment)
|
|
9101
9420
|
* @param wallet - Wallet address
|
|
9102
|
-
* @returns Array of
|
|
9421
|
+
* @returns Array of raw position states owned by the wallet
|
|
9103
9422
|
*/
|
|
9104
|
-
async
|
|
9423
|
+
async getRawPositionsForWallet(wallet) {
|
|
9105
9424
|
try {
|
|
9106
9425
|
const response22 = await this.config.rpc.getTokenAccountsByOwner(
|
|
9107
9426
|
wallet,
|
|
@@ -9118,29 +9437,7 @@ var PositionManager = class {
|
|
|
9118
9437
|
(ta) => this.getPosition(ta.account.data.parsed.info.mint)
|
|
9119
9438
|
)
|
|
9120
9439
|
);
|
|
9121
|
-
|
|
9122
|
-
(p) => !!p
|
|
9123
|
-
);
|
|
9124
|
-
const enrichedPositions = await Promise.all(
|
|
9125
|
-
validPositions.map(async (position) => {
|
|
9126
|
-
try {
|
|
9127
|
-
const poolAccount = await fetchMaybePoolState(
|
|
9128
|
-
this.config.rpc,
|
|
9129
|
-
position.poolId,
|
|
9130
|
-
{ commitment: this.config.commitment }
|
|
9131
|
-
);
|
|
9132
|
-
if (!poolAccount.exists) {
|
|
9133
|
-
console.warn(`Pool ${position.poolId} not found for position`);
|
|
9134
|
-
return null;
|
|
9135
|
-
}
|
|
9136
|
-
return this.enrichPositionInfo(position, poolAccount.data);
|
|
9137
|
-
} catch (error) {
|
|
9138
|
-
console.error(`Failed to enrich position: ${error}`);
|
|
9139
|
-
return null;
|
|
9140
|
-
}
|
|
9141
|
-
})
|
|
9142
|
-
);
|
|
9143
|
-
return enrichedPositions.filter((p) => !!p);
|
|
9440
|
+
return positions.filter((p) => !!p);
|
|
9144
9441
|
} catch (error) {
|
|
9145
9442
|
throw new ClmmError(
|
|
9146
9443
|
"POSITION_NOT_FOUND" /* POSITION_NOT_FOUND */,
|
|
@@ -9148,6 +9445,146 @@ var PositionManager = class {
|
|
|
9148
9445
|
);
|
|
9149
9446
|
}
|
|
9150
9447
|
}
|
|
9448
|
+
/**
|
|
9449
|
+
* Get all positions for a wallet, enriched with pool data
|
|
9450
|
+
* @param wallet - Wallet address
|
|
9451
|
+
* @returns Structured result with enriched positions and any failures
|
|
9452
|
+
*/
|
|
9453
|
+
async getPositionsForWallet(wallet) {
|
|
9454
|
+
const rawPositions = await this.getRawPositionsForWallet(wallet);
|
|
9455
|
+
const results = await Promise.allSettled(
|
|
9456
|
+
rawPositions.map(async (position) => {
|
|
9457
|
+
const poolAccount = await fetchMaybePoolState(
|
|
9458
|
+
this.config.rpc,
|
|
9459
|
+
position.poolId,
|
|
9460
|
+
{ commitment: this.config.commitment }
|
|
9461
|
+
);
|
|
9462
|
+
if (!poolAccount.exists) {
|
|
9463
|
+
throw new Error(`Pool ${position.poolId} not found for position`);
|
|
9464
|
+
}
|
|
9465
|
+
const { fees, rewards } = await this.getPositionFeeAndRewards(
|
|
9466
|
+
position,
|
|
9467
|
+
poolAccount.data
|
|
9468
|
+
);
|
|
9469
|
+
return this.enrichPositionInfo(
|
|
9470
|
+
position,
|
|
9471
|
+
poolAccount.data,
|
|
9472
|
+
fees,
|
|
9473
|
+
rewards
|
|
9474
|
+
);
|
|
9475
|
+
})
|
|
9476
|
+
);
|
|
9477
|
+
const positions = [];
|
|
9478
|
+
const failed = [];
|
|
9479
|
+
results.forEach((result, index) => {
|
|
9480
|
+
if (result.status === "fulfilled") {
|
|
9481
|
+
positions.push(result.value);
|
|
9482
|
+
} else {
|
|
9483
|
+
failed.push({
|
|
9484
|
+
position: rawPositions[index],
|
|
9485
|
+
error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
|
|
9486
|
+
});
|
|
9487
|
+
}
|
|
9488
|
+
});
|
|
9489
|
+
return { positions, failed };
|
|
9490
|
+
}
|
|
9491
|
+
/**
|
|
9492
|
+
* Calculate pending fees and rewards for a position.
|
|
9493
|
+
*
|
|
9494
|
+
* @param position - Personal position state
|
|
9495
|
+
* @param pool - Pool state
|
|
9496
|
+
* @returns Pending fees for both tokens and rewards for each reward token (up to 3)
|
|
9497
|
+
*/
|
|
9498
|
+
async getPositionFeeAndRewards(position, pool) {
|
|
9499
|
+
const [tickArrayLower] = await PdaUtils.getTickArrayStatePda(
|
|
9500
|
+
position.poolId,
|
|
9501
|
+
PdaUtils.getTickArrayStartIndex(
|
|
9502
|
+
position.tickLowerIndex,
|
|
9503
|
+
pool.tickSpacing
|
|
9504
|
+
),
|
|
9505
|
+
this.programId
|
|
9506
|
+
);
|
|
9507
|
+
const [tickArrayUpper] = await PdaUtils.getTickArrayStatePda(
|
|
9508
|
+
position.poolId,
|
|
9509
|
+
PdaUtils.getTickArrayStartIndex(
|
|
9510
|
+
position.tickUpperIndex,
|
|
9511
|
+
pool.tickSpacing
|
|
9512
|
+
),
|
|
9513
|
+
this.programId
|
|
9514
|
+
);
|
|
9515
|
+
const tickArrayLowerAccount = await fetchMaybeTickArrayState(
|
|
9516
|
+
this.config.rpc,
|
|
9517
|
+
tickArrayLower
|
|
9518
|
+
);
|
|
9519
|
+
const tickArrayUpperAccount = await fetchMaybeTickArrayState(
|
|
9520
|
+
this.config.rpc,
|
|
9521
|
+
tickArrayUpper
|
|
9522
|
+
);
|
|
9523
|
+
if (!tickArrayLowerAccount.exists || !tickArrayUpperAccount.exists) {
|
|
9524
|
+
console.log(
|
|
9525
|
+
"[getPositionFeeAndRewards] tick array state accounts do not exist."
|
|
9526
|
+
);
|
|
9527
|
+
return {
|
|
9528
|
+
fees: { tokenFees0: new BN7(0), tokenFees1: new BN7(0) },
|
|
9529
|
+
rewards: { rewards: [new BN7(0), new BN7(0), new BN7(0)] }
|
|
9530
|
+
};
|
|
9531
|
+
}
|
|
9532
|
+
const tickSpacing = pool.tickSpacing;
|
|
9533
|
+
const tickArrayLowerIndex = TickUtils.getTickOffsetInArray(
|
|
9534
|
+
position.tickLowerIndex,
|
|
9535
|
+
tickSpacing
|
|
9536
|
+
);
|
|
9537
|
+
const tickArrayUpperIndex = TickUtils.getTickOffsetInArray(
|
|
9538
|
+
position.tickUpperIndex,
|
|
9539
|
+
tickSpacing
|
|
9540
|
+
);
|
|
9541
|
+
if (tickArrayLowerIndex < 0 || tickArrayUpperIndex < 0) {
|
|
9542
|
+
console.log("[getPositionFeeAndRewards] tick array indexes < 0.");
|
|
9543
|
+
return {
|
|
9544
|
+
fees: { tokenFees0: new BN7(0), tokenFees1: new BN7(0) },
|
|
9545
|
+
rewards: { rewards: [new BN7(0), new BN7(0), new BN7(0)] }
|
|
9546
|
+
};
|
|
9547
|
+
}
|
|
9548
|
+
const lowerTickState = tickArrayLowerAccount.data.ticks[tickArrayLowerIndex];
|
|
9549
|
+
const upperTickState = tickArrayUpperAccount.data.ticks[tickArrayUpperIndex];
|
|
9550
|
+
const fees = PositionUtils.getPositionFees({
|
|
9551
|
+
liquidity: position.liquidity,
|
|
9552
|
+
tickLower: position.tickLowerIndex,
|
|
9553
|
+
tickUpper: position.tickUpperIndex,
|
|
9554
|
+
feeGrowthInside0LastX64: position.feeGrowthInside0LastX64,
|
|
9555
|
+
feeGrowthInside1LastX64: position.feeGrowthInside1LastX64,
|
|
9556
|
+
tokenFeesOwed0: position.tokenFeesOwed0,
|
|
9557
|
+
tokenFeesOwed1: position.tokenFeesOwed1,
|
|
9558
|
+
tickCurrent: pool.tickCurrent,
|
|
9559
|
+
feeGrowthGlobal0X64: pool.feeGrowthGlobal0X64,
|
|
9560
|
+
feeGrowthGlobal1X64: pool.feeGrowthGlobal1X64,
|
|
9561
|
+
tickLowerState: {
|
|
9562
|
+
feeGrowthOutside0X64: lowerTickState.feeGrowthOutside0X64,
|
|
9563
|
+
feeGrowthOutside1X64: lowerTickState.feeGrowthOutside1X64
|
|
9564
|
+
},
|
|
9565
|
+
tickUpperState: {
|
|
9566
|
+
feeGrowthOutside0X64: upperTickState.feeGrowthOutside0X64,
|
|
9567
|
+
feeGrowthOutside1X64: upperTickState.feeGrowthOutside1X64
|
|
9568
|
+
}
|
|
9569
|
+
});
|
|
9570
|
+
const rewards = PositionUtils.getPositionRewards({
|
|
9571
|
+
liquidity: position.liquidity,
|
|
9572
|
+
tickLower: position.tickLowerIndex,
|
|
9573
|
+
tickUpper: position.tickUpperIndex,
|
|
9574
|
+
positionRewardInfos: position.rewardInfos,
|
|
9575
|
+
tickCurrent: pool.tickCurrent,
|
|
9576
|
+
rewardInfos: pool.rewardInfos,
|
|
9577
|
+
tickLowerState: {
|
|
9578
|
+
liquidityGross: lowerTickState.liquidityGross,
|
|
9579
|
+
rewardGrowthsOutsideX64: lowerTickState.rewardGrowthsOutsideX64
|
|
9580
|
+
},
|
|
9581
|
+
tickUpperState: {
|
|
9582
|
+
liquidityGross: upperTickState.liquidityGross,
|
|
9583
|
+
rewardGrowthsOutsideX64: upperTickState.rewardGrowthsOutsideX64
|
|
9584
|
+
}
|
|
9585
|
+
});
|
|
9586
|
+
return { fees, rewards };
|
|
9587
|
+
}
|
|
9151
9588
|
};
|
|
9152
9589
|
|
|
9153
9590
|
// src/api/config.ts
|
|
@@ -10122,7 +10559,7 @@ var PriceApiClient = class _PriceApiClient {
|
|
|
10122
10559
|
};
|
|
10123
10560
|
|
|
10124
10561
|
// src/swap.ts
|
|
10125
|
-
import
|
|
10562
|
+
import BN8 from "bn.js";
|
|
10126
10563
|
import Decimal6 from "decimal.js";
|
|
10127
10564
|
var DEFAULT_RETRY_CONFIG = {
|
|
10128
10565
|
maxRetries: 3,
|
|
@@ -10182,7 +10619,7 @@ var SwapMathEngine = class {
|
|
|
10182
10619
|
slippageTolerance,
|
|
10183
10620
|
poolAddress
|
|
10184
10621
|
} = params;
|
|
10185
|
-
if (amountIn.lte(new
|
|
10622
|
+
if (amountIn.lte(new BN8(0))) {
|
|
10186
10623
|
throw new ClmmError(
|
|
10187
10624
|
"SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
|
|
10188
10625
|
"Swap amount must be greater than zero"
|
|
@@ -10194,8 +10631,8 @@ var SwapMathEngine = class {
|
|
|
10194
10631
|
`Slippage tolerance must be between 0 and 1, got ${slippageTolerance}`
|
|
10195
10632
|
);
|
|
10196
10633
|
}
|
|
10197
|
-
const liquidity = new
|
|
10198
|
-
const sqrtPriceCurrentX64 = new
|
|
10634
|
+
const liquidity = new BN8(pool.liquidity.toString());
|
|
10635
|
+
const sqrtPriceCurrentX64 = new BN8(pool.sqrtPriceX64.toString());
|
|
10199
10636
|
const feeRate = ammConfig.tradeFeeRate;
|
|
10200
10637
|
const sqrtPriceTargetX64 = this.calculateSqrtPriceLimit(
|
|
10201
10638
|
sqrtPriceCurrentX64,
|
|
@@ -10223,9 +10660,9 @@ var SwapMathEngine = class {
|
|
|
10223
10660
|
pool.mintDecimals1
|
|
10224
10661
|
);
|
|
10225
10662
|
const priceImpact = priceAfter.minus(priceBefore).div(priceBefore).abs().toNumber();
|
|
10226
|
-
const slippageBN = new
|
|
10663
|
+
const slippageBN = new BN8(Math.floor(slippageTolerance * 1e4));
|
|
10227
10664
|
const minAmountOut = step.amountOut.sub(
|
|
10228
|
-
step.amountOut.mul(slippageBN).div(new
|
|
10665
|
+
step.amountOut.mul(slippageBN).div(new BN8(1e4))
|
|
10229
10666
|
);
|
|
10230
10667
|
return {
|
|
10231
10668
|
amountIn,
|
|
@@ -10272,17 +10709,17 @@ var SwapMathEngine = class {
|
|
|
10272
10709
|
tickArrayCache
|
|
10273
10710
|
} = params;
|
|
10274
10711
|
const sqrtPriceLimitX64 = this.calculateSqrtPriceLimit(
|
|
10275
|
-
new
|
|
10712
|
+
new BN8(pool.sqrtPriceX64.toString()),
|
|
10276
10713
|
zeroForOne,
|
|
10277
10714
|
slippageTolerance
|
|
10278
10715
|
);
|
|
10279
10716
|
const result = await SwapMath.swapCompute({
|
|
10280
10717
|
poolState: {
|
|
10281
|
-
sqrtPriceX64: new
|
|
10718
|
+
sqrtPriceX64: new BN8(pool.sqrtPriceX64.toString()),
|
|
10282
10719
|
tickCurrent: pool.tickCurrent,
|
|
10283
|
-
liquidity: new
|
|
10284
|
-
feeGrowthGlobal0X64: new
|
|
10285
|
-
feeGrowthGlobal1X64: new
|
|
10720
|
+
liquidity: new BN8(pool.liquidity.toString()),
|
|
10721
|
+
feeGrowthGlobal0X64: new BN8(pool.feeGrowthGlobal0X64.toString()),
|
|
10722
|
+
feeGrowthGlobal1X64: new BN8(pool.feeGrowthGlobal1X64.toString())
|
|
10286
10723
|
},
|
|
10287
10724
|
tickArrayCache,
|
|
10288
10725
|
tickSpacing: pool.tickSpacing,
|
|
@@ -10299,7 +10736,7 @@ var SwapMathEngine = class {
|
|
|
10299
10736
|
poolId: poolAddress
|
|
10300
10737
|
});
|
|
10301
10738
|
const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
|
|
10302
|
-
new
|
|
10739
|
+
new BN8(pool.sqrtPriceX64.toString()),
|
|
10303
10740
|
pool.mintDecimals0,
|
|
10304
10741
|
pool.mintDecimals1
|
|
10305
10742
|
);
|
|
@@ -10309,9 +10746,9 @@ var SwapMathEngine = class {
|
|
|
10309
10746
|
pool.mintDecimals1
|
|
10310
10747
|
);
|
|
10311
10748
|
const priceImpact = priceAfter.minus(priceBefore).div(priceBefore).abs().toNumber();
|
|
10312
|
-
const slippageBN = new
|
|
10749
|
+
const slippageBN = new BN8(Math.floor(slippageTolerance * 1e4));
|
|
10313
10750
|
const minAmountOut = result.amountOut.sub(
|
|
10314
|
-
result.amountOut.mul(slippageBN).div(new
|
|
10751
|
+
result.amountOut.mul(slippageBN).div(new BN8(1e4))
|
|
10315
10752
|
);
|
|
10316
10753
|
const feeImpact = ammConfig.tradeFeeRate / FEE_RATE_DENOMINATOR_NUMBER;
|
|
10317
10754
|
return {
|
|
@@ -10355,10 +10792,10 @@ var SwapMathEngine = class {
|
|
|
10355
10792
|
*/
|
|
10356
10793
|
calculateSqrtPriceLimit(sqrtPriceX64, zeroForOne, slippageTolerance) {
|
|
10357
10794
|
const bps = Math.floor(slippageTolerance * 1e4);
|
|
10358
|
-
const base = new
|
|
10359
|
-
const scaled = zeroForOne ? sqrtPriceX64.mul(base.sub(new
|
|
10360
|
-
const min2 = new
|
|
10361
|
-
const max = new
|
|
10795
|
+
const base = new BN8(1e4);
|
|
10796
|
+
const scaled = zeroForOne ? sqrtPriceX64.mul(base.sub(new BN8(bps))).div(base) : sqrtPriceX64.mul(base.add(new BN8(bps))).div(base);
|
|
10797
|
+
const min2 = new BN8(MIN_SQRT_PRICE_X64);
|
|
10798
|
+
const max = new BN8(MAX_SQRT_PRICE_X64);
|
|
10362
10799
|
if (scaled.lt(min2)) return min2;
|
|
10363
10800
|
if (scaled.gt(max)) return max;
|
|
10364
10801
|
return scaled;
|
|
@@ -10451,6 +10888,7 @@ var SwapManager = class {
|
|
|
10451
10888
|
constructor(config, managerConfig) {
|
|
10452
10889
|
this.config = config;
|
|
10453
10890
|
this.managerConfig = managerConfig;
|
|
10891
|
+
this.programId = config.programAddress ?? STABBLE_CLMM_PROGRAM_ID;
|
|
10454
10892
|
this.poolDataManager = new PoolDataManager(config, {
|
|
10455
10893
|
cacheTTL: 2e3,
|
|
10456
10894
|
immutability: "freeze",
|
|
@@ -10471,6 +10909,7 @@ var SwapManager = class {
|
|
|
10471
10909
|
);
|
|
10472
10910
|
}
|
|
10473
10911
|
}
|
|
10912
|
+
programId;
|
|
10474
10913
|
poolDataManager;
|
|
10475
10914
|
mathEngine;
|
|
10476
10915
|
priceApiClient;
|
|
@@ -10782,7 +11221,7 @@ var SwapManager = class {
|
|
|
10782
11221
|
`Invalid slippage tolerance: ${slippageTolerance}. Must be between 0 and 1.`
|
|
10783
11222
|
);
|
|
10784
11223
|
}
|
|
10785
|
-
if (amountIn.lte(new
|
|
11224
|
+
if (amountIn.lte(new BN8(0))) {
|
|
10786
11225
|
throw new ClmmError(
|
|
10787
11226
|
"SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
|
|
10788
11227
|
"Swap amount must be greater than zero."
|
|
@@ -10884,7 +11323,7 @@ var SwapManager = class {
|
|
|
10884
11323
|
`Invalid slippage tolerance: ${slippageTolerance}. Must be between 0 and 1.`
|
|
10885
11324
|
);
|
|
10886
11325
|
}
|
|
10887
|
-
if (amountIn.lte(new
|
|
11326
|
+
if (amountIn.lte(new BN8(0))) {
|
|
10888
11327
|
throw new ClmmError(
|
|
10889
11328
|
"SWAP_AMOUNT_CANNOT_BE_ZERO" /* SWAP_AMOUNT_CANNOT_BE_ZERO */,
|
|
10890
11329
|
"Swap amount must be greater than zero."
|
|
@@ -10938,7 +11377,7 @@ var SwapManager = class {
|
|
|
10938
11377
|
poolAddress
|
|
10939
11378
|
});
|
|
10940
11379
|
const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
|
|
10941
|
-
new
|
|
11380
|
+
new BN8(pool.sqrtPriceX64.toString()),
|
|
10942
11381
|
pool.mintDecimals0,
|
|
10943
11382
|
pool.mintDecimals1
|
|
10944
11383
|
);
|
|
@@ -11048,21 +11487,21 @@ var SwapManager = class {
|
|
|
11048
11487
|
* @returns Number of tick arrays to fetch (includes safety buffer)
|
|
11049
11488
|
*/
|
|
11050
11489
|
estimateTickArrayCount(pool, amountIn) {
|
|
11051
|
-
const liquidity = new
|
|
11052
|
-
if (liquidity.eq(new
|
|
11490
|
+
const liquidity = new BN8(pool.liquidity.toString());
|
|
11491
|
+
if (liquidity.eq(new BN8(0)) || liquidity.lt(new BN8(1e3))) {
|
|
11053
11492
|
return 10;
|
|
11054
11493
|
}
|
|
11055
|
-
const roughImpact = amountIn.mul(new
|
|
11494
|
+
const roughImpact = amountIn.mul(new BN8(1e3)).div(liquidity);
|
|
11056
11495
|
let baseArrays;
|
|
11057
|
-
if (roughImpact.lte(new
|
|
11496
|
+
if (roughImpact.lte(new BN8(1))) {
|
|
11058
11497
|
baseArrays = 2;
|
|
11059
|
-
} else if (roughImpact.lte(new
|
|
11498
|
+
} else if (roughImpact.lte(new BN8(10))) {
|
|
11060
11499
|
baseArrays = 4;
|
|
11061
|
-
} else if (roughImpact.lte(new
|
|
11500
|
+
} else if (roughImpact.lte(new BN8(50))) {
|
|
11062
11501
|
baseArrays = 6;
|
|
11063
|
-
} else if (roughImpact.lte(new
|
|
11502
|
+
} else if (roughImpact.lte(new BN8(100))) {
|
|
11064
11503
|
baseArrays = 8;
|
|
11065
|
-
} else if (roughImpact.lte(new
|
|
11504
|
+
} else if (roughImpact.lte(new BN8(200))) {
|
|
11066
11505
|
baseArrays = 12;
|
|
11067
11506
|
} else {
|
|
11068
11507
|
baseArrays = 15;
|
|
@@ -11081,7 +11520,8 @@ var SwapManager = class {
|
|
|
11081
11520
|
const startIndex = currentStartIndex + offset * TICKS_PER_ARRAY * tickSpacing;
|
|
11082
11521
|
const [tickArrayPda] = await PdaUtils.getTickArrayStatePda(
|
|
11083
11522
|
poolAddress,
|
|
11084
|
-
startIndex
|
|
11523
|
+
startIndex,
|
|
11524
|
+
this.programId
|
|
11085
11525
|
);
|
|
11086
11526
|
tickArrayAddresses.push(tickArrayPda);
|
|
11087
11527
|
}
|
|
@@ -11107,7 +11547,7 @@ var SwapManager = class {
|
|
|
11107
11547
|
const decOut = zeroForOne ? pool.mintDecimals1 : pool.mintDecimals0;
|
|
11108
11548
|
const promises = params.amounts.map(async (amountIn) => {
|
|
11109
11549
|
try {
|
|
11110
|
-
if (amountIn.lte(new
|
|
11550
|
+
if (amountIn.lte(new BN8(0))) return;
|
|
11111
11551
|
const quote = await this.mathEngine.calculateSimpleSwap({
|
|
11112
11552
|
pool,
|
|
11113
11553
|
ammConfig,
|
|
@@ -11149,7 +11589,7 @@ var SwapManager = class {
|
|
|
11149
11589
|
options
|
|
11150
11590
|
);
|
|
11151
11591
|
const priceBefore = SqrtPriceMath.sqrtPriceX64ToPrice(
|
|
11152
|
-
new
|
|
11592
|
+
new BN8(pool.sqrtPriceX64.toString()),
|
|
11153
11593
|
pool.mintDecimals0,
|
|
11154
11594
|
pool.mintDecimals1
|
|
11155
11595
|
);
|
|
@@ -11272,13 +11712,13 @@ var SwapManager = class {
|
|
|
11272
11712
|
`Extremely high price impact: ${(quote.priceImpact * 100).toFixed(2)}%. Swap likely to fail or result in significant slippage.`
|
|
11273
11713
|
);
|
|
11274
11714
|
}
|
|
11275
|
-
const oneUnit = new
|
|
11715
|
+
const oneUnit = new BN8(10).pow(new BN8(outputDecimals));
|
|
11276
11716
|
if (quote.amountOut.lt(oneUnit)) {
|
|
11277
11717
|
warnings.push(
|
|
11278
11718
|
`Output amount is less than 1 unit of the output token. Consider increasing input amount or slippage tolerance.`
|
|
11279
11719
|
);
|
|
11280
11720
|
}
|
|
11281
|
-
if (quote.amountOut.lte(new
|
|
11721
|
+
if (quote.amountOut.lte(new BN8(0))) {
|
|
11282
11722
|
errors.push(
|
|
11283
11723
|
"Swap would result in zero output. Amount may be too small."
|
|
11284
11724
|
);
|
|
@@ -11299,11 +11739,11 @@ var SwapManager = class {
|
|
|
11299
11739
|
return {
|
|
11300
11740
|
quote: {
|
|
11301
11741
|
amountIn: params.amountIn,
|
|
11302
|
-
amountOut: new
|
|
11303
|
-
minAmountOut: new
|
|
11742
|
+
amountOut: new BN8(0),
|
|
11743
|
+
minAmountOut: new BN8(0),
|
|
11304
11744
|
priceImpact: 0,
|
|
11305
11745
|
route: [],
|
|
11306
|
-
fee: new
|
|
11746
|
+
fee: new BN8(0)
|
|
11307
11747
|
},
|
|
11308
11748
|
willSucceed: false,
|
|
11309
11749
|
errors,
|
|
@@ -11391,7 +11831,7 @@ var SwapManager = class {
|
|
|
11391
11831
|
}
|
|
11392
11832
|
const pool = await this.poolDataManager.getPoolState(poolAddress, options);
|
|
11393
11833
|
const zeroForOne = params.tokenIn === pool.tokenMint0;
|
|
11394
|
-
const [observationState] = await PdaUtils.getObservationStatePda(poolAddress);
|
|
11834
|
+
const [observationState] = await PdaUtils.getObservationStatePda(poolAddress, this.programId);
|
|
11395
11835
|
const [inputTokenAccount] = await findAssociatedTokenPda2({
|
|
11396
11836
|
mint: params.tokenIn,
|
|
11397
11837
|
owner: payer.address,
|
|
@@ -11403,7 +11843,7 @@ var SwapManager = class {
|
|
|
11403
11843
|
tokenProgram: TOKEN_PROGRAM_ADDRESS4
|
|
11404
11844
|
});
|
|
11405
11845
|
const sqrtPriceLimitX64 = params.sqrtPriceLimitX64 || this.mathEngine.calculateSqrtPriceLimit(
|
|
11406
|
-
new
|
|
11846
|
+
new BN8(pool.sqrtPriceX64.toString()),
|
|
11407
11847
|
zeroForOne,
|
|
11408
11848
|
params.slippageTolerance || DEFAULT_SLIPPAGE_TOLERANCE
|
|
11409
11849
|
);
|
|
@@ -11428,7 +11868,7 @@ var SwapManager = class {
|
|
|
11428
11868
|
async getCurrentPrice(poolAddress, options) {
|
|
11429
11869
|
const pool = await this.poolDataManager.getPoolState(poolAddress, options);
|
|
11430
11870
|
return SqrtPriceMath.sqrtPriceX64ToPrice(
|
|
11431
|
-
new
|
|
11871
|
+
new BN8(pool.sqrtPriceX64.toString()),
|
|
11432
11872
|
pool.mintDecimals0,
|
|
11433
11873
|
pool.mintDecimals1
|
|
11434
11874
|
);
|
|
@@ -11640,11 +12080,13 @@ export {
|
|
|
11640
12080
|
PoolManager,
|
|
11641
12081
|
PoolUtils,
|
|
11642
12082
|
PositionManager,
|
|
12083
|
+
PositionUtils,
|
|
11643
12084
|
PriceApiClient,
|
|
11644
12085
|
Q128,
|
|
11645
12086
|
Q64,
|
|
11646
12087
|
SLIPPAGE_CALC,
|
|
11647
12088
|
STABBLE_CLMM_PROGRAM_ID,
|
|
12089
|
+
STABBLE_CLMM_QAS_PROGRAM_ID,
|
|
11648
12090
|
SYSTEM_PROGRAM_ID,
|
|
11649
12091
|
SYSVAR_RENT_PROGRAM_ID,
|
|
11650
12092
|
SqrtPriceMath,
|