okx-api 0.0.6 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +46 -10
  2. package/lib/index.d.ts +2 -1
  3. package/lib/index.js +2 -2
  4. package/lib/index.js.map +1 -1
  5. package/lib/rest-client.d.ts +3 -4
  6. package/lib/rest-client.js +1 -1
  7. package/lib/rest-client.js.map +1 -1
  8. package/lib/types/index.d.ts +2 -0
  9. package/lib/types/index.js +2 -0
  10. package/lib/types/index.js.map +1 -1
  11. package/lib/types/rest/client.d.ts +5 -0
  12. package/lib/types/rest/client.js +3 -0
  13. package/lib/types/rest/client.js.map +1 -0
  14. package/lib/types/rest/index.d.ts +1 -0
  15. package/lib/types/rest/index.js +1 -0
  16. package/lib/types/rest/index.js.map +1 -1
  17. package/lib/types/shared.d.ts +6 -0
  18. package/lib/types/shared.js +3 -0
  19. package/lib/types/shared.js.map +1 -0
  20. package/lib/types/websockets/client.d.ts +22 -0
  21. package/lib/types/websockets/client.js +3 -0
  22. package/lib/types/websockets/client.js.map +1 -0
  23. package/lib/types/websockets/event.d.ts +21 -0
  24. package/lib/types/websockets/event.js +3 -0
  25. package/lib/types/websockets/event.js.map +1 -0
  26. package/lib/types/websockets/index.d.ts +3 -0
  27. package/lib/types/websockets/index.js +20 -0
  28. package/lib/types/websockets/index.js.map +1 -0
  29. package/lib/types/websockets/request.d.ts +108 -0
  30. package/lib/types/websockets/request.js +3 -0
  31. package/lib/types/websockets/request.js.map +1 -0
  32. package/lib/util/BaseRestClient.d.ts +2 -7
  33. package/lib/util/BaseRestClient.js +6 -7
  34. package/lib/util/BaseRestClient.js.map +1 -1
  35. package/lib/util/WsStore.d.ts +66 -0
  36. package/lib/util/WsStore.js +168 -0
  37. package/lib/util/WsStore.js.map +1 -0
  38. package/lib/util/index.d.ts +4 -0
  39. package/lib/util/index.js +21 -0
  40. package/lib/util/index.js.map +1 -0
  41. package/lib/util/logger.d.ts +9 -0
  42. package/lib/util/logger.js +24 -0
  43. package/lib/util/logger.js.map +1 -0
  44. package/lib/util/requestUtils.d.ts +2 -12
  45. package/lib/util/requestUtils.js +3 -3
  46. package/lib/util/requestUtils.js.map +1 -1
  47. package/lib/util/typeGuards.d.ts +13 -0
  48. package/lib/util/typeGuards.js +46 -1
  49. package/lib/util/typeGuards.js.map +1 -1
  50. package/lib/util/websocket-util.d.ts +26 -0
  51. package/lib/util/websocket-util.js +131 -0
  52. package/lib/util/websocket-util.js.map +1 -0
  53. package/lib/websocket-client.d.ts +99 -0
  54. package/lib/websocket-client.js +467 -0
  55. package/lib/websocket-client.js.map +1 -0
  56. package/package.json +1 -1
