@drift-labs/sdk
Version:
SDK for Drift Protocol
100 lines (99 loc) • 5.77 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.gprcDriftClientAccountSubscriber = void 0;
const webSocketDriftClientAccountSubscriber_1 = require("./webSocketDriftClientAccountSubscriber");
const config_1 = require("../config");
const pda_1 = require("../addresses/pda");
const grpcAccountSubscriber_1 = require("./grpcAccountSubscriber");
const oracleId_1 = require("../oracles/oracleId");
class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscriber_1.WebSocketDriftClientAccountSubscriber {
constructor(grpcConfigs, program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, delistedMarketSetting, resubOpts) {
super(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, delistedMarketSetting, resubOpts);
this.grpcConfigs = grpcConfigs;
}
async subscribe() {
if (this.isSubscribed) {
return true;
}
if (this.isSubscribing) {
return await this.subscriptionPromise;
}
this.isSubscribing = true;
this.subscriptionPromise = new Promise((res) => {
this.subscriptionPromiseResolver = res;
});
if (this.shouldFindAllMarketsAndOracles) {
const { perpMarketIndexes, perpMarketAccounts, spotMarketIndexes, spotMarketAccounts, oracleInfos, } = await (0, config_1.findAllMarketAndOracles)(this.program);
this.perpMarketIndexes = perpMarketIndexes;
this.spotMarketIndexes = spotMarketIndexes;
this.oracleInfos = oracleInfos;
// front run and set the initial data here to save extra gma call in set initial data
this.initialPerpMarketAccountData = new Map(perpMarketAccounts.map((market) => [market.marketIndex, market]));
this.initialSpotMarketAccountData = new Map(spotMarketAccounts.map((market) => [market.marketIndex, market]));
}
const statePublicKey = await (0, pda_1.getDriftStateAccountPublicKey)(this.program.programId);
// create and activate main state account subscription
this.stateAccountSubscriber =
await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'state', this.program, statePublicKey, undefined, undefined);
await this.stateAccountSubscriber.subscribe((data) => {
this.eventEmitter.emit('stateAccountUpdate', data);
this.eventEmitter.emit('update');
});
// set initial data to avoid spamming getAccountInfo calls in webSocketAccountSubscriber
await this.setInitialData();
await Promise.all([
// subscribe to market accounts
this.subscribeToPerpMarketAccounts(),
// subscribe to spot market accounts
this.subscribeToSpotMarketAccounts(),
// subscribe to oracles
this.subscribeToOracles(),
]);
this.eventEmitter.emit('update');
await this.handleDelistedMarkets();
await Promise.all([this.setPerpOracleMap(), this.setSpotOracleMap()]);
this.subscriptionPromiseResolver(true);
this.isSubscribing = false;
this.isSubscribed = true;
// delete initial data
this.removeInitialData();
return true;
}
async subscribeToSpotMarketAccount(marketIndex) {
const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'spotMarket', this.program, marketPublicKey, undefined, this.resubOpts);
accountSubscriber.setData(this.initialSpotMarketAccountData.get(marketIndex));
await accountSubscriber.subscribe((data) => {
this.eventEmitter.emit('spotMarketAccountUpdate', data);
this.eventEmitter.emit('update');
});
this.spotMarketAccountSubscribers.set(marketIndex, accountSubscriber);
return true;
}
async subscribeToPerpMarketAccount(marketIndex) {
const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts);
accountSubscriber.setData(this.initialPerpMarketAccountData.get(marketIndex));
await accountSubscriber.subscribe((data) => {
this.eventEmitter.emit('perpMarketAccountUpdate', data);
this.eventEmitter.emit('update');
});
this.perpMarketAccountSubscribers.set(marketIndex, accountSubscriber);
return true;
}
async subscribeToOracle(oracleInfo) {
const oracleId = (0, oracleId_1.getOracleId)(oracleInfo.publicKey, oracleInfo.source);
const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'oracle', this.program, oracleInfo.publicKey, (buffer) => {
return client.getOraclePriceDataFromBuffer(buffer);
}, this.resubOpts);
accountSubscriber.setData(this.initialOraclePriceData.get(oracleId));
await accountSubscriber.subscribe((data) => {
this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, oracleInfo.source, data);
this.eventEmitter.emit('update');
});
this.oracleSubscribers.set(oracleId, accountSubscriber);
return true;
}
}
exports.gprcDriftClientAccountSubscriber = gprcDriftClientAccountSubscriber;