@drift-labs/sdk
Version:
SDK for Drift Protocol
118 lines (117 loc) • 5.83 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SignedMsgUserOrdersAccountSubscriber = void 0;
const memcmp_1 = require("../memcmp");
const webSocketProgramAccountSubscriber_1 = require("../accounts/webSocketProgramAccountSubscriber");
const events_1 = require("events");
class SignedMsgUserOrdersAccountSubscriber {
constructor({ driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }) {
this.signedMsgUserOrderAccounts = new Map();
this.commitment = commitment !== null && commitment !== void 0 ? commitment : 'confirmed';
this.resubOpts = resubOpts;
this.driftClient = driftClient;
this.decodeFn =
decodeFn !== null && decodeFn !== void 0 ? decodeFn : this.driftClient.program.account.signedMsgUserOrders.coder.accounts.decodeUnchecked.bind(this.driftClient.program.account.signedMsgUserOrders.coder.accounts);
this.resyncIntervalMs = resyncIntervalMs;
this.eventEmitter = new events_1.EventEmitter();
this.resubOpts = resubOpts;
}
async subscribe() {
if (!this.subscriber) {
const filters = [(0, memcmp_1.getSignedMsgUserOrdersFilter)()];
this.subscriber =
new webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber('SingedMsgUserOrdersAccountMap', 'SignedMsgUserOrders', this.driftClient.program, this.decodeFn, {
filters,
commitment: this.commitment,
}, this.resubOpts);
}
await this.subscriber.subscribe((_accountId, account, context) => {
this.tryUpdateSignedMsgUserOrdersAccount(account, 'decoded', context.slot);
});
await this.fetch();
if (this.resyncIntervalMs) {
const recursiveResync = () => {
this.resyncTimeoutId = setTimeout(() => {
this.fetch()
.catch((e) => {
console.error('Failed to resync in OrderSubscriber');
console.log(e);
})
.finally(() => {
if (!this.resyncTimeoutId)
return;
recursiveResync();
});
}, this.resyncIntervalMs);
};
recursiveResync();
}
}
async fetch() {
if (this.fetchPromise) {
return this.fetchPromise;
}
this.fetchPromise = new Promise((resolver) => {
this.fetchPromiseResolver = resolver;
});
const skipEventEmitting = this.signedMsgUserOrderAccounts.size === 0;
try {
const rpcResponseAndContext = await this.driftClient.connection.getProgramAccounts(this.driftClient.program.programId, {
commitment: this.commitment,
filters: [(0, memcmp_1.getSignedMsgUserOrdersFilter)()],
encoding: 'base64',
withContext: true,
});
const slot = rpcResponseAndContext.context.slot;
for (const programAccount of rpcResponseAndContext.value) {
this.tryUpdateSignedMsgUserOrdersAccount(programAccount.account.data, 'buffer', slot, skipEventEmitting);
await new Promise((resolve) => setTimeout(resolve, 0));
}
}
catch (e) {
console.error(e);
}
finally {
this.fetchPromiseResolver();
this.fetchPromise = undefined;
}
}
tryUpdateSignedMsgUserOrdersAccount(data, dataType, slot, skipEventEmitting = false) {
var _a;
if (!this.mostRecentSlot || slot > this.mostRecentSlot) {
this.mostRecentSlot = slot;
}
const signedMsgUserOrdersAccount = dataType === 'buffer'
? this.decodeFn('SignedMsgUserOrders', data)
: data;
const key = signedMsgUserOrdersAccount.authorityPubkey.toBase58();
const slotAndSignedMsgUserOrdersAccount = this.signedMsgUserOrderAccounts.get(key);
if (!slotAndSignedMsgUserOrdersAccount ||
slotAndSignedMsgUserOrdersAccount.slot <= slot) {
if (!skipEventEmitting) {
this.eventEmitter.emit('onAccountUpdate', signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => signedMsgOrderId.orderId !== 0), signedMsgUserOrdersAccount.authorityPubkey, slot);
}
const existingSignedMsgOrderIds = (_a = slotAndSignedMsgUserOrdersAccount === null || slotAndSignedMsgUserOrdersAccount === void 0 ? void 0 : slotAndSignedMsgUserOrdersAccount.signedMsgUserOrdersAccount.signedMsgOrderData.map((signedMsgOrderId) => signedMsgOrderId.orderId)) !== null && _a !== void 0 ? _a : [];
const newSignedMsgOrderIds = signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => !existingSignedMsgOrderIds.includes(signedMsgOrderId.orderId) &&
signedMsgOrderId.orderId !== 0);
if (newSignedMsgOrderIds.length > 0 && !skipEventEmitting) {
this.eventEmitter.emit('newSignedMsgOrderIds', newSignedMsgOrderIds, signedMsgUserOrdersAccount.authorityPubkey, slot);
}
this.signedMsgUserOrderAccounts.set(key, {
slot,
signedMsgUserOrdersAccount,
});
}
}
async unsubscribe() {
if (!this.subscriber)
return;
await this.subscriber.unsubscribe();
this.subscriber = undefined;
if (this.resyncTimeoutId !== undefined) {
clearTimeout(this.resyncTimeoutId);
this.resyncTimeoutId = undefined;
}
}
}
exports.SignedMsgUserOrdersAccountSubscriber = SignedMsgUserOrdersAccountSubscriber;