UNPKG

@orca-so/whirlpool-sdk

Version:

Whirlpool SDK for the Orca protocol.

95 lines (94 loc) 5 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLiquidityDistribution = void 0; const whirlpool_client_sdk_1 = require("@orca-so/whirlpool-client-sdk"); const anchor_1 = require("@project-serum/anchor"); const decimal_js_1 = __importDefault(require("decimal.js")); const __1 = require("../.."); const address_1 = require("../../utils/address"); const tick_util_1 = require("../../utils/whirlpool/tick-util"); function getLiquidityDistribution(dal, poolAddress, tickLower, tickUpper, refresh) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const datapoints = []; const pool = yield dal.getPool(poolAddress, refresh); if (!pool) { throw new Error(`Whirlpool not found: ${(0, anchor_1.translateAddress)(poolAddress).toBase58()}`); } const tokenDecimalsA = (_a = (yield dal.getMintInfo(pool.tokenMintA, false))) === null || _a === void 0 ? void 0 : _a.decimals; if (!tokenDecimalsA) { throw new Error(`Token mint not found: ${pool.tokenMintA.toBase58()}`); } const tokenDecimalsB = (_b = (yield dal.getMintInfo(pool.tokenMintB, false))) === null || _b === void 0 ? void 0 : _b.decimals; if (!tokenDecimalsB) { throw new Error(`Token mint not found: ${pool.tokenMintB.toBase58()}`); } const tickArrayAddresses = getSurroundingTickArrayAddresses(pool, poolAddress, tickLower, tickUpper, dal.programId); const tickArrays = yield dal.listTickArrays(tickArrayAddresses, refresh); const currentLiquidity = new decimal_js_1.default(pool.liquidity.toString()); let relativeLiquidity = currentLiquidity; let minLiquidity = new decimal_js_1.default(0); let liquidity = new decimal_js_1.default(0); tickArrays.forEach((tickArray) => { if (!tickArray) { return; } const startIndex = tickArray.startTickIndex; tickArray.ticks.forEach((tick, index) => { const tickIndex = startIndex + index * pool.tickSpacing; const price = (0, __1.tickIndexToPrice)(tickIndex, tokenDecimalsA, tokenDecimalsB); const liquidityNet = new decimal_js_1.default(tick.liquidityNet.toString()); liquidity = liquidity.add(liquidityNet); datapoints.push({ liquidity: new decimal_js_1.default(liquidity), price, tickIndex }); minLiquidity = liquidity.lt(minLiquidity) ? liquidity : minLiquidity; if (tickIndex === pool.tickCurrentIndex) { relativeLiquidity = relativeLiquidity.sub(liquidityNet); } }); }); if (!relativeLiquidity.eq(currentLiquidity)) { minLiquidity = minLiquidity.add(relativeLiquidity); datapoints.forEach((datapoint) => { datapoint.liquidity = datapoint.liquidity.add(relativeLiquidity); }); } if (minLiquidity.lt(0)) { datapoints.forEach((datapoint) => { datapoint.liquidity = datapoint.liquidity.add(minLiquidity.neg()); }); } return { currentPrice: (0, __1.sqrtPriceX64ToPrice)(pool.sqrtPrice, tokenDecimalsA, tokenDecimalsB), currentTickIndex: pool.tickCurrentIndex, datapoints, }; }); } exports.getLiquidityDistribution = getLiquidityDistribution; function getSurroundingTickArrayAddresses(pool, poolAddress, tickLower, tickUpper, programId) { const tickArrayAddresses = []; let startIndex = tick_util_1.TickUtil.getStartTickIndex(tickLower, pool.tickSpacing); while (startIndex <= tickUpper) { const address = (0, whirlpool_client_sdk_1.getTickArrayPda)((0, address_1.toPubKey)(programId), (0, address_1.toPubKey)(poolAddress), startIndex).publicKey; tickArrayAddresses.push(address); try { startIndex = tick_util_1.TickUtil.getStartTickIndex(startIndex, pool.tickSpacing, 1); } catch (_e) { return tickArrayAddresses; } } return tickArrayAddresses; }