@kamino-finance/kliquidity-sdk 8.3.0 → 8.3.2

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.
Files changed (77) hide show
  1. package/dist/Kamino.d.ts +12 -12
  2. package/dist/Kamino.d.ts.map +1 -1
  3. package/dist/Kamino.js +103 -122
  4. package/dist/Kamino.js.map +1 -1
  5. package/dist/constants/numericalValues.d.ts +3 -0
  6. package/dist/constants/numericalValues.d.ts.map +1 -1
  7. package/dist/constants/numericalValues.js +4 -1
  8. package/dist/constants/numericalValues.js.map +1 -1
  9. package/dist/rebalance_methods/autodriftRebalance.d.ts.map +1 -1
  10. package/dist/rebalance_methods/autodriftRebalance.js +10 -10
  11. package/dist/rebalance_methods/autodriftRebalance.js.map +1 -1
  12. package/dist/rebalance_methods/driftRebalance.d.ts.map +1 -1
  13. package/dist/rebalance_methods/driftRebalance.js +10 -10
  14. package/dist/rebalance_methods/driftRebalance.js.map +1 -1
  15. package/dist/rebalance_methods/expanderRebalance.d.ts.map +1 -1
  16. package/dist/rebalance_methods/expanderRebalance.js +3 -4
  17. package/dist/rebalance_methods/expanderRebalance.js.map +1 -1
  18. package/dist/rebalance_methods/pricePercentageRebalance.d.ts.map +1 -1
  19. package/dist/rebalance_methods/pricePercentageRebalance.js +5 -6
  20. package/dist/rebalance_methods/pricePercentageRebalance.js.map +1 -1
  21. package/dist/rebalance_methods/pricePercentageWithResetRebalance.d.ts.map +1 -1
  22. package/dist/rebalance_methods/pricePercentageWithResetRebalance.js +5 -6
  23. package/dist/rebalance_methods/pricePercentageWithResetRebalance.js.map +1 -1
  24. package/dist/rebalance_methods/takeProfitRebalance.d.ts.map +1 -1
  25. package/dist/rebalance_methods/takeProfitRebalance.js +5 -5
  26. package/dist/rebalance_methods/takeProfitRebalance.js.map +1 -1
  27. package/dist/services/OrcaService.d.ts +7 -11
  28. package/dist/services/OrcaService.d.ts.map +1 -1
  29. package/dist/services/OrcaService.js +132 -100
  30. package/dist/services/OrcaService.js.map +1 -1
  31. package/dist/services/OrcaWhirlpoolsResponse.d.ts +63 -92
  32. package/dist/services/OrcaWhirlpoolsResponse.d.ts.map +1 -1
  33. package/dist/utils/farms.d.ts +1 -0
  34. package/dist/utils/farms.d.ts.map +1 -0
  35. package/dist/utils/farms.js +2 -0
  36. package/dist/utils/farms.js.map +1 -0
  37. package/dist/utils/index.d.ts +1 -0
  38. package/dist/utils/index.d.ts.map +1 -1
  39. package/dist/utils/index.js +1 -0
  40. package/dist/utils/index.js.map +1 -1
  41. package/dist/utils/orca.d.ts +37 -1
  42. package/dist/utils/orca.d.ts.map +1 -1
  43. package/dist/utils/orca.js +242 -0
  44. package/dist/utils/orca.js.map +1 -1
  45. package/dist/utils/tokenUtils.d.ts +5 -5
  46. package/dist/utils/tokenUtils.d.ts.map +1 -1
  47. package/dist/utils/tokenUtils.js +11 -7
  48. package/dist/utils/tokenUtils.js.map +1 -1
  49. package/dist/utils/types.d.ts +5 -0
  50. package/dist/utils/types.d.ts.map +1 -1
  51. package/dist/utils/types.js.map +1 -1
  52. package/dist/utils/utils.d.ts +0 -1
  53. package/dist/utils/utils.d.ts.map +1 -1
  54. package/dist/utils/utils.js +3 -4
  55. package/dist/utils/utils.js.map +1 -1
  56. package/dist/utils/whirlpools.d.ts +12 -1
  57. package/dist/utils/whirlpools.d.ts.map +1 -1
  58. package/dist/utils/whirlpools.js +30 -29
  59. package/dist/utils/whirlpools.js.map +1 -1
  60. package/package.json +4 -3
  61. package/src/Kamino.ts +256 -209
  62. package/src/constants/numericalValues.ts +5 -0
  63. package/src/rebalance_methods/autodriftRebalance.ts +30 -22
  64. package/src/rebalance_methods/driftRebalance.ts +30 -22
  65. package/src/rebalance_methods/expanderRebalance.ts +7 -4
  66. package/src/rebalance_methods/pricePercentageRebalance.ts +13 -6
  67. package/src/rebalance_methods/pricePercentageWithResetRebalance.ts +13 -6
  68. package/src/rebalance_methods/takeProfitRebalance.ts +13 -5
  69. package/src/services/OrcaService.ts +162 -125
  70. package/src/services/OrcaWhirlpoolsResponse.ts +69 -101
  71. package/src/utils/farms.ts +0 -0
  72. package/src/utils/index.ts +1 -0
  73. package/src/utils/orca.ts +377 -1
  74. package/src/utils/tokenUtils.ts +5 -5
  75. package/src/utils/types.ts +7 -0
  76. package/src/utils/utils.ts +2 -4
  77. package/src/utils/whirlpools.ts +50 -31
