UNPKG

@drift-labs/sdk

Version:
151 lines (150 loc) 6.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DLOBSubscriber = void 0; const DLOB_1 = require("./DLOB"); const events_1 = require("events"); const types_1 = require("../types"); const orderBookLevels_1 = require("./orderBookLevels"); const protectedMakerParams_1 = require("../math/protectedMakerParams"); class DLOBSubscriber { constructor(config) { this.driftClient = config.driftClient; this.dlobSource = config.dlobSource; this.slotSource = config.slotSource; this.updateFrequency = config.updateFrequency; this.protectedMakerView = config.protectedMakerView || false; this.dlob = new DLOB_1.DLOB(this.getProtectedMakerParamsMap()); this.eventEmitter = new events_1.EventEmitter(); } async subscribe() { if (this.intervalId) { return; } await this.updateDLOB(); this.intervalId = setInterval(async () => { try { await this.updateDLOB(); this.eventEmitter.emit('update', this.dlob); } catch (e) { this.eventEmitter.emit('error', e); } }, this.updateFrequency); } getProtectedMakerParamsMap() { return this.protectedMakerView ? (0, protectedMakerParams_1.getProtectedMakerParamsMap)(this.driftClient.getPerpMarketAccounts()) : undefined; } async updateDLOB() { this.dlob = await this.dlobSource.getDLOB(this.slotSource.getSlot(), this.getProtectedMakerParamsMap()); } getDLOB() { return this.dlob; } /** * Get the L2 order book for a given market. * * @param marketName e.g. "SOL-PERP" or "SOL". If not provided, marketIndex and marketType must be provided. * @param marketIndex * @param marketType * @param depth Number of orders to include in the order book. Defaults to 10. * @param includeVamm Whether to include the VAMM orders in the order book. Defaults to false. If true, creates vAMM generator {@link getVammL2Generator} and adds it to fallbackL2Generators. * @param fallbackL2Generators L2 generators for fallback liquidity e.g. vAMM {@link getVammL2Generator}, openbook {@link SerumSubscriber} * @param latestSlot Latest slot observed via slot subscriber or similar for accuarate vamm quotes (if including the vAMM). */ getL2({ marketName, marketIndex, marketType, depth = 10, includeVamm = false, numVammOrders, fallbackL2Generators = [], latestSlot, }) { if (marketName) { const derivedMarketInfo = this.driftClient.getMarketIndexAndType(marketName); if (!derivedMarketInfo) { throw new Error(`Market ${marketName} not found`); } marketIndex = derivedMarketInfo.marketIndex; marketType = derivedMarketInfo.marketType; } else { if (marketIndex === undefined || marketType === undefined) { throw new Error('Either marketName or marketIndex and marketType must be provided'); } } let oraclePriceData; const isPerp = (0, types_1.isVariant)(marketType, 'perp'); if (isPerp) { const perpMarketAccount = this.driftClient.getPerpMarketAccount(marketIndex); oraclePriceData = this.driftClient.getOracleDataForPerpMarket(perpMarketAccount.marketIndex); } else { oraclePriceData = this.driftClient.getOracleDataForSpotMarket(marketIndex); } if (isPerp && includeVamm) { if (fallbackL2Generators.length > 0) { throw new Error('includeVamm can only be used if fallbackL2Generators is empty'); } fallbackL2Generators = [ (0, orderBookLevels_1.getVammL2Generator)({ marketAccount: this.driftClient.getPerpMarketAccount(marketIndex), mmOraclePriceData: this.driftClient.getMMOracleDataForPerpMarket(marketIndex), numOrders: numVammOrders !== null && numVammOrders !== void 0 ? numVammOrders : depth, topOfBookQuoteAmounts: marketIndex < 3 ? orderBookLevels_1.MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS : orderBookLevels_1.DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS, latestSlot, }), ]; } return this.dlob.getL2({ marketIndex, marketType, depth, oraclePriceData, slot: this.slotSource.getSlot(), fallbackL2Generators: fallbackL2Generators, }); } /** * Get the L3 order book for a given market. * * @param marketName e.g. "SOL-PERP" or "SOL". If not provided, marketIndex and marketType must be provided. * @param marketIndex * @param marketType */ getL3({ marketName, marketIndex, marketType, }) { if (marketName) { const derivedMarketInfo = this.driftClient.getMarketIndexAndType(marketName); if (!derivedMarketInfo) { throw new Error(`Market ${marketName} not found`); } marketIndex = derivedMarketInfo.marketIndex; marketType = derivedMarketInfo.marketType; } else { if (marketIndex === undefined || marketType === undefined) { throw new Error('Either marketName or marketIndex and marketType must be provided'); } } let oraclePriceData; const isPerp = (0, types_1.isVariant)(marketType, 'perp'); if (isPerp) { oraclePriceData = this.driftClient.getOracleDataForPerpMarket(marketIndex); } else { oraclePriceData = this.driftClient.getOracleDataForSpotMarket(marketIndex); } return this.dlob.getL3({ marketIndex, marketType, oraclePriceData, slot: this.slotSource.getSlot(), }); } async unsubscribe() { if (this.intervalId) { clearInterval(this.intervalId); this.intervalId = undefined; } } } exports.DLOBSubscriber = DLOBSubscriber;