@@ -0,0 +1,99 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import WebSocket from 'isomorphic-ws';
4
+ import { WsChannelSubUnSubRequestArg, WSClientConfigurableOptions, WsDataEvent, WsEvent } from './types';
5
+ import { DefaultLogger, WsStore } from './util';
6
+ import { WsKey } from './util/websocket-util';
7
+ export declare type WsClientEvent = 'open' | 'update' | 'close' | 'error' | 'reconnect' | 'reconnected' | 'response';
8
+ declare type WsKeyObject = {
9
+ wsKey: WsKey;
10
+ };
11
+ interface WebsocketClientEvents {
12
+ /** Connection opened. If this connection was previously opened and reconnected, expect the reconnected event instead */
13
+ open: (evt: {
14
+ event: any;
15
+ } & WsKeyObject) => void;
16
+ /** Reconnecting a dropped connection */
17
+ reconnect: (evt: {
18
+ event: any;
19
+ } & WsKeyObject) => void;
20
+ /** Successfully reconnected a connection that dropped */
21
+ reconnected: (evt: {
22
+ event: any;
23
+ } & WsKeyObject) => void;
24
+ /** Connection closed */
25
+ close: (evt: {
26
+ event: any;
27
+ } & WsKeyObject) => void;
28
+ /** Received reply to websocket command (e.g. after subscribing to topics or authenticating) */
29
+ response: (response: WsEvent & WsKeyObject) => void;
30
+ /** Received data for a topic/channel */
31
+ update: (response: WsDataEvent & WsKeyObject) => void;
32
+ /** Exception from ws client OR custom listeners */
33
+ error: (response: any) => void;
34
+ }
35
+ export declare interface WebsocketClient {
36
+ on<U extends keyof WebsocketClientEvents>(event: U, listener: WebsocketClientEvents[U]): this;
37
+ emit<U extends keyof WebsocketClientEvents>(event: U, ...args: Parameters<WebsocketClientEvents[U]>): boolean;
38
+ }
39
+ export declare class WebsocketClient extends EventEmitter {
40
+ private logger;
41
+ private options;
42
+ private wsStore;
43
+ constructor(options: WSClientConfigurableOptions, logger?: typeof DefaultLogger);
44
+ /**
45
+ * Subscribe to topics & track/persist them. They will be automatically resubscribed to if the connection drops/reconnects.
46
+ * @param wsEvents topic or list of topics
47
+ * @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)
48
+ */
49
+ subscribe(wsEvents: WsChannelSubUnSubRequestArg[] | WsChannelSubUnSubRequestArg, isPrivateTopic?: boolean): void;
50
+ /**
51
+ * Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects.
52
+ * @param wsTopics topic or list of topics
53
+ * @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)
54
+ */
55
+ unsubscribe(wsTopics: WsChannelSubUnSubRequestArg[] | WsChannelSubUnSubRequestArg, isPrivateTopic?: boolean): void;
56
+ /** Get the WsStore that tracks websocket & topic state */
57
+ getWsStore(): WsStore<WsChannelSubUnSubRequestArg>;
58
+ close(wsKey: WsKey, force?: boolean): void;
59
+ closeAll(force?: boolean): void;
60
+ /**
61
+ * Request connection of all dependent (public & private) websockets, instead of waiting for automatic connection by library
62
+ */
63
+ connectAll(): Promise<WebSocket | undefined>[];
64
+ connectPublic(): Promise<WebSocket | undefined>;
65
+ connectPrivate(): Promise<WebSocket | undefined>;
66
+ private connect;
67
+ private parseWsError;
68
+ /**
69
+ * Return params required to make authorized request
70
+ */
71
+ private getWsAuthRequest;
72
+ private getWsAuthSignature;
73
+ private sendAuthRequest;
74
+ private reconnectWithDelay;
75
+ private ping;
76
+ /**
77
+ * Closes a connection, if it's even open. If open, this will trigger a reconnect asynchronously.
78
+ * If closed, trigger a reconnect immediately
79
+ */
80
+ private executeReconnectableClose;
81
+ private clearTimers;
82
+ private clearPingTimer;
83
+ private clearPongTimer;
84
+ private clearReconnectTimer;
85
+ /**
86
+ * @private Use the `subscribe(topics)` method to subscribe to topics. Send WS message to subscribe to topics.
87
+ */
88
+ private requestSubscribeTopics;
89
+ /**
90
+ * @private Use the `unsubscribe(topics)` method to unsubscribe from topics. Send WS message to unsubscribe from topics.
91
+ */
92
+ private requestUnsubscribeTopics;
93
+ tryWsSend(wsKey: WsKey, wsMessage: string): void;
94
+ private connectToWsUrl;
95
+ private onWsOpen;
96
+ private onWsMessage;
97
+ private onWsClose;
98
+ }
99
+ export {};
@@ -0,0 +1,467 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.WebsocketClient = void 0;
16
+ const events_1 = require("events");
17
+ const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
18
+ const node_support_1 = require("./util/node-support");
19
+ const util_1 = require("./util");
20
+ const websocket_util_1 = require("./util/websocket-util");
21
+ const loggerCategory = { category: 'okx-ws' };
22
+ class WebsocketClient extends events_1.EventEmitter {
23
+ constructor(options, logger) {
24
+ super();
25
+ this.logger = logger || util_1.DefaultLogger;
26
+ this.wsStore = new util_1.WsStore(this.logger);
27
+ this.options = Object.assign({ market: 'prod', pongTimeout: 2000, pingInterval: 10000, reconnectTimeout: 500 }, options);
28
+ // add default error handling so this doesn't crash node (if the user didn't set a handler)
29
+ this.on('error', () => { });
30
+ }
31
+ /**
32
+ * Subscribe to topics & track/persist them. They will be automatically resubscribed to if the connection drops/reconnects.
33
+ * @param wsEvents topic or list of topics
34
+ * @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)
35
+ */
36
+ subscribe(wsEvents, isPrivateTopic) {
37
+ const wsEventArgs = Array.isArray(wsEvents) ? wsEvents : [wsEvents];
38
+ wsEventArgs.forEach((wsEventArg) => {
39
+ const wsKey = (0, util_1.getWsKeyForTopicChannel)(this.options.market, wsEventArg.channel, isPrivateTopic);
40
+ // Persist topic for reconnects
41
+ this.wsStore.addComplexTopic(wsKey, wsEventArg);
42
+ // if connected, send subscription request
43
+ if (this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.CONNECTED)) {
44
+ return this.requestSubscribeTopics(wsKey, [wsEventArg]);
45
+ }
46
+ // start connection process if it hasn't yet begun. Topics are automatically subscribed to on-connect
47
+ if (!this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.CONNECTING) &&
48
+ !this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.RECONNECTING)) {
49
+ return this.connect(wsKey);
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects.
55
+ * @param wsTopics topic or list of topics
56
+ * @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)
57
+ */
58
+ unsubscribe(wsTopics, isPrivateTopic) {
59
+ const wsEventArgs = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
60
+ wsEventArgs.forEach((wsEventArg) => {
61
+ const wsKey = (0, util_1.getWsKeyForTopicChannel)(this.options.market, wsEventArg.channel, isPrivateTopic);
62
+ // Remove topic from persistence for reconnects
63
+ this.wsStore.deleteComplexTopic(wsKey, wsEventArg);
64
+ // unsubscribe request only necessary if active connection exists
65
+ if (this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.CONNECTED)) {
66
+ this.requestUnsubscribeTopics(wsKey, [wsEventArg]);
67
+ }
68
+ });
69
+ }
70
+ /** Get the WsStore that tracks websocket & topic state */
71
+ getWsStore() {
72
+ return this.wsStore;
73
+ }
74
+ close(wsKey, force) {
75
+ this.logger.info('Closing connection', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
76
+ this.wsStore.setConnectionState(wsKey, util_1.WsConnectionStateEnum.CLOSING);
77
+ this.clearTimers(wsKey);
78
+ const ws = this.wsStore.getWs(wsKey);
79
+ ws === null || ws === void 0 ? void 0 : ws.close();
80
+ if (force) {
81
+ ws === null || ws === void 0 ? void 0 : ws.terminate();
82
+ }
83
+ }
84
+ closeAll(force) {
85
+ const keys = this.wsStore.getKeys();
86
+ this.logger.info(`Closing all ws connections: ${keys}`);
87
+ keys.forEach((key) => {
88
+ this.close(key, force);
89
+ });
90
+ }
91
+ /**
92
+ * Request connection of all dependent (public & private) websockets, instead of waiting for automatic connection by library
93
+ */
94
+ connectAll() {
95
+ return [this.connectPublic(), this.connectPrivate()];
96
+ }
97
+ connectPublic() {
98
+ const isPrivate = false;
99
+ const wsKey = (0, websocket_util_1.getWsKeyForMarket)(this.options.market, isPrivate);
100
+ return this.connect(util_1.WS_KEY_MAP[wsKey]);
101
+ }
102
+ connectPrivate() {
103
+ const isPrivate = true;
104
+ const wsKey = (0, websocket_util_1.getWsKeyForMarket)(this.options.market, isPrivate);
105
+ return this.connect(util_1.WS_KEY_MAP[wsKey]);
106
+ }
107
+ connect(wsKey) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ try {
110
+ if (this.wsStore.isWsOpen(wsKey)) {
111
+ this.logger.error('Refused to connect to ws with existing active connection', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
112
+ return this.wsStore.getWs(wsKey);
113
+ }
114
+ if (this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.CONNECTING)) {
115
+ this.logger.error('Refused to connect to ws, connection attempt already active', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
116
+ return;
117
+ }
118
+ if (!this.wsStore.getConnectionState(wsKey) ||
119
+ this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.INITIAL)) {
120
+ this.wsStore.setConnectionState(wsKey, util_1.WsConnectionStateEnum.CONNECTING);
121
+ }
122
+ const url = (0, websocket_util_1.getWsUrlForWsKey)(wsKey, this.options);
123
+ const ws = this.connectToWsUrl(url, wsKey);
124
+ return this.wsStore.setWs(wsKey, ws);
125
+ }
126
+ catch (err) {
127
+ this.parseWsError('Connection failed', err, wsKey);
128
+ this.reconnectWithDelay(wsKey, this.options.reconnectTimeout);
129
+ }
130
+ });
131
+ }
132
+ parseWsError(context, error, wsKey) {
133
+ if (!error.message) {
134
+ this.logger.error(`${context} due to unexpected error: `, error);
135
+ this.emit('error', error);
136
+ return;
137
+ }
138
+ switch (error.message) {
139
+ default:
140
+ if (this.wsStore.getConnectionState(wsKey) !==
141
+ util_1.WsConnectionStateEnum.CLOSING) {
142
+ this.logger.error(`${context} due to unexpected response error: "${(error === null || error === void 0 ? void 0 : error.msg) || (error === null || error === void 0 ? void 0 : error.message) || error}"`, Object.assign(Object.assign({}, loggerCategory), { wsKey, error }));
143
+ this.executeReconnectableClose(wsKey, 'unhandled onWsError');
144
+ }
145
+ else {
146
+ this.logger.info(`${wsKey} socket forcefully closed. Will not reconnect.`);
147
+ }
148
+ break;
149
+ }
150
+ this.emit('error', error);
151
+ }
152
+ /**
153
+ * Return params required to make authorized request
154
+ */
155
+ getWsAuthRequest(wsKey) {
156
+ return __awaiter(this, void 0, void 0, function* () {
157
+ const isPublicWsKey = util_1.PUBLIC_WS_KEYS.includes(wsKey);
158
+ const accounts = this.options.accounts;
159
+ const hasAccountsToAuth = !!(accounts === null || accounts === void 0 ? void 0 : accounts.length);
160
+ if (isPublicWsKey || !accounts || !hasAccountsToAuth) {
161
+ this.logger.debug('Starting public only websocket client.', Object.assign(Object.assign({}, loggerCategory), { wsKey,
162
+ isPublicWsKey,
163
+ hasAccountsToAuth }));
164
+ return;
165
+ }
166
+ try {
167
+ const authAccountRequests = accounts.map((credentials) => __awaiter(this, void 0, void 0, function* () {
168
+ try {
169
+ const { signature, timestamp } = yield this.getWsAuthSignature(wsKey, credentials);
170
+ return {
171
+ apiKey: credentials.apiKey,
172
+ passphrase: credentials.apiPass,
173
+ timestamp: timestamp,
174
+ sign: signature,
175
+ };
176
+ }
177
+ catch (e) {
178
+ this.logger.error(`Account with key ${credentials.apiKey} could not be authenticateD: ${e}`);
179
+ }
180
+ return;
181
+ }));
182
+ const signedAuthAccountRequests = yield Promise.all(authAccountRequests);
183
+ // Filter out failed accounts
184
+ const authRequests = signedAuthAccountRequests.filter((request) => !!request);
185
+ const authParams = {
186
+ op: 'login',
187
+ args: authRequests,
188
+ };
189
+ return authParams;
190
+ }
191
+ catch (e) {
192
+ this.logger.error(e, Object.assign(Object.assign({}, loggerCategory), { wsKey }));
193
+ return;
194
+ }
195
+ });
196
+ }
197
+ getWsAuthSignature(wsKey, credentials) {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ const { apiKey, apiSecret } = credentials;
200
+ if (!apiKey || !apiSecret) {
201
+ this.logger.warning('Cannot authenticate websocket, either api or secret missing.', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
202
+ throw new Error(`Cannot auth - missing api or secret in config (key: ${apiKey})`);
203
+ }
204
+ this.logger.debug("Getting auth'd request params", Object.assign(Object.assign({}, loggerCategory), { wsKey }));
205
+ const timestamp = (Date.now() / 1000).toFixed(0);
206
+ // const signatureExpiresAt = timestamp + 5;
207
+ const signatureRequest = timestamp + 'GET' + '/users/self/verify';
208
+ const signature = yield (0, node_support_1.signMessage)(signatureRequest, apiSecret);
209
+ return {
210
+ signature,
211
+ timestamp,
212
+ };
213
+ });
214
+ }
215
+ sendAuthRequest(wsKey) {
216
+ return __awaiter(this, void 0, void 0, function* () {
217
+ const logContext = Object.assign(Object.assign({}, loggerCategory), { wsKey, method: 'sendAuthRequest' });
218
+ this.logger.info(`Sending auth request...`, logContext);
219
+ try {
220
+ const authRequest = yield this.getWsAuthRequest(wsKey);
221
+ if (!authRequest) {
222
+ throw new Error('Cannot authenticate this connection');
223
+ }
224
+ this.logger.info(`Sending authentication request on wsKey(${wsKey})`, logContext);
225
+ this.logger.silly(`Authenticating with event: ${JSON.stringify(authRequest, null, 2)} on wsKey(${wsKey})`, logContext);
226
+ return this.tryWsSend(wsKey, JSON.stringify(authRequest));
227
+ }
228
+ catch (e) {
229
+ this.logger.error(e, logContext);
230
+ }
231
+ });
232
+ }
233
+ reconnectWithDelay(wsKey, connectionDelayMs) {
234
+ var _a;
235
+ this.clearTimers(wsKey);
236
+ if (this.wsStore.getConnectionState(wsKey) !==
237
+ util_1.WsConnectionStateEnum.CONNECTING) {
238
+ this.wsStore.setConnectionState(wsKey, util_1.WsConnectionStateEnum.RECONNECTING);
239
+ }
240
+ if ((_a = this.wsStore.get(wsKey)) === null || _a === void 0 ? void 0 : _a.activeReconnectTimer) {
241
+ this.clearReconnectTimer(wsKey);
242
+ }
243
+ this.wsStore.get(wsKey, true).activeReconnectTimer = setTimeout(() => {
244
+ this.logger.info('Reconnecting to websocket', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
245
+ this.clearReconnectTimer(wsKey);
246
+ this.connect(wsKey);
247
+ }, connectionDelayMs);
248
+ }
249
+ ping(wsKey) {
250
+ if (this.wsStore.get(wsKey, true).activePongTimer) {
251
+ return;
252
+ }
253
+ this.clearPongTimer(wsKey);
254
+ this.logger.silly('Sending ping', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
255
+ this.tryWsSend(wsKey, 'ping');
256
+ this.wsStore.get(wsKey, true).activePongTimer = setTimeout(() => this.executeReconnectableClose(wsKey, 'Pong timeout'), this.options.pongTimeout);
257
+ }
258
+ /**
259
+ * Closes a connection, if it's even open. If open, this will trigger a reconnect asynchronously.
260
+ * If closed, trigger a reconnect immediately
261
+ */
262
+ executeReconnectableClose(wsKey, reason) {
263
+ var _a;
264
+ this.logger.info(`${reason} - closing socket to reconnect`, Object.assign(Object.assign({}, loggerCategory), { wsKey,
265
+ reason }));
266
+ const wasOpen = this.wsStore.isWsOpen(wsKey);
267
+ (_a = this.wsStore.getWs(wsKey)) === null || _a === void 0 ? void 0 : _a.terminate();
268
+ delete this.wsStore.get(wsKey, true).activePongTimer;
269
+ this.clearPingTimer(wsKey);
270
+ this.clearPongTimer(wsKey);
271
+ if (!wasOpen) {
272
+ this.logger.info(`${reason} - socket already closed - trigger immediate reconnect`, Object.assign(Object.assign({}, loggerCategory), { wsKey,
273
+ reason }));
274
+ this.reconnectWithDelay(wsKey, this.options.reconnectTimeout);
275
+ }
276
+ }
277
+ clearTimers(wsKey) {
278
+ this.clearPingTimer(wsKey);
279
+ this.clearPongTimer(wsKey);
280
+ this.clearReconnectTimer(wsKey);
281
+ }
282
+ // Send a ping at intervals
283
+ clearPingTimer(wsKey) {
284
+ const wsState = this.wsStore.get(wsKey);
285
+ if (wsState === null || wsState === void 0 ? void 0 : wsState.activePingTimer) {
286
+ clearInterval(wsState.activePingTimer);
287
+ wsState.activePingTimer = undefined;
288
+ }
289
+ }
290
+ // Expect a pong within a time limit
291
+ clearPongTimer(wsKey) {
292
+ const wsState = this.wsStore.get(wsKey);
293
+ if (wsState === null || wsState === void 0 ? void 0 : wsState.activePongTimer) {
294
+ clearTimeout(wsState.activePongTimer);
295
+ wsState.activePongTimer = undefined;
296
+ }
297
+ }
298
+ clearReconnectTimer(wsKey) {
299
+ const wsState = this.wsStore.get(wsKey);
300
+ if (wsState === null || wsState === void 0 ? void 0 : wsState.activeReconnectTimer) {
301
+ clearTimeout(wsState.activeReconnectTimer);
302
+ wsState.activeReconnectTimer = undefined;
303
+ }
304
+ }
305
+ /**
306
+ * @private Use the `subscribe(topics)` method to subscribe to topics. Send WS message to subscribe to topics.
307
+ */
308
+ requestSubscribeTopics(wsKey, topics) {
309
+ if (!topics.length) {
310
+ return;
311
+ }
312
+ const maxTopicsPerEvent = (0, util_1.getMaxTopicsPerSubscribeEvent)(this.options.market);
313
+ if (maxTopicsPerEvent && topics.length > maxTopicsPerEvent) {
314
+ this.logger.silly(`Subscribing to topics in batches of ${maxTopicsPerEvent}`);
315
+ for (var i = 0; i < topics.length; i += maxTopicsPerEvent) {
316
+ const batch = topics.slice(i, i + maxTopicsPerEvent);
317
+ this.logger.silly(`Subscribing to batch of ${batch.length}`);
318
+ this.requestSubscribeTopics(wsKey, batch);
319
+ }
320
+ this.logger.silly(`Finished batch subscribing to ${topics.length} topics`);
321
+ return;
322
+ }
323
+ const request = {
324
+ op: 'subscribe',
325
+ args: topics,
326
+ };
327
+ const wsMessage = JSON.stringify(request);
328
+ this.tryWsSend(wsKey, wsMessage);
329
+ }
330
+ /**
331
+ * @private Use the `unsubscribe(topics)` method to unsubscribe from topics. Send WS message to unsubscribe from topics.
332
+ */
333
+ requestUnsubscribeTopics(wsKey, topics) {
334
+ if (!topics.length) {
335
+ return;
336
+ }
337
+ const maxTopicsPerEvent = (0, util_1.getMaxTopicsPerSubscribeEvent)(this.options.market);
338
+ if (maxTopicsPerEvent && topics.length > maxTopicsPerEvent) {
339
+ this.logger.silly(`Unsubscribing to topics in batches of ${maxTopicsPerEvent}`);
340
+ for (var i = 0; i < topics.length; i += maxTopicsPerEvent) {
341
+ const batch = topics.slice(i, i + maxTopicsPerEvent);
342
+ this.logger.silly(`Unsubscribing to batch of ${batch.length}`);
343
+ this.requestUnsubscribeTopics(wsKey, batch);
344
+ }
345
+ this.logger.silly(`Finished batch unsubscribing to ${topics.length} topics`);
346
+ return;
347
+ }
348
+ const request = {
349
+ op: 'unsubscribe',
350
+ args: topics,
351
+ };
352
+ const wsMessage = JSON.stringify(request);
353
+ this.tryWsSend(wsKey, wsMessage);
354
+ }
355
+ tryWsSend(wsKey, wsMessage) {
356
+ try {
357
+ this.logger.silly(`Sending upstream ws message: `, Object.assign(Object.assign({}, loggerCategory), { wsMessage,
358
+ wsKey }));
359
+ if (!wsKey) {
360
+ throw new Error(`Cannot send message (wsKey not provided: wsKey(${wsKey}))`);
361
+ }
362
+ const ws = this.wsStore.getWs(wsKey);
363
+ if (!ws) {
364
+ throw new Error(`${wsKey} socket not connected yet, call "connect(${wsKey}) first then try again when the "open" event arrives`);
365
+ }
366
+ ws.send(wsMessage);
367
+ }
368
+ catch (e) {
369
+ this.logger.error(`Failed to send WS message`, Object.assign(Object.assign({}, loggerCategory), { wsMessage,
370
+ wsKey, exception: e }));
371
+ }
372
+ }
373
+ connectToWsUrl(url, wsKey) {
374
+ var _a;
375
+ this.logger.silly(`Opening WS connection to URL: ${url}`, Object.assign(Object.assign({}, loggerCategory), { wsKey }));
376
+ const agent = (_a = this.options.requestOptions) === null || _a === void 0 ? void 0 : _a.agent;
377
+ const ws = new isomorphic_ws_1.default(url, undefined, agent ? { agent } : undefined);
378
+ ws.onopen = (event) => this.onWsOpen(event, wsKey);
379
+ ws.onmessage = (event) => this.onWsMessage(event, wsKey);
380
+ ws.onerror = (event) => this.parseWsError('Websocket onWsError', event, wsKey);
381
+ ws.onclose = (event) => this.onWsClose(event, wsKey);
382
+ return ws;
383
+ }
384
+ onWsOpen(event, wsKey) {
385
+ return __awaiter(this, void 0, void 0, function* () {
386
+ if (this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.CONNECTING)) {
387
+ this.logger.info('Websocket connected', Object.assign(Object.assign({}, loggerCategory), { wsKey, market: this.options.market }));
388
+ this.emit('open', { wsKey, event });
389
+ }
390
+ else if (this.wsStore.isConnectionState(wsKey, util_1.WsConnectionStateEnum.RECONNECTING)) {
391
+ this.logger.info('Websocket reconnected', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
392
+ this.emit('reconnected', { wsKey, event });
393
+ }
394
+ this.wsStore.setConnectionState(wsKey, util_1.WsConnectionStateEnum.CONNECTED);
395
+ this.wsStore.get(wsKey, true).activePingTimer = setInterval(() => this.ping(wsKey), this.options.pingInterval);
396
+ // Private websockets require an auth packet to be sent after opening the connection
397
+ if (util_1.PRIVATE_WS_KEYS.includes(wsKey)) {
398
+ // Any requested private topics will be subscribed to once authentication succeeds (in onWsMessage handler)
399
+ yield this.sendAuthRequest(wsKey);
400
+ // Private topics will be subscribed to once authentication is confirmed as successful
401
+ return;
402
+ }
403
+ // Public topics can be subscribed to immediately
404
+ const topics = [
405
+ ...this.wsStore.getTopics(wsKey),
406
+ ];
407
+ // Since public channels have their own ws key, these topics must be public ones already
408
+ this.requestSubscribeTopics(wsKey, topics);
409
+ });
410
+ }
411
+ onWsMessage(event, wsKey) {
412
+ const logContext = Object.assign(Object.assign({}, loggerCategory), { wsKey, method: 'onWsMessage' });
413
+ try {
414
+ // any message can clear the pong timer - wouldn't get a message if the ws dropped
415
+ this.clearPongTimer(wsKey);
416
+ if ((0, util_1.isWsPong)(event)) {
417
+ this.logger.silly('Received pong', logContext);
418
+ return;
419
+ }
420
+ const msg = JSON.parse((event === null || event === void 0 ? void 0 : event.data) || event);
421
+ if ((0, util_1.isWsErrorEvent)(msg)) {
422
+ this.logger.error(`WS error event: `, Object.assign(Object.assign({}, msg), { wsKey }));
423
+ return this.emit('error', Object.assign(Object.assign({}, msg), { wsKey }));
424
+ }
425
+ if ((0, util_1.isWsDataEvent)(msg)) {
426
+ return this.emit('update', Object.assign(Object.assign({}, msg), { wsKey }));
427
+ }
428
+ if ((0, util_1.isWsLoginEvent)(msg)) {
429
+ // Successfully authenticated
430
+ if (msg.code === websocket_util_1.WS_EVENT_CODE_ENUM.OK) {
431
+ this.logger.info(`Authenticated succesfully on wsKey(${wsKey})`, logContext);
432
+ this.emit('response', Object.assign(Object.assign({}, msg), { wsKey }));
433
+ const topics = [
434
+ ...this.wsStore.getTopics(wsKey),
435
+ ];
436
+ // Since private topics have a dedicated WsKey, these are automatically all private topics (no filtering required before the subscribe call)
437
+ this.requestSubscribeTopics(wsKey, topics);
438
+ return;
439
+ }
440
+ this.logger.error(`Authentication failed: `, Object.assign(Object.assign(Object.assign({}, logContext), msg), { wsKey }));
441
+ return this.emit('error', Object.assign(Object.assign({}, msg), { wsKey }));
442
+ }
443
+ if ((0, util_1.isWsSubscribeEvent)(msg) || (0, util_1.isWsUnsubscribeEvent)(msg)) {
444
+ // this.logger.silly(`Ws subscribe reply:`, { ...msg, wsKey });
445
+ return this.emit('response', Object.assign(Object.assign({}, msg), { wsKey }));
446
+ }
447
+ this.logger.error('Unhandled/unrecognised ws event message', Object.assign(Object.assign({}, logContext), { eventName: msg.event, msg: JSON.stringify(msg, null, 2), wsKey }));
448
+ }
449
+ catch (e) {
450
+ this.logger.error('Failed to parse ws event message', Object.assign(Object.assign({}, logContext), { error: e, event,
451
+ wsKey }));
452
+ }
453
+ }
454
+ onWsClose(event, wsKey) {
455
+ this.logger.info('Websocket connection closed', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
456
+ if (this.wsStore.getConnectionState(wsKey) !== util_1.WsConnectionStateEnum.CLOSING) {
457
+ this.reconnectWithDelay(wsKey, this.options.reconnectTimeout);
458
+ this.emit('reconnect', { wsKey, event });
459
+ }
460
+ else {
461
+ this.wsStore.setConnectionState(wsKey, util_1.WsConnectionStateEnum.INITIAL);
462
+ this.emit('close', { wsKey, event });
463
+ }
464
+ }
465
+ }
466
+ exports.WebsocketClient = WebsocketClient;
467
+ //# sourceMappingURL=websocket-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-client.js","sourceRoot":"","sources":["../src/websocket-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okx-api",
3
- "version": "0.0.6",
3
+ "version": "1.0.1",
4
4
  "description": "Node.js connector for OKX REST APIs and WebSockets, with TypeScript & integration tests.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",