UNPKG

bitmart-api

Version:

Complete & robust Node.js SDK for BitMart's REST APIs and WebSockets, with TypeScript declarations.

157 lines (156 loc) 7.38 kB
import EventEmitter from 'events'; import WebSocket from 'isomorphic-ws'; import { WebsocketClientOptions, WSClientConfigurableOptions } from '../types/websockets/client.js'; import { DefaultLogger } from './logger.js'; import { MessageEventLike } from './requestUtils.js'; import { WsStore } from './websocket/WsStore.js'; interface WSClientEventMap<WsKey extends string> { /** Connection opened. If this connection was previously opened and reconnected, expect the reconnected event instead */ open: (evt: { wsKey: WsKey; event: any; }) => void; /** Reconnecting a dropped connection */ reconnect: (evt: { wsKey: WsKey; event: any; }) => void; /** Successfully reconnected a connection that dropped */ reconnected: (evt: { wsKey: WsKey; event: any; }) => void; /** Connection closed */ close: (evt: { wsKey: WsKey; event: any; }) => void; /** Received reply to websocket command (e.g. after subscribing to topics) */ response: (response: any & { wsKey: WsKey; }) => void; /** Received data for topic */ update: (response: any & { wsKey: WsKey; }) => void; /** Exception from ws client OR custom listeners (e.g. if you throw inside your event handler) */ exception: (response: any & { wsKey: WsKey; }) => void; /** Confirmation that a connection successfully authenticated */ authenticated: (event: { wsKey: WsKey; event: any; }) => void; } export interface EmittableEvent<TEvent = any> { eventType: 'response' | 'update' | 'exception' | 'authenticated'; event: TEvent; } export interface BaseWebsocketClient<TWSMarket extends string, TWSKey extends string, TWSTopic = any> { on<U extends keyof WSClientEventMap<TWSKey>>(event: U, listener: WSClientEventMap<TWSKey>[U]): this; emit<U extends keyof WSClientEventMap<TWSKey>>(event: U, ...args: Parameters<WSClientEventMap<TWSKey>[U]>): boolean; } export declare abstract class BaseWebsocketClient<TWSMarket extends string, TWSKey extends string, /** * The "topic" being subscribed to, not the event sent to subscribe to one or more topics */ TWSTopic extends string | object> extends EventEmitter { private wsStore; protected logger: typeof DefaultLogger; protected options: WebsocketClientOptions; constructor(options?: WSClientConfigurableOptions, logger?: typeof DefaultLogger); protected abstract getWsKeyForMarket(market: TWSMarket, isPrivate?: boolean): TWSKey; protected abstract sendPingEvent(wsKey: TWSKey, ws: WebSocket): void; protected abstract isWsPong(data: any): boolean; protected abstract getWsAuthRequestEvent(wsKey: TWSKey): Promise<object>; protected abstract getWsMarketForWsKey(key: TWSKey): TWSMarket; protected abstract isPrivateChannel(subscribeEvent: TWSTopic): boolean; protected abstract getPrivateWSKeys(): TWSKey[]; protected abstract getWsUrl(wsKey: TWSKey): string; protected abstract getMaxTopicsPerSubscribeEvent(wsKey: TWSKey): number | null; /** * Returns a list of string events that can be individually sent upstream to complete subscribing to these topics */ protected abstract getWsSubscribeEventsForTopics(topics: TWSTopic[], wsKey: TWSKey): string[]; /** * Returns a list of string events that can be individually sent upstream to complete unsubscribing to these topics */ protected abstract getWsUnsubscribeEventsForTopics(topics: TWSTopic[], wsKey: TWSKey): string[]; /** * Abstraction called to sort ws events into emittable event types (response to a request, data update, etc) */ protected abstract resolveEmittableEvents(event: MessageEventLike): EmittableEvent[]; /** * Request connection of all dependent (public & private) websockets, instead of waiting for automatic connection by library */ abstract connectAll(): Promise<WebSocket | undefined>[]; protected isPrivateWsKey(wsKey: TWSKey): boolean; /** * Subscribe to one or more topics on a WS connection (identified by WS Key). * * - Topics are automatically cached * - Connections are automatically opened, if not yet connected * - Authentication is automatically handled * - Topics are automatically resubscribed to, if something happens to the connection, unless you call unsubsribeTopicsForWsKey(topics, key). * * @param wsTopics array of topics to subscribe to * @param wsKey ws key referring to the ws connection these topics should be subscribed on */ subscribeTopicsForWsKey(wsTopics: TWSTopic[], wsKey: TWSKey): false | Promise<WebSocket | undefined> | undefined; unsubscribeTopicsForWsKey(wsTopics: TWSTopic[], wsKey: TWSKey): void; /** * Subscribe to topics & track/persist them. They will be automatically resubscribed to if the connection drops/reconnects. * @param wsTopics topic or list of topics * @param isPrivate optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet) */ subscribe(wsTopics: TWSTopic[] | TWSTopic, market: TWSMarket, isPrivate?: boolean): void; /** * Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects. * @param wsTopics topic or list of topics * @param isPrivateTopic optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet) */ unsubscribe(wsTopics: TWSTopic[] | TWSTopic, market: TWSMarket, isPrivateTopic?: boolean): void; /** Get the WsStore that tracks websockets & topics */ getWsStore(): WsStore<TWSKey, TWSTopic>; close(wsKey: TWSKey, force?: boolean): void; closeAll(force?: boolean): void; isConnected(wsKey: TWSKey): boolean; /** * Request connection to a specific websocket, instead of waiting for automatic connection. */ protected connect(wsKey: TWSKey): Promise<WebSocket | undefined>; private parseWsError; /** Get a signature, build the auth request and send it */ private sendAuthRequest; private reconnectWithDelay; private ping; private clearTimers; private clearPingTimer; private clearPongTimer; /** * Simply builds and sends subscribe events for a list of topics for a ws key * * @private Use the `subscribe(topics)` or `subscribeTopicsForWsKey(topics, wsKey)` method to subscribe to topics. Send WS message to subscribe to topics. */ private requestSubscribeTopics; /** * Simply builds and sends unsubscribe events for a list of topics for a ws key * * @private Use the `unsubscribe(topics)` method to unsubscribe from topics. Send WS message to unsubscribe from topics. */ private requestUnsubscribeTopics; /** * Try sending a string event on a WS connection (identified by the WS Key) */ tryWsSend(wsKey: TWSKey, wsMessage: string): void; private connectToWsUrl; private onWsOpen; /** Handle subscription to private topics _after_ authentication successfully completes asynchronously */ private onWsAuthenticated; private onWsMessage; private onWsClose; private getWs; private setWsState; } export {};