@kamino-finance/kliquidity-sdk 8.3.1 → 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.
- package/dist/Kamino.d.ts +12 -12
- package/dist/Kamino.d.ts.map +1 -1
- package/dist/Kamino.js +101 -120
- package/dist/Kamino.js.map +1 -1
- package/dist/constants/numericalValues.d.ts +3 -0
- package/dist/constants/numericalValues.d.ts.map +1 -1
- package/dist/constants/numericalValues.js +4 -1
- package/dist/constants/numericalValues.js.map +1 -1
- package/dist/rebalance_methods/autodriftRebalance.d.ts.map +1 -1
- package/dist/rebalance_methods/autodriftRebalance.js +10 -10
- package/dist/rebalance_methods/autodriftRebalance.js.map +1 -1
- package/dist/rebalance_methods/driftRebalance.d.ts.map +1 -1
- package/dist/rebalance_methods/driftRebalance.js +10 -10
- package/dist/rebalance_methods/driftRebalance.js.map +1 -1
- package/dist/rebalance_methods/expanderRebalance.d.ts.map +1 -1
- package/dist/rebalance_methods/expanderRebalance.js +3 -4
- package/dist/rebalance_methods/expanderRebalance.js.map +1 -1
- package/dist/rebalance_methods/pricePercentageRebalance.d.ts.map +1 -1
- package/dist/rebalance_methods/pricePercentageRebalance.js +5 -6
- package/dist/rebalance_methods/pricePercentageRebalance.js.map +1 -1
- package/dist/rebalance_methods/pricePercentageWithResetRebalance.d.ts.map +1 -1
- package/dist/rebalance_methods/pricePercentageWithResetRebalance.js +5 -6
- package/dist/rebalance_methods/pricePercentageWithResetRebalance.js.map +1 -1
- package/dist/rebalance_methods/takeProfitRebalance.d.ts.map +1 -1
- package/dist/rebalance_methods/takeProfitRebalance.js +5 -5
- package/dist/rebalance_methods/takeProfitRebalance.js.map +1 -1
- package/dist/services/OrcaService.d.ts +7 -11
- package/dist/services/OrcaService.d.ts.map +1 -1
- package/dist/services/OrcaService.js +132 -100
- package/dist/services/OrcaService.js.map +1 -1
- package/dist/services/OrcaWhirlpoolsResponse.d.ts +63 -92
- package/dist/services/OrcaWhirlpoolsResponse.d.ts.map +1 -1
- package/dist/utils/farms.d.ts +1 -0
- package/dist/utils/farms.d.ts.map +1 -0
- package/dist/utils/farms.js +2 -0
- package/dist/utils/farms.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/orca.d.ts +37 -1
- package/dist/utils/orca.d.ts.map +1 -1
- package/dist/utils/orca.js +242 -0
- package/dist/utils/orca.js.map +1 -1
- package/dist/utils/tokenUtils.d.ts +5 -5
- package/dist/utils/tokenUtils.d.ts.map +1 -1
- package/dist/utils/tokenUtils.js +11 -7
- package/dist/utils/tokenUtils.js.map +1 -1
- package/dist/utils/types.d.ts +5 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/dist/utils/types.js.map +1 -1
- package/dist/utils/utils.d.ts +0 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +3 -4
- package/dist/utils/utils.js.map +1 -1
- package/dist/utils/whirlpools.d.ts +12 -1
- package/dist/utils/whirlpools.d.ts.map +1 -1
- package/dist/utils/whirlpools.js +30 -29
- package/dist/utils/whirlpools.js.map +1 -1
- package/package.json +4 -3
- package/src/Kamino.ts +252 -205
- package/src/constants/numericalValues.ts +5 -0
- package/src/rebalance_methods/autodriftRebalance.ts +30 -22
- package/src/rebalance_methods/driftRebalance.ts +30 -22
- package/src/rebalance_methods/expanderRebalance.ts +7 -4
- package/src/rebalance_methods/pricePercentageRebalance.ts +13 -6
- package/src/rebalance_methods/pricePercentageWithResetRebalance.ts +13 -6
- package/src/rebalance_methods/takeProfitRebalance.ts +13 -5
- package/src/services/OrcaService.ts +162 -125
- package/src/services/OrcaWhirlpoolsResponse.ts +69 -101
- package/src/utils/farms.ts +0 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/orca.ts +377 -1
- package/src/utils/tokenUtils.ts +5 -5
- package/src/utils/types.ts +7 -0
- package/src/utils/utils.ts +2 -4
- 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
|
|
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,
|
|
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.
|
|
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.
|
|
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,
|
|
552
|
-
tokenMintA: (0, kit_1.address)(pool.
|
|
553
|
-
tokenMintB: (0, kit_1.address)(pool.
|
|
554
|
-
tvl: pool.
|
|
555
|
-
feeRate: new decimal_js_1.default(pool.
|
|
556
|
-
volumeOnLast7d: pool.
|
|
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.
|
|
617
|
-
if ((element.
|
|
618
|
-
(element.
|
|
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,
|
|
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,
|
|
1042
|
-
const lowerPrice = (0,
|
|
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:
|
|
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,
|
|
1530
|
-
const upperPrice = (0,
|
|
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 =
|
|
1543
|
-
const upperPrice =
|
|
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
|
|
@@ -2941,8 +2942,8 @@ class Kamino {
|
|
|
2941
2942
|
};
|
|
2942
2943
|
};
|
|
2943
2944
|
getStartEndTicketIndexProgramAddressesOrca = async (whirlpool, whirlpoolState, tickLowerIndex, tickUpperIndex) => {
|
|
2944
|
-
const startTickIndex = (0,
|
|
2945
|
-
const endTickIndex = (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,
|
|
3094
|
-
const tickUpperIndex = (0,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
4135
|
-
if (
|
|
4136
|
-
|
|
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
|
|
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,
|
|
4662
|
-
const tickUpperIndex = (0,
|
|
4663
|
-
const
|
|
4664
|
-
|
|
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,
|
|
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.
|
|
4677
|
-
(0, utils_1.lamportsToNumberDecimal)(addLiqResult.
|
|
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
|
-
|
|
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 ({
|
|
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
|
|
4798
|
-
const
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
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
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
new decimal_js_1.default(
|
|
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
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
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
|
-
|
|
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,
|
|
5022
|
-
return { amountSlippageA: quote.
|
|
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:
|
|
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:
|
|
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
|
|
5056
|
-
|
|
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,
|
|
5067
|
-
return { amountSlippageA: quote.
|
|
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,
|
|
5282
|
-
const startTickIndex = (0,
|
|
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
|