@drift-labs/sdk
Version:
SDK for Drift Protocol
151 lines (150 loc) • 6.31 kB
JavaScript
"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;