UNPKG

@kamino-finance/kliquidity-sdk

Version:

Typescript SDK for interacting with the Kamino Liquidity (kliquidity) protocol

180 lines 9.61 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DriftRebalanceTypeName = exports.DEFAULT_DIRECTION = exports.DEFAULT_SECONDS_PER_TICK = exports.DEFAULT_TICKS_ABOVE_MID = exports.DEFAULT_TICKS_BELOW_MID = void 0; exports.getDriftRebalanceFieldInfos = getDriftRebalanceFieldInfos; exports.getPositionRangeFromDriftParams = getPositionRangeFromDriftParams; exports.getDefaultDriftRebalanceFieldInfos = getDefaultDriftRebalanceFieldInfos; exports.readDriftRebalanceParamsFromStrategy = readDriftRebalanceParamsFromStrategy; exports.readRawDriftRebalanceStateFromStrategy = readRawDriftRebalanceStateFromStrategy; exports.readDriftRebalanceStateFromStrategy = readDriftRebalanceStateFromStrategy; exports.deserializeDriftRebalanceFromOnchainParams = deserializeDriftRebalanceFromOnchainParams; exports.deserializeDriftRebalanceWithStateOverride = deserializeDriftRebalanceWithStateOverride; const decimal_js_1 = __importDefault(require("decimal.js")); const whirlpool_sdk_1 = require("@orca-so/whirlpool-sdk"); const consts_1 = require("./consts"); const utils_1 = require("./utils"); const meteora_1 = require("../utils/meteora"); const lib_1 = require("@raydium-io/raydium-sdk-v2/lib"); exports.DEFAULT_TICKS_BELOW_MID = new decimal_js_1.default(10); exports.DEFAULT_TICKS_ABOVE_MID = new decimal_js_1.default(10); exports.DEFAULT_SECONDS_PER_TICK = new decimal_js_1.default(60 * 60 * 24 * 3); // 3 days; todo: get a reasonable default from Matt exports.DEFAULT_DIRECTION = new decimal_js_1.default(1); exports.DriftRebalanceTypeName = 'drift'; function getDriftRebalanceFieldInfos(dex, tickSpacing, tokenADecimals, tokenBDecimals, startMidTick, ticksBelowMid, ticksAboveMid, secondsPerTick, direction, enabled = true) { const rebalanceType = { label: consts_1.RebalanceTypeLabelName, type: 'string', value: exports.DriftRebalanceTypeName, enabled, }; const startMidTickRebalanceFieldInfo = { label: 'startMidTick', type: 'number', value: startMidTick, enabled, }; const ticksBelowMidRebalanceFieldInfo = { label: 'ticksBelowMid', type: 'number', value: ticksBelowMid, enabled, }; const ticksAboveMidRebalanceFieldInfo = { label: 'ticksAboveMid', type: 'number', value: ticksAboveMid, enabled, }; const secondsPerTickRebalanceFieldInfo = { label: 'secondsPerTick', type: 'number', value: secondsPerTick, enabled, }; const directionRebalanceFieldInfo = { label: 'direction', type: 'number', value: direction, enabled, }; const { lowerPrice, upperPrice } = getPositionRangeFromDriftParams(dex, tokenADecimals, tokenBDecimals, tickSpacing, startMidTick, ticksBelowMid, ticksAboveMid); const lowerRangeRebalanceFieldInfo = { label: 'rangePriceLower', type: 'number', value: lowerPrice, enabled: false, }; const upperRangeRebalanceFieldInfo = { label: 'rangePriceUpper', type: 'number', value: upperPrice, enabled: false, }; return [ rebalanceType, startMidTickRebalanceFieldInfo, ticksBelowMidRebalanceFieldInfo, ticksAboveMidRebalanceFieldInfo, secondsPerTickRebalanceFieldInfo, directionRebalanceFieldInfo, lowerRangeRebalanceFieldInfo, upperRangeRebalanceFieldInfo, ]; } function getPositionRangeFromDriftParams(dex, tickSpacing, tokenADecimals, tokenBDecimals, startMidTick, ticksBelowMid, ticksAboveMid) { const lowerTickIndex = startMidTick.sub(ticksBelowMid); const upperTickIndex = startMidTick.add(ticksAboveMid); if (dex == 'ORCA') { const lowerPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(lowerTickIndex.toNumber(), tokenADecimals, tokenBDecimals); const upperPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(upperTickIndex.toNumber(), tokenADecimals, tokenBDecimals); return { lowerPrice, upperPrice }; } else if (dex == 'RAYDIUM') { const lowerPrice = (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(lowerTickIndex.toNumber()), tokenADecimals, tokenBDecimals); const upperPrice = (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(upperTickIndex.toNumber()), tokenADecimals, tokenBDecimals); return { lowerPrice, upperPrice }; } else if (dex == 'METEORA') { const lowerPrice = (0, meteora_1.getPriceOfBinByBinIdWithDecimals)(lowerTickIndex.toNumber(), tickSpacing, tokenADecimals, tokenBDecimals); const upperPrice = (0, meteora_1.getPriceOfBinByBinIdWithDecimals)(upperTickIndex.toNumber(), tickSpacing, tokenADecimals, tokenBDecimals); return { lowerPrice, upperPrice }; } else { throw new Error(`Unknown DEX ${dex}`); } } // todo(silviu): get sensible default params from Matt function getDefaultDriftRebalanceFieldInfos(dex, tickSpacing, price, tokenADecimals, tokenBDecimals) { const currentTickIndex = (0, whirlpool_sdk_1.priceToTickIndex)(price, tokenADecimals, tokenBDecimals); const startMidTick = new decimal_js_1.default(currentTickIndex); return getDriftRebalanceFieldInfos(dex, tickSpacing, tokenADecimals, tokenBDecimals, startMidTick, exports.DEFAULT_TICKS_BELOW_MID, exports.DEFAULT_TICKS_ABOVE_MID, exports.DEFAULT_SECONDS_PER_TICK, exports.DEFAULT_DIRECTION); } function readDriftRebalanceParamsFromStrategy(rebalanceRaw) { const paramsBuffer = Buffer.from(rebalanceRaw.params); const params = {}; params['startMidTick'] = new decimal_js_1.default(paramsBuffer.readInt32LE(0)); params['ticksBelowMid'] = new decimal_js_1.default(paramsBuffer.readInt32LE(4)); params['ticksAboveMid'] = new decimal_js_1.default(paramsBuffer.readInt32LE(8)); params['secondsPerTick'] = new decimal_js_1.default(paramsBuffer.readBigUInt64LE(12).toString()); params['direction'] = new decimal_js_1.default(paramsBuffer.readUint8(20)); return params; } function readRawDriftRebalanceStateFromStrategy(rebalanceRaw) { const stateBuffer = Buffer.from(rebalanceRaw.state); const state = {}; state['step'] = new decimal_js_1.default(stateBuffer.readUInt8(0)); state['lastDriftTimestamp'] = new decimal_js_1.default(stateBuffer.readBigUInt64LE(1).toString()); state['lastMidTick'] = new decimal_js_1.default(stateBuffer.readInt32LE(9)); return state; } function readDriftRebalanceStateFromStrategy(dex, tickSpacing, tokenADecimals, tokenBDecimals, rebalanceRaw) { const stateBuffer = Buffer.from(rebalanceRaw.state); const paramsBuffer = Buffer.from(rebalanceRaw.params); const lastMidTick = new decimal_js_1.default(stateBuffer.readInt32LE(9)); const ticksBelowMid = new decimal_js_1.default(paramsBuffer.readInt32LE(4)); const ticksAboveMid = new decimal_js_1.default(paramsBuffer.readInt32LE(8)); const lowerTickIndex = lastMidTick.sub(ticksBelowMid); const upperTickIndex = lastMidTick.add(ticksAboveMid); let lowerPrice, upperPrice; if (dex == 'ORCA') { lowerPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(lowerTickIndex.toNumber(), tokenADecimals, tokenBDecimals); upperPrice = (0, whirlpool_sdk_1.tickIndexToPrice)(upperTickIndex.toNumber(), tokenADecimals, tokenBDecimals); } else if (dex == 'RAYDIUM') { lowerPrice = (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(lowerTickIndex.toNumber()), tokenADecimals, tokenBDecimals); upperPrice = (0, whirlpool_sdk_1.sqrtPriceX64ToPrice)(lib_1.SqrtPriceMath.getSqrtPriceX64FromTick(upperTickIndex.toNumber()), tokenADecimals, tokenBDecimals); } else if (dex == 'METEORA') { lowerPrice = (0, meteora_1.getPriceOfBinByBinIdWithDecimals)(lowerTickIndex.toNumber(), tickSpacing, tokenADecimals, tokenBDecimals); upperPrice = (0, meteora_1.getPriceOfBinByBinIdWithDecimals)(upperTickIndex.toNumber(), tickSpacing, tokenADecimals, tokenBDecimals); } else { throw new Error(`Unknown DEX ${dex}`); } const lowerRangeRebalanceFieldInfo = { label: 'rangePriceLower', type: 'number', value: lowerPrice, enabled: false, }; const upperRangeRebalanceFieldInfo = { label: 'rangePriceUpper', type: 'number', value: upperPrice, enabled: false, }; return [lowerRangeRebalanceFieldInfo, upperRangeRebalanceFieldInfo]; } function deserializeDriftRebalanceFromOnchainParams(dex, tickSpacing, tokenADecimals, tokenBDecimals, rebalanceRaw) { const params = readDriftRebalanceParamsFromStrategy(rebalanceRaw); return getDriftRebalanceFieldInfos(dex, tickSpacing, tokenADecimals, tokenBDecimals, params['startMidTick'], params['ticksBelowMid'], params['ticksAboveMid'], params['secondsPerTick'], params['direction']); } function deserializeDriftRebalanceWithStateOverride(dex, tickSpacing, tokenADecimals, tokenBDecimals, rebalanceRaw) { const stateFields = readDriftRebalanceStateFromStrategy(dex, tickSpacing, tokenADecimals, tokenBDecimals, rebalanceRaw); const fields = deserializeDriftRebalanceFromOnchainParams(dex, tickSpacing, tokenADecimals, tokenBDecimals, rebalanceRaw); return (0, utils_1.upsertManyRebalanceFieldInfos)(fields, stateFields); } //# sourceMappingURL=driftRebalance.js.map