@drift-labs/sdk
Version:
SDK for Drift Protocol
103 lines (102 loc) • 3.77 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PollingUserAccountSubscriber = void 0;
const types_1 = require("./types");
const events_1 = require("events");
class PollingUserAccountSubscriber {
constructor(connection, userAccountPublicKey, accountLoader, decode) {
this.isSubscribed = false;
this.connection = connection;
this.accountLoader = accountLoader;
this.eventEmitter = new events_1.EventEmitter();
this.userAccountPublicKey = userAccountPublicKey;
this.decode = decode;
}
async subscribe(userAccount) {
if (this.isSubscribed) {
return true;
}
if (userAccount) {
this.user = { data: userAccount, slot: undefined };
}
await this.addToAccountLoader();
await this.fetchIfUnloaded();
if (this.doesAccountExist()) {
this.eventEmitter.emit('update');
}
this.isSubscribed = true;
return true;
}
async addToAccountLoader() {
if (this.callbackId) {
return;
}
this.callbackId = await this.accountLoader.addAccount(this.userAccountPublicKey, (buffer, slot) => {
if (!buffer) {
return;
}
if (this.user && this.user.slot > slot) {
return;
}
const account = this.decode('User', buffer);
this.user = { data: account, slot };
this.eventEmitter.emit('userAccountUpdate', account);
this.eventEmitter.emit('update');
});
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
this.eventEmitter.emit('error', error);
});
}
async fetchIfUnloaded() {
if (this.user === undefined) {
await this.fetch();
}
}
async fetch() {
var _a, _b;
try {
const dataAndContext = await this.connection.getAccountInfoAndContext(this.userAccountPublicKey, this.accountLoader.commitment);
if (dataAndContext.context.slot > ((_b = (_a = this.user) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0)) {
this.user = {
data: this.decode('User', dataAndContext.value.data),
slot: dataAndContext.context.slot,
};
}
}
catch (e) {
console.log(`PollingUserAccountSubscriber.fetch() UserAccount does not exist: ${e.message}-${e.stack}`);
}
}
doesAccountExist() {
return this.user !== undefined;
}
async unsubscribe() {
if (!this.isSubscribed) {
return;
}
this.accountLoader.removeAccount(this.userAccountPublicKey, this.callbackId);
this.callbackId = undefined;
this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
this.errorCallbackId = undefined;
this.isSubscribed = false;
}
assertIsSubscribed() {
if (!this.isSubscribed) {
throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
}
}
getUserAccountAndSlot() {
if (!this.doesAccountExist()) {
throw new types_1.NotSubscribedError('You must call `subscribe` or `fetch` before using this function');
}
return this.user;
}
updateData(userAccount, slot) {
if (!this.user || this.user.slot < slot) {
this.user = { data: userAccount, slot };
this.eventEmitter.emit('userAccountUpdate', userAccount);
this.eventEmitter.emit('update');
}
}
}
exports.PollingUserAccountSubscriber = PollingUserAccountSubscriber;