@drift-labs/sdk
Version:
SDK for Drift Protocol
97 lines (96 loc) • 3.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketLogProvider = void 0;
const events_1 = require("events");
class WebSocketLogProvider {
constructor(connection, address, commitment, resubTimeoutMs) {
this.connection = connection;
this.address = address;
this.commitment = commitment;
this.resubTimeoutMs = resubTimeoutMs;
this.isUnsubscribing = false;
this.externalUnsubscribe = false;
this.receivingData = false;
this.reconnectAttempts = 0;
if (this.resubTimeoutMs) {
this.eventEmitter = new events_1.EventEmitter();
}
}
async subscribe(callback) {
if (this.subscriptionId != null) {
return true;
}
this.callback = callback;
try {
this.setSubscription(callback);
}
catch (error) {
// Sometimes ws connection isn't ready, give it a few secs
setTimeout(() => this.setSubscription(callback), 2000);
}
if (this.resubTimeoutMs) {
this.setTimeout();
}
return true;
}
setSubscription(callback) {
this.subscriptionId = this.connection.onLogs(this.address, (logs, ctx) => {
if (this.resubTimeoutMs && !this.isUnsubscribing) {
this.receivingData = true;
clearTimeout(this.timeoutId);
this.setTimeout();
if (this.reconnectAttempts > 0) {
console.log('Resetting reconnect attempts to 0');
}
this.reconnectAttempts = 0;
}
if (logs.err !== null) {
return;
}
callback(logs.signature, ctx.slot, logs.logs, undefined, undefined);
}, this.commitment);
}
isSubscribed() {
return this.subscriptionId != null;
}
async unsubscribe(external = false) {
this.isUnsubscribing = true;
this.externalUnsubscribe = external;
clearTimeout(this.timeoutId);
this.timeoutId = undefined;
if (this.subscriptionId != null) {
try {
await this.connection.removeOnLogsListener(this.subscriptionId);
this.subscriptionId = undefined;
this.isUnsubscribing = false;
return true;
}
catch (err) {
console.log('Error unsubscribing from logs: ', err);
this.isUnsubscribing = false;
return false;
}
}
else {
this.isUnsubscribing = false;
return true;
}
}
setTimeout() {
this.timeoutId = setTimeout(async () => {
if (this.isUnsubscribing || this.externalUnsubscribe) {
// If we are in the process of unsubscribing, do not attempt to resubscribe
return;
}
if (this.receivingData) {
console.log(`webSocketLogProvider: No log data in ${this.resubTimeoutMs}ms, resubscribing on attempt ${this.reconnectAttempts + 1}`);
await this.unsubscribe();
this.receivingData = false;
this.reconnectAttempts++;
this.eventEmitter.emit('reconnect', this.reconnectAttempts);
this.subscribe(this.callback);
}
}, this.resubTimeoutMs);
}
}
exports.WebSocketLogProvider = WebSocketLogProvider;