@drift-labs/sdk
Version:
SDK for Drift Protocol
122 lines (121 loc) • 4.61 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventsServerLogProvider = void 0;
const events_1 = require("events");
// browser support
let WebSocketImpl;
if (typeof window !== 'undefined' && window.WebSocket) {
WebSocketImpl = window.WebSocket;
}
else {
WebSocketImpl = require('ws');
}
const EVENT_SERVER_HEARTBEAT_INTERVAL_MS = 5000;
const ALLOWED_MISSED_HEARTBEATS = 3;
class EventsServerLogProvider {
constructor(url, eventTypes, userAccount) {
this.url = url;
this.eventTypes = eventTypes;
this.userAccount = userAccount;
this.isUnsubscribing = false;
this.externalUnsubscribe = false;
this.lastHeartbeat = 0;
this.reconnectAttempts = 0;
this.eventEmitter = new events_1.EventEmitter();
}
isSubscribed() {
return this.ws !== undefined;
}
async subscribe(callback) {
if (this.ws !== undefined) {
return true;
}
this.ws = new WebSocketImpl(this.url);
this.callback = callback;
this.ws.addEventListener('open', () => {
for (const channel of this.eventTypes) {
const subscribeMessage = {
type: 'subscribe',
channel: channel,
};
if (this.userAccount) {
subscribeMessage['user'] = this.userAccount;
}
this.ws.send(JSON.stringify(subscribeMessage));
}
this.reconnectAttempts = 0;
});
this.ws.addEventListener('message', (data) => {
try {
if (!this.isUnsubscribing) {
clearTimeout(this.timeoutId);
this.setTimeout();
if (this.reconnectAttempts > 0) {
console.log('eventsServerLogProvider: Resetting reconnect attempts to 0');
}
this.reconnectAttempts = 0;
}
const parsedData = JSON.parse(data.data.toString());
if (parsedData.channel === 'heartbeat') {
this.lastHeartbeat = Date.now();
return;
}
if (parsedData.message !== undefined) {
return;
}
const event = JSON.parse(parsedData.data);
this.callback(event.txSig, event.slot, [
'Program dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH invoke [1]',
event.rawLog,
'Program dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH success',
], undefined, event.txSigIndex);
}
catch (error) {
console.error('Error parsing message:', error);
}
});
this.ws.addEventListener('close', () => {
console.log('eventsServerLogProvider: WebSocket closed');
});
this.ws.addEventListener('error', (error) => {
console.error('eventsServerLogProvider: WebSocket error:', error);
});
this.setTimeout();
return true;
}
async unsubscribe(external = false) {
this.isUnsubscribing = true;
this.externalUnsubscribe = external;
if (this.timeoutId) {
clearInterval(this.timeoutId);
this.timeoutId = undefined;
}
if (this.ws !== undefined) {
this.ws.close();
this.ws = undefined;
return true;
}
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;
}
const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeat;
if (timeSinceLastHeartbeat >
EVENT_SERVER_HEARTBEAT_INTERVAL_MS * ALLOWED_MISSED_HEARTBEATS) {
console.log(`eventServerLogProvider: No heartbeat in ${timeSinceLastHeartbeat}ms, resubscribing on attempt ${this.reconnectAttempts + 1}`);
await this.unsubscribe();
this.reconnectAttempts++;
this.eventEmitter.emit('reconnect', this.reconnectAttempts);
this.subscribe(this.callback);
}
}, EVENT_SERVER_HEARTBEAT_INTERVAL_MS * 2);
}
}
exports.EventsServerLogProvider = EventsServerLogProvider;