UNPKG

@kamino-finance/kliquidity-sdk

Version:

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

220 lines 12.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AutodriftRebalanceTypeName = exports.DEFAULT_DIRECTION = exports.DEFAULT_STAKING_RATE_SOURCE_B = exports.DEFAULT_STAKING_RATE_SOURCE_A = exports.DEFAULT_FRONTRUN_MULTIPLIER_BPS = exports.DEFAULT_TICKS_ABOVE_MID = exports.DEFAULT_TICKS_BELOW_MID = exports.DEFAULT_DRIFT_TICKS_PER_EPOCH = void 0; exports.getAutodriftRebalanceFieldInfos = getAutodriftRebalanceFieldInfos; exports.getPositionRangeFromAutodriftParams = getPositionRangeFromAutodriftParams; exports.getDefaultAutodriftRebalanceFieldInfos = getDefaultAutodriftRebalanceFieldInfos; exports.readAutodriftRebalanceParamsFromStrategy = readAutodriftRebalanceParamsFromStrategy; exports.readRawAutodriftRebalanceStateFromStrategy = readRawAutodriftRebalanceStateFromStrategy; exports.readAutodriftRebalanceStateFromStrategy = readAutodriftRebalanceStateFromStrategy; exports.deserializeAutodriftRebalanceFromOnchainParams = deserializeAutodriftRebalanceFromOnchainParams; exports.deserializeAutodriftRebalanceWithStateOverride = deserializeAutodriftRebalanceWithStateOverride; const decimal_js_1 = __importDefault(require("decimal.js")); const utils_1 = require("../utils"); const whirlpool_sdk_1 = require("@orca-so/whirlpool-sdk"); const consts_1 = require("./consts"); const utils_2 = require("./utils"); const meteora_1 = require("../utils/meteora"); const lib_1 = require("@raydium-io/raydium-sdk-v2/lib"); exports.DEFAULT_DRIFT_TICKS_PER_EPOCH = new decimal_js_1.default(1); exports.DEFAULT_TICKS_BELOW_MID = new decimal_js_1.default(10); exports.DEFAULT_TICKS_ABOVE_MID = new decimal_js_1.default(10); exports.DEFAULT_FRONTRUN_MULTIPLIER_BPS = new decimal_js_1.default(10_000); exports.DEFAULT_STAKING_RATE_SOURCE_A = new decimal_js_1.default(0); exports.DEFAULT_STAKING_RATE_SOURCE_B = new decimal_js_1.default(0); exports.DEFAULT_DIRECTION = new decimal_js_1.default(1); exports.AutodriftRebalanceTypeName = 'autodrift'; function getAutodriftRebalanceFieldInfos(dex, tokenADecimals, tokenBDecimals, tickSpacing, lastMidTick, initDriftTicksPerEpoch, ticksBelowMid, ticksAboveMid, frontrunMultiplierBps, stakingRateASource, stakingRateBSource, initialDriftDirection, enabled = true) { const rebalanceType = { label: consts_1.RebalanceTypeLabelName, type: 'string', value: exports.AutodriftRebalanceTypeName, enabled, }; const lastMidTickRebalanceFieldInfo = { label: 'lastMidTick', type: 'number', value: lastMidTick, enabled: false, }; const initDriftTicksPerEpochRebalanceFieldInfo = { label: 'initDriftTicksPerEpoch', type: 'number', value: initDriftTicksPerEpoch, enabled, }; const ticksBelowMidRebalanceFieldInfo = { label: 'ticksBelowMid', type: 'number', value: ticksBelowMid, enabled, }; const ticksAboveMidRebalanceFieldInfo = { label: 'ticksAboveMid', type: 'number', value: ticksAboveMid, enabled, }; const fronturnMultiplierBpsRebalanceFieldInfo = { label: 'frontrunMultiplierBps', type: 'number', value: frontrunMultiplierBps, enabled, }; const stakingRateASourceRebalanceFieldInfo = { label: 'stakingRateASource', type: 'number', value: stakingRateASource, enabled, }; const stakingRateBSourceRebalanceFieldInfo = { label: 'stakingRateBSource', type: 'number', value: stakingRateBSource, enabled, }; const initialDriftDirectionRebalanceFieldInfo = { label: 'initialDriftDirection', type: 'number', value: initialDriftDirection, enabled, }; const { lowerPrice, upperPrice } = getPositionRangeFromAutodriftParams(dex, tokenADecimals, tokenBDecimals, lastMidTick, ticksBelowMid, ticksAboveMid, tickSpacing); const lowerRangeRebalanceFieldInfo = { label: 'rangePriceLower', type: 'number', value: lowerPrice, enabled: false, }; const upperRangeRebalanceFieldInfo = { label: 'rangePriceUpper', type: 'number', value: upperPrice, enabled: false, }; return [ rebalanceType, ticksBelowMidRebalanceFieldInfo, ticksAboveMidRebalanceFieldInfo, initialDriftDirectionRebalanceFieldInfo, lowerRangeRebalanceFieldInfo, upperRangeRebalanceFieldInfo, fronturnMultiplierBpsRebalanceFieldInfo, stakingRateASourceRebalanceFieldInfo, stakingRateBSourceRebalanceFieldInfo, initDriftTicksPerEpochRebalanceFieldInfo, lastMidTickRebalanceFieldInfo, ]; } function getPositionRangeFromAutodriftParams(dex, tokenADecimals, tokenBDecimals, startMidTick, ticksBelowMid, ticksAboveMid, tickSpacing) { 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 getDefaultAutodriftRebalanceFieldInfos(dex, price, tokenADecimals, tokenBDecimals, tickSpacing) { const currentTickIndex = (0, whirlpool_sdk_1.priceToTickIndex)(price, tokenADecimals, tokenBDecimals); const startMidTick = new decimal_js_1.default(currentTickIndex); return getAutodriftRebalanceFieldInfos(dex, tokenADecimals, tokenBDecimals, tickSpacing, startMidTick, exports.DEFAULT_DRIFT_TICKS_PER_EPOCH, exports.DEFAULT_TICKS_BELOW_MID, exports.DEFAULT_TICKS_ABOVE_MID, exports.DEFAULT_FRONTRUN_MULTIPLIER_BPS, exports.DEFAULT_STAKING_RATE_SOURCE_A, exports.DEFAULT_STAKING_RATE_SOURCE_B, exports.DEFAULT_DIRECTION); } function readAutodriftRebalanceParamsFromStrategy(rebalanceRaw) { const paramsBuffer = Buffer.from(rebalanceRaw.params); const params = {}; params['initDriftTicksPerEpoch'] = new decimal_js_1.default(paramsBuffer.readUInt32LE(0)); params['ticksBelowMid'] = new decimal_js_1.default(paramsBuffer.readInt32LE(4)); params['ticksAboveMid'] = new decimal_js_1.default(paramsBuffer.readInt32LE(8)); params['frontrunMultiplierBps'] = new decimal_js_1.default(paramsBuffer.readUInt16LE(12)); params['stakingRateASource'] = new decimal_js_1.default(paramsBuffer.readUint8(14)); params['stakingRateBSource'] = new decimal_js_1.default(paramsBuffer.readUint8(15)); params['initialDriftDirection'] = new decimal_js_1.default(paramsBuffer.readUint8(16)); return params; } function readRawAutodriftRebalanceStateFromStrategy(rebalanceRaw) { const stateBuffer = Buffer.from(rebalanceRaw.state); const state = {}; // prettier-ignore { let offset = 0; [offset, state['last_window_staking_rate_a']] = (0, utils_1.readPriceOption)(stateBuffer, offset); [offset, state['last_window_staking_rate_b']] = (0, utils_1.readPriceOption)(stateBuffer, offset); [offset, state['last_window_epoch']] = [offset + 8, new decimal_js_1.default(stateBuffer.readBigUInt64LE(offset).toString())]; [offset, state['last_window_theoretical_tick']] = [offset + 4, new decimal_js_1.default(stateBuffer.readInt32LE(offset))]; [offset, state['last_window_strat_mid_tick']] = [offset + 4, new decimal_js_1.default(stateBuffer.readInt32LE(offset))]; [offset, state['current_window_staking_rate_a']] = (0, utils_1.readPriceOption)(stateBuffer, offset); [offset, state['current_window_staking_rate_b']] = (0, utils_1.readPriceOption)(stateBuffer, offset); [offset, state['current_window_epoch']] = [offset + 8, new decimal_js_1.default(stateBuffer.readBigUInt64LE(offset).toString())]; [offset, state['current_window_theoretical_tick']] = [offset + 4, new decimal_js_1.default(stateBuffer.readInt32LE(offset))]; [offset, state['current_window_strat_mid_tick']] = [offset + 4, new decimal_js_1.default(stateBuffer.readInt32LE(offset))]; [offset, state['autodrift_step']] = [offset + 1, new decimal_js_1.default(stateBuffer.readInt8(offset))]; } return state; } function readAutodriftRebalanceStateFromStrategy(dex, tokenADecimals, tokenBDecimals, tickSpacing, rebalanceRaw) { const params = readAutodriftRebalanceParamsFromStrategy(rebalanceRaw); const state = readRawAutodriftRebalanceStateFromStrategy(rebalanceRaw); const lastMidTick = state['current_window_strat_mid_tick']; const ticksBelowMid = params['ticksBelowMid']; const ticksAboveMid = params['ticksAboveMid']; 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 deserializeAutodriftRebalanceFromOnchainParams(dex, tokenADecimals, tokenBDecimals, tickSpacing, rebalanceRaw) { const params = readAutodriftRebalanceParamsFromStrategy(rebalanceRaw); const state = readRawAutodriftRebalanceStateFromStrategy(rebalanceRaw); return getAutodriftRebalanceFieldInfos(dex, tokenADecimals, tokenBDecimals, tickSpacing, state['current_window_strat_mid_tick'], params['initDriftTicksPerEpoch'], params['ticksBelowMid'], params['ticksAboveMid'], params['frontrunMultiplierBps'], params['stakingRateASource'], params['stakingRateBSource'], params['initialDriftDirection']); } function deserializeAutodriftRebalanceWithStateOverride(dex, tokenADecimals, tokenBDecimals, tickSpacing, rebalanceRaw) { const stateFields = readAutodriftRebalanceStateFromStrategy(dex, tokenADecimals, tokenBDecimals, tickSpacing, rebalanceRaw); const fields = deserializeAutodriftRebalanceFromOnchainParams(dex, tokenADecimals, tokenBDecimals, tickSpacing, rebalanceRaw); return (0, utils_2.upsertManyRebalanceFieldInfos)(fields, stateFields); } //# sourceMappingURL=autodriftRebalance.js.map