package/dist/Kamino.js CHANGED
@@ -11,9 +11,7 @@ const accounts_1 = require("./@codegen/kliquidity/accounts");
11
11
  const decimal_js_1 = __importDefault(require("decimal.js"));
12
12
  const instructions_1 = require("./@codegen/whirlpools/instructions");
13
13
  const accounts_2 = require("./@codegen/whirlpools/accounts");
14
- const whirlpool_sdk_1 = require("@orca-so/whirlpool-sdk");
15
- const orca_dal_1 = require("@orca-so/whirlpool-sdk/dist/dal/orca-dal");
16
- const orca_position_1 = require("@orca-so/whirlpool-sdk/dist/position/orca-position");
14
+ const whirlpools_core_1 = require("@orca-so/whirlpools-core");
17
15
  const models_1 = require("./models");
18
16
  const scope_sdk_1 = require("@kamino-finance/scope-sdk");
19
17
  const utils_1 = require("./utils");
@@ -24,7 +22,6 @@ const constants_1 = require("./constants");
24
22
  const types_1 = require("./@codegen/kliquidity/types");
25
23
  const accounts_3 = require("./@codegen/raydium/accounts");
26
24
  const services_1 = require("./services");
27
- const add_liquidity_1 = require("@orca-so/whirlpool-sdk/dist/position/quotes/add-liquidity");
28
25
  const StrategyConfigOption_1 = require("./@codegen/kliquidity/types/StrategyConfigOption");
29
26
  const DefaultStrategyConfig_1 = require("./constants/DefaultStrategyConfig");
30
27
  const pubkeys_1 = require("./constants/pubkeys");
@@ -92,7 +89,7 @@ class Kamino {
92
89
  this._globalConfig = globalConfig ? globalConfig : (0, compat_1.fromLegacyPublicKey)(this._config.kamino.globalConfig);
93
90
  }
94
91
  this._scope = new scope_sdk_1.Scope(cluster, rpc);
95
- this._orcaService = new services_1.OrcaService(rpc, legacyConnection, cluster, whirlpoolProgramId);
92
+ this._orcaService = new services_1.OrcaService(rpc, legacyConnection, whirlpoolProgramId);
96
93
  this._raydiumService = new services_1.RaydiumService(rpc, legacyConnection, raydiumProgramId);
97
94
  this._meteoraService = new MeteoraService_1.MeteoraService(rpc, meteoraProgramId);
98
95
  if (jupBaseAPI) {
@@ -100,6 +97,7 @@ class Kamino {
100
97
  }
101
98
  }
102
99
  getConnection = () => this._rpc;
100
+ getLegacyConnection = () => this._legacyConnection;
103
101
  getProgramID = () => this._kliquidityProgramId;
