UNPKG

@renec-foundation/redex-sdk

Version:

Typescript SDK to interact with Orca's Whirlpool program.

137 lines (136 loc) 7.95 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.increaseLiquidityQuoteByInputTokenWithParams = exports.increaseLiquidityQuoteByInputToken = void 0; const common_sdk_1 = require("@orca-so/common-sdk"); const tiny_invariant_1 = __importDefault(require("tiny-invariant")); const position_util_1 = require("../../utils/position-util"); const public_1 = require("../../utils/public"); /** * Get an estimated quote on the maximum tokens required to deposit based on a specified input token amount. * * @category Quotes * @param inputTokenAmount - The amount of input tokens to deposit. * @param inputTokenMint - The mint of the input token the user would like to deposit. * @param tickLower - The lower index of the position that we are withdrawing from. * @param tickUpper - The upper index of the position that we are withdrawing from. * @param slippageTolerance - The maximum slippage allowed when calculating the minimum tokens received. * @param whirlpool - A Whirlpool helper class to help interact with the Whirlpool account. * @returns An IncreaseLiquidityInput object detailing the required token amounts & liquidity values to use when calling increase-liquidity-ix. */ function increaseLiquidityQuoteByInputToken(inputTokenMint, inputTokenAmount, tickLower, tickUpper, slippageTolerance, whirlpool) { const data = whirlpool.getData(); const tokenAInfo = whirlpool.getTokenAInfo(); const tokenBInfo = whirlpool.getTokenBInfo(); const inputMint = common_sdk_1.AddressUtil.toPubKey(inputTokenMint); const inputTokenInfo = inputMint.equals(tokenAInfo.mint) ? tokenAInfo : tokenBInfo; return increaseLiquidityQuoteByInputTokenWithParams(Object.assign({ inputTokenMint: inputMint, inputTokenAmount: common_sdk_1.DecimalUtil.toU64(inputTokenAmount, inputTokenInfo.decimals), tickLowerIndex: public_1.TickUtil.getInitializableTickIndex(tickLower, data.tickSpacing), tickUpperIndex: public_1.TickUtil.getInitializableTickIndex(tickUpper, data.tickSpacing), slippageTolerance }, data)); } exports.increaseLiquidityQuoteByInputToken = increaseLiquidityQuoteByInputToken; /** * Get an estimated quote on the maximum tokens required to deposit based on a specified input token amount. * * @category Quotes * @param param IncreaseLiquidityQuoteParam * @returns An IncreaseLiquidityInput object detailing the required token amounts & liquidity values to use when calling increase-liquidity-ix. */ function increaseLiquidityQuoteByInputTokenWithParams(param) { (0, tiny_invariant_1.default)(public_1.TickUtil.checkTickInBounds(param.tickLowerIndex), "tickLowerIndex is out of bounds."); (0, tiny_invariant_1.default)(public_1.TickUtil.checkTickInBounds(param.tickUpperIndex), "tickUpperIndex is out of bounds."); (0, tiny_invariant_1.default)(param.inputTokenMint.equals(param.tokenMintA) || param.inputTokenMint.equals(param.tokenMintB), `input token mint ${param.inputTokenMint.toBase58()} does not match any tokens in the provided pool.`); const positionStatus = position_util_1.PositionUtil.getPositionStatus(param.tickCurrentIndex, param.tickLowerIndex, param.tickUpperIndex); switch (positionStatus) { case position_util_1.PositionStatus.BelowRange: return quotePositionBelowRange(param); case position_util_1.PositionStatus.InRange: return quotePositionInRange(param); case position_util_1.PositionStatus.AboveRange: return quotePositionAboveRange(param); default: throw new Error(`type ${positionStatus} is an unknown PositionStatus`); } } exports.increaseLiquidityQuoteByInputTokenWithParams = increaseLiquidityQuoteByInputTokenWithParams; /*** Private ***/ function quotePositionBelowRange(param) { const { tokenMintA, inputTokenMint, inputTokenAmount, tickLowerIndex, tickUpperIndex, slippageTolerance, } = param; if (!tokenMintA.equals(inputTokenMint)) { return { tokenMaxA: common_sdk_1.ZERO, tokenMaxB: common_sdk_1.ZERO, tokenEstA: common_sdk_1.ZERO, tokenEstB: common_sdk_1.ZERO, liquidityAmount: common_sdk_1.ZERO, }; } const sqrtPriceLowerX64 = public_1.PriceMath.tickIndexToSqrtPriceX64(tickLowerIndex); const sqrtPriceUpperX64 = public_1.PriceMath.tickIndexToSqrtPriceX64(tickUpperIndex); const liquidityAmount = (0, position_util_1.getLiquidityFromTokenA)(inputTokenAmount, sqrtPriceLowerX64, sqrtPriceUpperX64, false); const tokenEstA = (0, position_util_1.getTokenAFromLiquidity)(liquidityAmount, sqrtPriceLowerX64, sqrtPriceUpperX64, true); const tokenMaxA = (0, position_util_1.adjustForSlippage)(tokenEstA, slippageTolerance, true); return { tokenMaxA, tokenMaxB: common_sdk_1.ZERO, tokenEstA, tokenEstB: common_sdk_1.ZERO, liquidityAmount, }; } function quotePositionInRange(param) { const { tokenMintA, sqrtPrice, inputTokenMint, inputTokenAmount, tickLowerIndex, tickUpperIndex, slippageTolerance, } = param; const sqrtPriceX64 = sqrtPrice; const sqrtPriceLowerX64 = public_1.PriceMath.tickIndexToSqrtPriceX64(tickLowerIndex); const sqrtPriceUpperX64 = public_1.PriceMath.tickIndexToSqrtPriceX64(tickUpperIndex); let [tokenEstA, tokenEstB] = tokenMintA.equals(inputTokenMint) ? [inputTokenAmount, undefined] : [undefined, inputTokenAmount]; let liquidityAmount; if (tokenEstA) { liquidityAmount = (0, position_util_1.getLiquidityFromTokenA)(tokenEstA, sqrtPriceX64, sqrtPriceUpperX64, false); tokenEstA = (0, position_util_1.getTokenAFromLiquidity)(liquidityAmount, sqrtPriceX64, sqrtPriceUpperX64, true); tokenEstB = (0, position_util_1.getTokenBFromLiquidity)(liquidityAmount, sqrtPriceLowerX64, sqrtPriceX64, true); } else if (tokenEstB) { liquidityAmount = (0, position_util_1.getLiquidityFromTokenB)(tokenEstB, sqrtPriceLowerX64, sqrtPriceX64, false); tokenEstA = (0, position_util_1.getTokenAFromLiquidity)(liquidityAmount, sqrtPriceX64, sqrtPriceUpperX64, true); tokenEstB = (0, position_util_1.getTokenBFromLiquidity)(liquidityAmount, sqrtPriceLowerX64, sqrtPriceX64, true); } else { throw new Error("invariant violation"); } const tokenMaxA = (0, position_util_1.adjustForSlippage)(tokenEstA, slippageTolerance, true); const tokenMaxB = (0, position_util_1.adjustForSlippage)(tokenEstB, slippageTolerance, true); return { tokenMaxA, tokenMaxB, tokenEstA: tokenEstA, tokenEstB: tokenEstB, liquidityAmount, }; } function quotePositionAboveRange(param) { const { tokenMintB, inputTokenMint, inputTokenAmount, tickLowerIndex, tickUpperIndex, slippageTolerance, } = param; if (!tokenMintB.equals(inputTokenMint)) { return { tokenMaxA: common_sdk_1.ZERO, tokenMaxB: common_sdk_1.ZERO, tokenEstA: common_sdk_1.ZERO, tokenEstB: common_sdk_1.ZERO, liquidityAmount: common_sdk_1.ZERO, }; } const sqrtPriceLowerX64 = public_1.PriceMath.tickIndexToSqrtPriceX64(tickLowerIndex); const sqrtPriceUpperX64 = public_1.PriceMath.tickIndexToSqrtPriceX64(tickUpperIndex); const liquidityAmount = (0, position_util_1.getLiquidityFromTokenB)(inputTokenAmount, sqrtPriceLowerX64, sqrtPriceUpperX64, false); const tokenEstB = (0, position_util_1.getTokenBFromLiquidity)(liquidityAmount, sqrtPriceLowerX64, sqrtPriceUpperX64, true); const tokenMaxB = (0, position_util_1.adjustForSlippage)(tokenEstB, slippageTolerance, true); return { tokenMaxA: common_sdk_1.ZERO, tokenMaxB, tokenEstA: common_sdk_1.ZERO, tokenEstB, liquidityAmount, }; }