104
102
  setGlobalConfig = (globalConfig) => {
105
103
  this._globalConfig = globalConfig;
@@ -435,7 +433,7 @@ class Kamino {
435
433
  if (pools.length === 0) {
436
434
  throw new Error(`No pool found for ${poolTokenA.toString()} and ${poolTokenB.toString()}`);
437
435
  }
438
- return pools[0].price;
436
+ return Number(pools[0].price);
439
437
  }
440
438
  else if (dex === 'RAYDIUM') {
441
439
  const pools = await this.getRaydiumPoolsForTokens(poolTokenA, poolTokenB);
@@ -490,7 +488,7 @@ class Kamino {
490
488
  let pool = pubkeys_1.DEFAULT_PUBLIC_KEY;
491
489
  const orcaPools = await this.getOrcaPoolsForTokens(poolTokenA, poolTokenB);
492
490
  orcaPools.forEach((element) => {
493
- if (element.lpFeeRate * CreationParameters_1.FullBPS === feeBPS.toNumber()) {
491
+ if (element.feeRate * CreationParameters_1.FullBPS === feeBPS.toNumber()) {
494
492
  pool = (0, kit_1.address)(element.address);
495
493
  }
496
494
  });
@@ -541,19 +539,19 @@ class Kamino {
541
539
  const genericPoolInfos = await Promise.all(pools.map(async (pool) => {
542
540
  const positionsCount = new decimal_js_1.default(await this.getPositionsCountForPool(dex, (0, kit_1.address)(pool.address)));
543
541
  // read price from pool
544
- const poolData = await this._orcaService.getPool((0, kit_1.address)(pool.address));
542
+ const poolData = await this._orcaService.getOrcaWhirlpool((0, kit_1.address)(pool.address));
545
543
  if (!poolData) {
546
544
  throw new Error(`Pool ${pool.address} not found`);
547
545
  }
548
546
  const poolInfo = {
549
547
  dex,
550
548
  address: (0, kit_1.address)(pool.address),
551
- price: (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(poolData.sqrtPrice, pool.tokenA.decimals, pool.tokenB.decimals),
552
- tokenMintA: (0, kit_1.address)(pool.tokenA.mint),
553
- tokenMintB: (0, kit_1.address)(pool.tokenB.mint),
554
- tvl: pool.tvl ? new decimal_js_1.default(pool.tvl) : undefined,
555
- feeRate: new decimal_js_1.default(pool.lpFeeRate).mul(CreationParameters_1.FullBPS),
556
- volumeOnLast7d: pool.volume ? new decimal_js_1.default(pool.volume.week) : undefined,
549
+ price: new decimal_js_1.default((0, whirlpools_core_1.sqrtPriceToPrice)(BigInt(poolData.sqrtPrice), pool.tokenA.decimals, pool.tokenB.decimals)),
550
+ tokenMintA: (0, kit_1.address)(pool.tokenMintA),
551
+ tokenMintB: (0, kit_1.address)(pool.tokenMintB),
552
+ tvl: pool.tvlUsdc ? new decimal_js_1.default(pool.tvlUsdc) : undefined,
553
+ feeRate: new decimal_js_1.default(pool.feeRate).mul(CreationParameters_1.FullBPS),
554
+ volumeOnLast7d: pool.stats['7d'] ? new decimal_js_1.default(pool.stats['7d'].volume) : undefined,
557
555
  tickSpacing: new decimal_js_1.default(pool.tickSpacing),
558
556
  positions: positionsCount,
559
557
  };
@@ -613,9 +611,9 @@ class Kamino {
613
611
  const poolTokenAString = poolTokenA.toString();
614
612
  const poolTokenBString = poolTokenB.toString();
615
613
  const whirlpools = await this._orcaService.getOrcaWhirlpools();
616
- whirlpools.whirlpools.forEach((element) => {
617
- if ((element.tokenA.mint === poolTokenAString && element.tokenB.mint === poolTokenBString) ||
618
- (element.tokenA.mint === poolTokenBString && element.tokenB.mint === poolTokenAString))
614
+ whirlpools.forEach((element) => {
615
+ if ((element.tokenMintA === poolTokenAString && element.tokenMintB === poolTokenBString) ||
616
+ (element.tokenMintA === poolTokenBString && element.tokenMintB === poolTokenAString))
619
617
  pools.push(element);
620
618
  });
621
619
  return pools;
@@ -1034,12 +1032,12 @@ class Kamino {
1034
1032
  const computedHoldings = this.getStrategyHoldingsUsd(tokenHoldings.available.a, tokenHoldings.available.b, tokenHoldings.invested.a, tokenHoldings.invested.b, new decimal_js_1.default(strategy.tokenAMintDecimals.toString()), new decimal_js_1.default(strategy.tokenBMintDecimals.toString()), strategyPrices.aPrice, strategyPrices.bPrice);
1035
1033
  const decimalsA = strategy.tokenAMintDecimals.toNumber();
1036
1034
  const decimalsB = strategy.tokenBMintDecimals.toNumber();
1037
- const poolPrice = (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(pool.sqrtPrice, decimalsA, decimalsB);
1035
+ const poolPrice = new decimal_js_1.default((0, whirlpools_core_1.sqrtPriceToPrice)(BigInt(pool.sqrtPrice.toString()), decimalsA, decimalsB));
1038
1036
  const twapPrice = strategyPrices.aTwapPrice !== null && strategyPrices.bTwapPrice !== null
1039
1037
  ? strategyPrices.aTwapPrice.div(strategyPrices.bTwapPrice)
1040
1038
  : null;
1041
- const upperPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(position.tickUpperIndex, decimalsA, decimalsB);
1042
- const lowerPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(position.tickLowerIndex, decimalsA, decimalsB);
1039
+ const upperPrice = new decimal_js_1.default((0, whirlpools_core_1.tickIndexToPrice)(position.tickUpperIndex, decimalsA, decimalsB));
1040
+ const lowerPrice = new decimal_js_1.default((0, whirlpools_core_1.tickIndexToPrice)(position.tickLowerIndex, decimalsA, decimalsB));
1043
1041
  let lowerResetPrice = null;
1044
1042
  let upperResetPrice = null;
1045
1043
  const dex = (0, utils_1.numberToDex)(strategy.strategyDex.toNumber());
@@ -1063,7 +1061,7 @@ class Kamino {
1063
1061
  const quote = (0, whirlpools_1.getRemoveLiquidityQuote)({
1064
1062
  positionAddress: strategy.position,
1065
1063
  liquidity: position.liquidity,
1066
- slippageTolerance: whirlpool_sdk_1.Percentage.fromFraction(0, 1000),
1064
+ slippageTolerance: { numerator: constants_1.ZERO_BN, denominator: new bn_js_1.default(1000) },
1067
1065
  sqrtPrice: pool.sqrtPrice,
1068
1066
  tickLowerIndex: position.tickLowerIndex,
1069
1067
  tickUpperIndex: position.tickUpperIndex,
@@ -1526,8 +1524,8 @@ class Kamino {
1526
1524
  if (!position) {
1527
1525
  return { lowerPrice: utils_1.ZERO, upperPrice: utils_1.ZERO };
1528
1526
  }
1529
- const lowerPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(position.tickLowerIndex, decimalsA, decimalsB);
1530
- const upperPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(position.tickUpperIndex, decimalsA, decimalsB);
1527
+ const lowerPrice = new decimal_js_1.default((0, whirlpools_core_1.tickIndexToPrice)(position.tickLowerIndex, decimalsA, decimalsB));
1528
+ const upperPrice = new decimal_js_1.default((0, whirlpools_core_1.tickIndexToPrice)(position.tickUpperIndex, decimalsA, decimalsB));
1531
1529
  const positionRange = { lowerPrice, upperPrice };
1532
1530
  return positionRange;
1533
1531
  };
@@ -1539,8 +1537,8 @@ class Kamino {
1539
1537
  if (!position) {
1540
1538
  return { lowerPrice: utils_1.ZERO, upperPrice: utils_1.ZERO };
1541
1539
  }
1542
- const lowerPrice = (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(position.tickLowerIndex), decimalsA, decimalsB);
1543
- const upperPrice = (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(position.tickUpperIndex), decimalsA, decimalsB);
1540
+ const lowerPrice = lib_1.SqrtPriceMath.sqrtPriceX64ToPrice(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(position.tickLowerIndex), decimalsA, decimalsB);
1541
+ const upperPrice = lib_1.SqrtPriceMath.sqrtPriceX64ToPrice(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(position.tickUpperIndex), decimalsA, decimalsB);
1544
1542
  const positionRange = { lowerPrice, upperPrice };
1545
1543
  return positionRange;
1546
1544
  };
@@ -1603,6 +1601,9 @@ class Kamino {
1603
1601
  }, {});
1604
1602
  return whirlpoolMap;
1605
1603
  };
1604
+ getAllWhirlpoolsFromAPI = async (tokens = []) => {
1605
+ return (await this._orcaService.getOrcaWhirlpools(tokens));
1606
+ };
1606
1607
  /**
1607
1608
  * Get a list of Orca positions from public keys
1608
1609
  * @param positions
@@ -1912,7 +1913,7 @@ class Kamino {
1912
1913
  };
1913
1914
  getWhirlpoolStateIfNotFetched = async (whirlpool) => {
1914
1915
  const hasWhirlpoolBeenFetched = (object) => {
1915
- return 'whirlpool' in object;
1916
+ return typeof object !== 'string' && 'whirlpool' in object;
1916
1917
  };
1917
1918
  if (hasWhirlpoolBeenFetched(whirlpool)) {
1918
1919
  return whirlpool;
@@ -1927,7 +1928,7 @@ class Kamino {
1927
1928
  };
1928
1929
  getMeteoraStateIfNotFetched = async (lbPair) => {
1929
1930
  const hasLbPairBeenFetched = (object) => {
1930
- return 'lbPair' in object;
1931
+ return typeof object !== 'string' && 'pool' in object;
1931
1932
  };
1932
1933
  if (hasLbPairBeenFetched(lbPair)) {
1933
1934
  return lbPair;
@@ -2941,8 +2942,8 @@ class Kamino {
2941
2942
  };
2942
2943
  };
2943
2944
  getStartEndTicketIndexProgramAddressesOrca = async (whirlpool, whirlpoolState, tickLowerIndex, tickUpperIndex) => {
2944
- const startTickIndex = (0, whirlpool_sdk_1.getStartTickIndex)(tickLowerIndex, whirlpoolState.tickSpacing, 0);
2945
- const endTickIndex = (0, whirlpool_sdk_1.getStartTickIndex)(tickUpperIndex, whirlpoolState.tickSpacing, 0);
2945
+ const startTickIndex = (0, whirlpools_core_1.getTickArrayStartTickIndex)(tickLowerIndex, whirlpoolState.tickSpacing);
2946
+ const endTickIndex = (0, whirlpools_core_1.getTickArrayStartTickIndex)(tickUpperIndex, whirlpoolState.tickSpacing);
2946
2947
  const [lowerTickPubkey, lowerTickBump] = await (0, kit_1.getProgramDerivedAddress)({
2947
2948
  seeds: [Buffer.from('tick_array'), addressEncoder.encode(whirlpool), Buffer.from(startTickIndex.toString())],
2948
2949
  programAddress: this._orcaService.getWhirlpoolProgramId(),
@@ -3090,8 +3091,8 @@ class Kamino {
3090
3091
  const isRebalancing = status.discriminator === StrategyStatus_1.Rebalancing.discriminator;
3091
3092
  const decimalsA = await (0, utils_1.getMintDecimals)(this._rpc, whirlpool.tokenMintA);
3092
3093
  const decimalsB = await (0, utils_1.getMintDecimals)(this._rpc, whirlpool.tokenMintB);
3093
- const tickLowerIndex = (0, whirlpool_sdk_1.getNextValidTickIndex)((0, whirlpool_sdk_1.priceToTickIndex)(priceLower, decimalsA, decimalsB), whirlpool.tickSpacing);
3094
- const tickUpperIndex = (0, whirlpool_sdk_1.getNextValidTickIndex)((0, whirlpool_sdk_1.priceToTickIndex)(priceUpper, decimalsA, decimalsB), whirlpool.tickSpacing);
3094
+ const tickLowerIndex = (0, whirlpools_core_1.getTickArrayStartTickIndex)((0, whirlpools_core_1.priceToTickIndex)(priceLower.toNumber(), decimalsA, decimalsB), whirlpool.tickSpacing);
3095
+ const tickUpperIndex = (0, whirlpools_core_1.getTickArrayStartTickIndex)((0, whirlpools_core_1.priceToTickIndex)(priceUpper.toNumber(), decimalsA, decimalsB), whirlpool.tickSpacing);
3095
3096
  const { position, positionBump, positionMetadata } = await this.getMetadataProgramAddressesOrca(positionMint.address);
3096
3097
  const positionTokenAccount = await (0, utils_1.getAssociatedTokenAddress)(positionMint.address, baseVaultAuthority);
3097
3098
  const args = {
@@ -3610,7 +3611,7 @@ class Kamino {
3610
3611
  if (dex === 'ORCA') {
3611
3612
  const { whirlpool: whilrpoolState } = await this.getWhirlpoolStateIfNotFetched(pool);
3612
3613
  if (rebalanceTypeKind.kind === types_1.RebalanceType.Drift.kind) {
3613
- processedRebalanceParams[0] = new decimal_js_1.default((0, whirlpool_sdk_1.getNearestValidTickIndexFromTickIndex)(rebalanceParams[0].toNumber(), whilrpoolState.tickSpacing));
3614
+ processedRebalanceParams[0] = new decimal_js_1.default((0, utils_1.getNearestValidTickIndexFromTickIndex)(rebalanceParams[0].toNumber(), whilrpoolState.tickSpacing));
3614
3615
  }
3615
3616
  }
3616
3617
  return processedRebalanceParams;
@@ -3805,7 +3806,7 @@ class Kamino {
3805
3806
  case types_1.RebalanceType.Expander.kind:
3806
3807
  return (0, rebalance_methods_1.getPositionRangeFromExpanderParams)(price, rebalanceParams[0], rebalanceParams[1]);
3807
3808
  case types_1.RebalanceType.Autodrift.kind:
3808
- const currentTickIndex = (0, whirlpool_sdk_1.priceToTickIndex)(price, tokenADecimals, tokenBDecimals);
3809
+ const currentTickIndex = (0, whirlpools_core_1.priceToTickIndex)(price.toNumber(), tokenADecimals, tokenBDecimals);
3809
3810
  const startMidTick = new decimal_js_1.default(currentTickIndex);
3810
3811
  return (0, autodriftRebalance_1.getPositionRangeFromAutodriftParams)(dex, tokenADecimals, tokenBDecimals, startMidTick, rebalanceParams[1], rebalanceParams[2], tickSpacing);
3811
3812
  default:
@@ -3816,11 +3817,11 @@ class Kamino {
3816
3817
  const strategyWithAddress = await this.getStrategyStateIfNotFetched(strategy);
3817
3818
  const pool = strategyWithAddress.strategy.pool;
3818
3819
  const dex = (0, utils_1.numberToDex)(strategyWithAddress.strategy.strategyDex.toNumber());
3819
- return this.getCurrentPriceFromPool(dex, pool);
3820
+ return this.getCurrentPriceFromPool(dex, pool, strategyWithAddress.strategy.tokenAMintDecimals.toNumber(), strategyWithAddress.strategy.tokenBMintDecimals.toNumber());
3820
3821
  }
3821
- async getCurrentPriceFromPool(dex, pool) {
3822
+ async getCurrentPriceFromPool(dex, pool, tokenADecimals, tokenBDecimals) {
3822
3823
  if (dex === 'ORCA') {
3823
- return this.getOrcaPoolPrice(pool);
3824
+ return this.getOrcaPoolPrice(pool, tokenADecimals, tokenBDecimals);
3824
3825
  }
3825
3826
  else if (dex === 'RAYDIUM') {
3826
3827
  return this.getRaydiumPoolPrice(pool);
@@ -4116,9 +4117,9 @@ class Kamino {
4116
4117
  /**
4117
4118
  * Read the pool price for a specific dex and pool
4118
4119
  */
4119
- async getPoolPrice(dex, pool) {
4120
+ async getPoolPrice(dex, pool, tokenADecimals, tokenBDecimals) {
4120
4121
  if (dex === 'ORCA') {
4121
- return this.getOrcaPoolPrice(pool);
4122
+ return this.getOrcaPoolPrice(pool, tokenADecimals, tokenBDecimals);
4122
4123
  }
4123
4124
  else if (dex === 'RAYDIUM') {
4124
4125
  return this.getRaydiumPoolPrice(pool);
@@ -4130,12 +4131,22 @@ class Kamino {
4130
4131
  throw new Error(`Invalid dex ${dex}`);
4131
4132
  }
4132
4133
  }
4133
- async getOrcaPoolPrice(pool) {
4134
- const poolData = await this._orcaService.getPool(pool);
4135
- if (!poolData) {
4136
- throw Error(`Could not fetch Whirlpool data for ${pool.toString()}`);
4134
+ async getOrcaPoolPrice(pool, tokenADecimals, tokenBDecimals) {
4135
+ // if the decimals are provided read from API, otherwise use RPC
4136
+ if (tokenADecimals && tokenBDecimals) {
4137
+ const whirlpool = await accounts_2.Whirlpool.fetch(this._rpc, pool, this._orcaService.getWhirlpoolProgramId());
4138
+ if (!whirlpool) {
4139
+ throw Error(`Could not fetch Whirlpool data for ${pool.toString()}`);
4140
+ }
4141
+ return new decimal_js_1.default((0, whirlpools_core_1.sqrtPriceToPrice)(BigInt(whirlpool.sqrtPrice.toString()), tokenADecimals, tokenBDecimals));
4142
+ }
4143
+ else {
4144
+ const whirlpool = await this._orcaService.getOrcaWhirlpool(pool);
4145
+ if (!whirlpool) {
4146
+ throw Error(`Could not fetch Whirlpool data for ${pool.toString()}`);
4147
+ }
4148
+ return new decimal_js_1.default((0, whirlpools_core_1.sqrtPriceToPrice)(BigInt(whirlpool.sqrtPrice.toString()), whirlpool.tokenA.decimals, whirlpool.tokenB.decimals));
4137
4149
  }
4138
- return poolData.price;
4139
4150
  }
4140
4151
  async getRaydiumPoolPrice(pool) {
4141
4152
  const poolState = await accounts_3.PoolState.fetch(this._rpc, pool, this._raydiumService.getRaydiumProgramId());
@@ -4483,7 +4494,7 @@ class Kamino {
4483
4494
  if (isOrca) {
4484
4495
  const prices = await this.getAllPrices();
4485
4496
  const collateralInfos = await this.getCollateralInfos();
4486
- return this._orcaService.getStrategyWhirlpoolPoolAprApy(strategyState, collateralInfos, prices, orcaPools);
4497
+ return this._orcaService.getStrategyWhirlpoolPoolAprApy(strategyState, collateralInfos, prices);
4487
4498
  }
4488
4499
  if (isRaydium) {
4489
4500
  return this._raydiumService.getStrategyWhirlpoolPoolAprApy(strategyState, raydiumPools);
@@ -4658,23 +4669,15 @@ class Kamino {
4658
4669
  const tokenMintB = whirlpoolState.tokenMintB;
4659
4670
  const decimalsA = await (0, utils_1.getMintDecimals)(this._rpc, tokenMintA);
4660
4671
  const decimalsB = await (0, utils_1.getMintDecimals)(this._rpc, tokenMintB);
4661
- const tickLowerIndex = (0, whirlpool_sdk_1.getNearestValidTickIndexFromTickIndex)((0, whirlpool_sdk_1.priceToTickIndex)(lowerPrice, decimalsA, decimalsB), whirlpoolState.tickSpacing);
4662
- const tickUpperIndex = (0, whirlpool_sdk_1.getNearestValidTickIndexFromTickIndex)((0, whirlpool_sdk_1.priceToTickIndex)(upperPrice, decimalsA, decimalsB), whirlpoolState.tickSpacing);
4663
- const params = {
4664
- tokenMintA: (0, compat_2.toLegacyPublicKey)(tokenMintA),
4665
- tokenMintB: (0, compat_2.toLegacyPublicKey)(tokenMintB),
4666
- tickCurrentIndex: whirlpoolState.tickCurrentIndex,
4667
- sqrtPrice: whirlpoolState.sqrtPrice,
4668
- inputTokenMint: (0, compat_2.toLegacyPublicKey)(tokenMintA),
4669
- inputTokenAmount: new bn_js_1.default((0, utils_1.collToLamportsDecimal)(tokenAAmountToDeposit, decimalsA).toString()),
4670
- tickLowerIndex,
4671
- tickUpperIndex,
4672
- slippageTolerance: whirlpool_sdk_1.defaultSlippagePercentage,
4672
+ const tickLowerIndex = (0, utils_1.getNearestValidTickIndexFromTickIndex)((0, whirlpools_core_1.priceToTickIndex)(lowerPrice.toNumber(), decimalsA, decimalsB), whirlpoolState.tickSpacing);
4673
+ const tickUpperIndex = (0, utils_1.getNearestValidTickIndexFromTickIndex)((0, whirlpools_core_1.priceToTickIndex)(upperPrice.toNumber(), decimalsA, decimalsB), whirlpoolState.tickSpacing);
4674
+ const param = {
4675
+ tokenA: BigInt((0, utils_1.collToLamportsDecimal)(tokenAAmountToDeposit, decimalsA).toString()),
4673
4676
  };
4674
- const addLiqResult = (0, add_liquidity_1.getAddLiquidityQuote)(params);
4677
+ const addLiqResult = (0, utils_1.getIncreaseLiquidityQuote)(param, whirlpoolState, tickLowerIndex, tickUpperIndex, utils_1.defaultSlippagePercentageBPS, undefined, undefined);
4675
4678
  return [
4676
- (0, utils_1.lamportsToNumberDecimal)(addLiqResult.estTokenA.toNumber(), decimalsA),
4677
- (0, utils_1.lamportsToNumberDecimal)(addLiqResult.estTokenB.toNumber(), decimalsB),
4679
+ (0, utils_1.lamportsToNumberDecimal)(new decimal_js_1.default(addLiqResult.tokenEstA.toString()), decimalsA),
4680
+ (0, utils_1.lamportsToNumberDecimal)(new decimal_js_1.default(addLiqResult.tokenEstB.toString()), decimalsB),
4678
4681
  ];
4679
4682
  }
4680
4683
  else if (dex === 'METEORA') {
@@ -4771,9 +4774,7 @@ class Kamino {
4771
4774
  throw new Error(`Unable to get Orca whirlpool for pubkey ${strategyState.pool}`);
4772
4775
  }
4773
4776
  return this.calculateAmountsOrca({
4774
- whirlpoolConfig: whirlpool.whirlpoolsConfig,
4775
- tokenAMint: strategyState.tokenAMint,
4776
- tokenBMint: strategyState.tokenBMint,
4777
+ whirlpoolState: whirlpool,
4777
4778
  positionAddress: strategyState.position,
4778
4779
  tokenAAmount,
4779
4780
  tokenBAmount,
@@ -4789,46 +4790,42 @@ class Kamino {
4789
4790
  throw new Error(`The strategy ${strategy.toString()} is not Orca or Raydium`);
4790
4791
  }
4791
4792
  };
4792
- calculateAmountsOrca = async ({ whirlpoolConfig, tokenAMint, tokenBMint, positionAddress, tokenAAmount, tokenBAmount, }) => {
4793
+ calculateAmountsOrca = async ({ whirlpoolState, positionAddress, tokenAAmount, tokenBAmount, }) => {
4793
4794
  if (!tokenAAmount && !tokenBAmount) {
4794
4795
  return [new decimal_js_1.default(0), new decimal_js_1.default(0)];
4795
4796
  }
4796
4797
  // Given A in ATA, calc how much A and B
4797
- const accessor = new orca_dal_1.OrcaDAL(whirlpoolConfig, this._orcaService.getWhirlpoolProgramId(), this._legacyConnection);
4798
- const orcaPosition = new orca_position_1.OrcaPosition(accessor);
4799
- const defaultSlippagePercentage = whirlpool_sdk_1.Percentage.fromFraction(1, 1000); // 0.1%
4800
- const primaryTokenAmount = tokenAAmount || tokenBAmount;
4801
- const primaryTokenMint = tokenAAmount ? tokenAMint : tokenBMint;
4802
- const secondaryTokenAmount = tokenAAmount ? tokenBAmount : tokenAAmount;
4803
- const secondaryTokenMint = tokenAAmount ? tokenBMint : tokenAMint;
4804
- let params = {
4805
- positionAddress,
4806
- tokenMint: primaryTokenMint,
4807
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
4808
- tokenAmount: new bn_js_1.default(primaryTokenAmount.toString()), // safe to use ! here because we check in the beginning that at least one of the amounts are not undefined;
4809
- refresh: true,
4810
- slippageTolerance: defaultSlippagePercentage,
4811
- };
4812
- const estimatedGivenPrimary = await orcaPosition.getAddLiquidityQuote(params);
4813
- if (secondaryTokenAmount &&
4814
- new decimal_js_1.default(estimatedGivenPrimary.estTokenB.toString()) > new decimal_js_1.default(secondaryTokenAmount.toString())) {
4815
- params = {
4816
- positionAddress,
4817
- tokenMint: secondaryTokenMint,
4818
- tokenAmount: new bn_js_1.default(secondaryTokenAmount.toString()),
4819
- refresh: true,
4820
- slippageTolerance: defaultSlippagePercentage,
4798
+ const defaultSlippagePercentageBPS = 10;
4799
+ const positionState = await accounts_2.Position.fetch(this._rpc, positionAddress, this._orcaService.getWhirlpoolProgramId());
4800
+ if (!positionState) {
4801
+ throw new Error(`Unable to get Orca position for pubkey ${positionAddress}`);
4802
+ }
4803
+ let computedAmounts = [new decimal_js_1.default(0), new decimal_js_1.default(0)];
4804
+ if (tokenAAmount) {
4805
+ const tokenAForQuote = BigInt(tokenAAmount.toString());
4806
+ const params = {
4807
+ tokenA: tokenAForQuote,
4821
4808
  };
4822
- const estimatedGivenSecondary = await orcaPosition.getAddLiquidityQuote(params);
4823
- return [
4824
- new decimal_js_1.default(estimatedGivenSecondary.estTokenA.toString()),
4825
- new decimal_js_1.default(estimatedGivenSecondary.estTokenB.toString()),
4809
+ const estimatedGivenA = (0, utils_1.getIncreaseLiquidityQuote)(params, whirlpoolState, positionState.tickLowerIndex, positionState.tickUpperIndex, defaultSlippagePercentageBPS, undefined, // todo: use new Wirlpool state and read transfer fees
4810
+ undefined);
4811
+ computedAmounts = [
4812
+ new decimal_js_1.default(estimatedGivenA.tokenEstA.toString()),
4813
+ new decimal_js_1.default(estimatedGivenA.tokenEstB.toString()),
4826
4814
  ];
4827
4815
  }
4828
- return [
4829
- new decimal_js_1.default(estimatedGivenPrimary.estTokenA.toString()),
4830
- new decimal_js_1.default(estimatedGivenPrimary.estTokenB.toString()),
4831
- ];
4816
+ if (tokenBAmount && computedAmounts[1] > tokenBAmount) {
4817
+ const tokenBForQuote = BigInt(tokenBAmount.toString());
4818
+ const params = {
4819
+ tokenB: tokenBForQuote,
4820
+ };
4821
+ const estimatedGivenB = (0, utils_1.getIncreaseLiquidityQuote)(params, whirlpoolState, positionState.tickLowerIndex, positionState.tickUpperIndex, defaultSlippagePercentageBPS, undefined, // todo: use new Wirlpool state and read transfer fees
4822
+ undefined);
4823
+ computedAmounts = [
4824
+ new decimal_js_1.default(estimatedGivenB.tokenEstA.toString()),
4825
+ new decimal_js_1.default(estimatedGivenB.tokenEstB.toString()),
4826
+ ];
4827
+ }
4828
+ return computedAmounts;
4832
4829
  };
4833
4830
  calculateAmountsRaydium = async ({ strategyState, tokenAAmount, tokenBAmount, }) => {
4834
4831
  if (!tokenAAmount && !tokenBAmount) {
@@ -5008,18 +5005,10 @@ class Kamino {
5008
5005
  throw new Error(`Whirlpool position ${strategyState.position} does not exist`);
5009
5006
  }
5010
5007
  const params = {
5011
- tokenMintA: (0, compat_2.toLegacyPublicKey)(strategyState.tokenAMint),
5012
- tokenMintB: (0, compat_2.toLegacyPublicKey)(strategyState.tokenBMint),
5013
- tickCurrentIndex: whirlpool.tickCurrentIndex,
5014
- sqrtPrice: whirlpool.sqrtPrice,
5015
- inputTokenMint: (0, compat_2.toLegacyPublicKey)(strategyState.tokenAMint),
5016
- inputTokenAmount: amountA,
5017
- tickLowerIndex: position.tickLowerIndex,
5018
- tickUpperIndex: position.tickUpperIndex,
5019
- slippageTolerance: whirlpool_sdk_1.defaultSlippagePercentage,
5008
+ tokenA: BigInt(amountA.toString()),
5020
5009
  };
5021
- const quote = (0, add_liquidity_1.getAddLiquidityQuote)(params);
5022
- return { amountSlippageA: quote.estTokenA, amountSlippageB: quote.estTokenB };
5010
+ const quote = (0, utils_1.getIncreaseLiquidityQuote)(params, whirlpool, position.tickLowerIndex, position.tickUpperIndex, utils_1.defaultSlippagePercentageBPS, undefined, undefined);
5011
+ return { amountSlippageA: new bn_js_1.default(quote.tokenEstA.toString()), amountSlippageB: new bn_js_1.default(quote.tokenEstB.toString()) };
5023
5012
  }
5024
5013
  async getDepositRatioFromAMeteora(strategy) {
5025
5014
  const { strategy: strategyState } = await this.getStrategyStateIfNotFetched(strategy);
@@ -5029,7 +5018,7 @@ class Kamino {
5029
5018
  if (!poolState) {
5030
5019
  throw Error(`Could not fetch lb pair state with pubkey ${strategyState.pool.toString()}`);
5031
5020
  }
5032
- return { amountSlippageA: utils_1.ZERO_BN, amountSlippageB: utils_1.ZERO_BN };
5021
+ return { amountSlippageA: constants_1.ZERO_BN, amountSlippageB: constants_1.ZERO_BN };
5033
5022
  }
5034
5023
  async getDepositRatioFromBMeteora(strategy) {
5035
5024
  const { strategy: strategyState } = await this.getStrategyStateIfNotFetched(strategy);
@@ -5040,7 +5029,7 @@ class Kamino {
5040
5029
  if (!poolState) {
5041
5030
  throw Error(`Could not fetch lb pair state with pubkey ${strategyState.pool.toString()}`);
5042
5031
  }
5043
- return { amountSlippageA: utils_1.ZERO_BN, amountSlippageB: utils_1.ZERO_BN };
5032
+ return { amountSlippageA: constants_1.ZERO_BN, amountSlippageB: constants_1.ZERO_BN };
5044
5033
  }
5045
5034
  getDepositRatioFromBOrca = async (strategy, amountB) => {
5046
5035
  const { strategy: strategyState } = await this.getStrategyStateIfNotFetched(strategy);
@@ -5052,19 +5041,11 @@ class Kamino {
5052
5041
  if (!position) {
5053
5042
  throw new Error(`Whirlpool position ${strategyState.position} does not exist`);
5054
5043
  }
5055
- const params = {
5056
- tokenMintA: (0, compat_2.toLegacyPublicKey)(strategyState.tokenAMint),
5057
- tokenMintB: (0, compat_2.toLegacyPublicKey)(strategyState.tokenBMint),
5058
- tickCurrentIndex: whirlpool.tickCurrentIndex,
5059
- sqrtPrice: whirlpool.sqrtPrice,
5060
- inputTokenMint: (0, compat_2.toLegacyPublicKey)(strategyState.tokenBMint),
5061
- inputTokenAmount: amountB,
5062
- tickLowerIndex: position.tickLowerIndex,
5063
- tickUpperIndex: position.tickUpperIndex,
5064
- slippageTolerance: whirlpool_sdk_1.defaultSlippagePercentage,
5044
+ const param = {
5045
+ tokenB: BigInt(amountB.toString()),
5065
5046
  };
5066
- const quote = (0, add_liquidity_1.getAddLiquidityQuote)(params);
5067
- return { amountSlippageA: quote.estTokenA, amountSlippageB: quote.estTokenB };
5047
+ const quote = (0, utils_1.getIncreaseLiquidityQuote)(param, whirlpool, position.tickLowerIndex, position.tickUpperIndex, utils_1.defaultSlippagePercentageBPS, undefined, undefined);
5048
+ return { amountSlippageA: new bn_js_1.default(quote.tokenEstA.toString()), amountSlippageB: new bn_js_1.default(quote.tokenEstB.toString()) };
5068
5049
  };
5069
5050
  getDepositRatioFromARaydium = async (strategy, amountA) => {
5070
5051
  const { strategy: strategyState } = await this.getStrategyStateIfNotFetched(strategy);
@@ -5278,8 +5259,8 @@ class Kamino {
5278
5259
  const { address: poolAddress, whirlpool: whilrpoolState } = await this.getWhirlpoolStateIfNotFetched(pool);
5279
5260
  const decimalsA = await (0, utils_1.getMintDecimals)(this._rpc, whilrpoolState.tokenMintA);
5280
5261
  const decimalsB = await (0, utils_1.getMintDecimals)(this._rpc, whilrpoolState.tokenMintB);
5281
- const tickIndex = (0, whirlpool_sdk_1.getNextValidTickIndex)((0, whirlpool_sdk_1.priceToTickIndex)(price, decimalsA, decimalsB), whilrpoolState.tickSpacing);
5282
- const startTickIndex = (0, whirlpool_sdk_1.getStartTickIndex)(tickIndex, whilrpoolState.tickSpacing);
5262
+ const tickIndex = (0, whirlpools_core_1.getTickArrayStartTickIndex)((0, whirlpools_core_1.priceToTickIndex)(price.toNumber(), decimalsA, decimalsB), whilrpoolState.tickSpacing);
5263
+ const startTickIndex = (0, whirlpools_core_1.getTickArrayStartTickIndex)(tickIndex, whilrpoolState.tickSpacing);
5283
5264
  const [startTickIndexPk, _startTickIndexBump] = await (0, utils_1.getTickArray)(this._orcaService.getWhirlpoolProgramId(), poolAddress, startTickIndex);
5284
5265
  const tick = await accounts_2.TickArray.fetch(this._rpc, startTickIndexPk, this._orcaService.getWhirlpoolProgramId());
5285
5266
  // initialize tick if it doesn't exist