bybit-api 3.10.30 → 4.0.0-beta.0

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 (146) hide show
  1. package/README.md +301 -178
  2. package/lib/index.d.ts +0 -11
  3. package/lib/index.js +0 -11
  4. package/lib/index.js.map +1 -1
  5. package/lib/rest-client-v5.d.ts +1 -1
  6. package/lib/rest-client-v5.js +1 -1
  7. package/lib/spot-client-v3.d.ts +8 -81
  8. package/lib/spot-client-v3.js +7 -172
  9. package/lib/spot-client-v3.js.map +1 -1
  10. package/lib/types/index.d.ts +1 -2
  11. package/lib/types/index.js +1 -2
  12. package/lib/types/index.js.map +1 -1
  13. package/lib/types/request/index.d.ts +0 -1
  14. package/lib/types/request/index.js +0 -1
  15. package/lib/types/request/index.js.map +1 -1
  16. package/lib/types/request/v5-account.d.ts +1 -1
  17. package/lib/types/request/v5-asset.d.ts +1 -1
  18. package/lib/types/request/v5-market.d.ts +1 -1
  19. package/lib/types/request/v5-position.d.ts +1 -1
  20. package/lib/types/request/v5-pre-upgrade.d.ts +1 -1
  21. package/lib/types/request/v5-spot-leverage-token.d.ts +1 -1
  22. package/lib/types/request/v5-trade.d.ts +1 -1
  23. package/lib/types/request/v5-user.d.ts +1 -1
  24. package/lib/types/response/v5-account.d.ts +1 -1
  25. package/lib/types/response/v5-asset.d.ts +1 -1
  26. package/lib/types/response/v5-market.d.ts +1 -1
  27. package/lib/types/response/v5-position.d.ts +1 -1
  28. package/lib/types/response/v5-spot-leverage-token.d.ts +1 -1
  29. package/lib/types/response/v5-trade.d.ts +1 -1
  30. package/lib/types/response/v5-user.d.ts +1 -1
  31. package/lib/types/{request/spot.js → shared-v5.js} +1 -1
  32. package/lib/types/shared-v5.js.map +1 -0
  33. package/lib/types/shared.d.ts +1 -19
  34. package/lib/types/websockets/index.d.ts +3 -0
  35. package/lib/types/websockets/index.js +20 -0
  36. package/lib/types/websockets/index.js.map +1 -0
  37. package/lib/types/websockets/ws-api.d.ts +73 -0
  38. package/lib/types/websockets/ws-api.js +10 -0
  39. package/lib/types/websockets/ws-api.js.map +1 -0
  40. package/lib/types/websockets/ws-confirmations.d.ts +13 -0
  41. package/lib/types/{websocket.events.js → websockets/ws-confirmations.js} +1 -1
  42. package/lib/types/websockets/ws-confirmations.js.map +1 -0
  43. package/lib/types/{websocket.events.d.ts → websockets/ws-events.d.ts} +9 -3
  44. package/lib/types/websockets/ws-events.js +11 -0
  45. package/lib/types/websockets/ws-events.js.map +1 -0
  46. package/lib/types/{websockets.d.ts → websockets/ws-general.d.ts} +35 -10
  47. package/lib/types/{v5-shared.js → websockets/ws-general.js} +1 -1
  48. package/lib/types/websockets/ws-general.js.map +1 -0
  49. package/lib/util/BaseRestClient.d.ts +1 -1
  50. package/lib/util/BaseRestClient.js +15 -39
  51. package/lib/util/BaseRestClient.js.map +1 -1
  52. package/lib/util/BaseWSClient.d.ts +221 -0
  53. package/lib/util/BaseWSClient.js +733 -0
  54. package/lib/util/BaseWSClient.js.map +1 -0
  55. package/lib/util/index.d.ts +1 -2
  56. package/lib/util/index.js +1 -2
  57. package/lib/util/index.js.map +1 -1
  58. package/lib/util/logger.d.ts +2 -5
  59. package/lib/util/logger.js +3 -12
  60. package/lib/util/logger.js.map +1 -1
  61. package/lib/util/requestUtils.d.ts +7 -10
  62. package/lib/util/requestUtils.js +6 -33
  63. package/lib/util/requestUtils.js.map +1 -1
  64. package/lib/util/typeGuards.d.ts +7 -1
  65. package/lib/util/typeGuards.js +41 -5
  66. package/lib/util/typeGuards.js.map +1 -1
  67. package/lib/util/webCryptoAPI.d.ts +10 -0
  68. package/lib/util/webCryptoAPI.js +69 -0
  69. package/lib/util/webCryptoAPI.js.map +1 -0
  70. package/lib/util/websockets/WsStore.d.ts +71 -0
  71. package/lib/util/websockets/WsStore.js +269 -0
  72. package/lib/util/websockets/WsStore.js.map +1 -0
  73. package/lib/util/websockets/WsStore.types.d.ts +50 -0
  74. package/lib/util/websockets/WsStore.types.js +14 -0
  75. package/lib/util/websockets/WsStore.types.js.map +1 -0
  76. package/lib/util/websockets/index.d.ts +3 -0
  77. package/lib/util/websockets/index.js +20 -0
  78. package/lib/util/websockets/index.js.map +1 -0
  79. package/lib/util/websockets/websocket-util.d.ts +92 -0
  80. package/lib/util/websockets/websocket-util.js +280 -0
  81. package/lib/util/websockets/websocket-util.js.map +1 -0
  82. package/lib/websocket-client.d.ts +107 -114
  83. package/lib/websocket-client.js +422 -716
  84. package/lib/websocket-client.js.map +1 -1
  85. package/package.json +4 -4
  86. package/lib/account-asset-client-v3.d.ts +0 -87
  87. package/lib/account-asset-client-v3.js +0 -154
  88. package/lib/account-asset-client-v3.js.map +0 -1
  89. package/lib/account-asset-client.d.ts +0 -46
  90. package/lib/account-asset-client.js +0 -108
  91. package/lib/account-asset-client.js.map +0 -1
  92. package/lib/contract-client.d.ts +0 -136
  93. package/lib/contract-client.js +0 -251
  94. package/lib/contract-client.js.map +0 -1
  95. package/lib/copy-trading-client.d.ts +0 -60
  96. package/lib/copy-trading-client.js +0 -114
  97. package/lib/copy-trading-client.js.map +0 -1
  98. package/lib/inverse-client.d.ts +0 -104
  99. package/lib/inverse-client.js +0 -213
  100. package/lib/inverse-client.js.map +0 -1
  101. package/lib/inverse-futures-client.d.ts +0 -217
  102. package/lib/inverse-futures-client.js +0 -224
  103. package/lib/inverse-futures-client.js.map +0 -1
  104. package/lib/linear-client.d.ts +0 -112
  105. package/lib/linear-client.js +0 -225
  106. package/lib/linear-client.js.map +0 -1
  107. package/lib/spot-client.d.ts +0 -46
  108. package/lib/spot-client.js +0 -131
  109. package/lib/spot-client.js.map +0 -1
  110. package/lib/types/request/spot.d.ts +0 -79
  111. package/lib/types/request/spot.js.map +0 -1
  112. package/lib/types/v5-shared.js.map +0 -1
  113. package/lib/types/websocket.events.js.map +0 -1
  114. package/lib/types/websockets.js +0 -3
  115. package/lib/types/websockets.js.map +0 -1
  116. package/lib/types/ws-events/failed-topic-subscription-confirmation.d.ts +0 -4
  117. package/lib/types/ws-events/failed-topic-subscription-confirmation.js +0 -3
  118. package/lib/types/ws-events/failed-topic-subscription-confirmation.js.map +0 -1
  119. package/lib/types/ws-events/succeeded-topic-subscription-confirmation.d.ts +0 -4
  120. package/lib/types/ws-events/succeeded-topic-subscription-confirmation.js +0 -3
  121. package/lib/types/ws-events/succeeded-topic-subscription-confirmation.js.map +0 -1
  122. package/lib/types/ws-events/topic-subscription-confirmation.d.ts +0 -7
  123. package/lib/types/ws-events/topic-subscription-confirmation.js +0 -3
  124. package/lib/types/ws-events/topic-subscription-confirmation.js.map +0 -1
  125. package/lib/unified-margin-client.d.ts +0 -140
  126. package/lib/unified-margin-client.js +0 -270
  127. package/lib/unified-margin-client.js.map +0 -1
  128. package/lib/usdc-option-client.d.ts +0 -110
  129. package/lib/usdc-option-client.js +0 -196
  130. package/lib/usdc-option-client.js.map +0 -1
  131. package/lib/usdc-perpetual-client.d.ts +0 -97
  132. package/lib/usdc-perpetual-client.js +0 -191
  133. package/lib/usdc-perpetual-client.js.map +0 -1
  134. package/lib/util/WsStore.d.ts +0 -57
  135. package/lib/util/WsStore.js +0 -97
  136. package/lib/util/WsStore.js.map +0 -1
  137. package/lib/util/browser-support.d.ts +0 -1
  138. package/lib/util/browser-support.js +0 -26
  139. package/lib/util/browser-support.js.map +0 -1
  140. package/lib/util/node-support.d.ts +0 -2
  141. package/lib/util/node-support.js +0 -21
  142. package/lib/util/node-support.js.map +0 -1
  143. package/lib/util/websocket-util.d.ts +0 -68
  144. package/lib/util/websocket-util.js +0 -506
  145. package/lib/util/websocket-util.js.map +0 -1
  146. /package/lib/types/{v5-shared.d.ts → shared-v5.d.ts} +0 -0
@@ -0,0 +1,733 @@
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.BaseWebsocketClient = void 0;
16
+ /* eslint-disable max-len */
17
+ /* eslint-disable @typescript-eslint/no-explicit-any */
18
+ const events_1 = __importDefault(require("events"));
19
+ const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
20
+ const logger_1 = require("./logger");
21
+ const types_1 = require("../types");
22
+ const WsStore_1 = require("./websockets/WsStore");
23
+ const websockets_1 = require("./websockets");
24
+ /**
25
+ * Base WebSocket abstraction layer. Handles connections, tracking each connection as a unique "WS Key"
26
+ */
27
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
28
+ class BaseWebsocketClient extends events_1.default {
29
+ constructor(options, logger) {
30
+ super();
31
+ this.wsApiRequestId = 0;
32
+ this.timeOffsetMs = 0;
33
+ /**
34
+ * A nested wsKey->request key store.
35
+ * pendingTopicSubscriptionRequests[wsKey][requestKey] = WsKeyPendingTopicSubscriptions<TWSRequestEvent>
36
+ */
37
+ this.pendingTopicSubscriptionRequests = {};
38
+ this.logger = logger || logger_1.DefaultLogger;
39
+ this.wsStore = new WsStore_1.WsStore(this.logger);
40
+ this.options = Object.assign({
41
+ // Some defaults:
42
+ testnet: false, demoTrading: false,
43
+ // Connect to V5 by default, if not defined by the user
44
+ market: 'v5', pongTimeout: 1000, pingInterval: 10000, reconnectTimeout: 500, recvWindow: 5000,
45
+ // Automatically send an authentication op/request after a connection opens, for private connections.
46
+ authPrivateConnectionsOnConnect: true,
47
+ // Individual requests do not require a signature, so this is disabled.
48
+ authPrivateRequests: false }, options);
49
+ // add default error handling so this doesn't crash node (if the user didn't set a handler)
50
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
51
+ this.on('error', () => { });
52
+ }
53
+ isPrivateWsKey(wsKey) {
54
+ return this.getPrivateWSKeys().includes(wsKey);
55
+ }
56
+ /** Returns auto-incrementing request ID, used to track promise references for async requests */
57
+ getNewRequestId() {
58
+ return `${++this.wsApiRequestId}`;
59
+ }
60
+ getTimeOffsetMs() {
61
+ return this.timeOffsetMs;
62
+ }
63
+ setTimeOffsetMs(newOffset) {
64
+ this.timeOffsetMs = newOffset;
65
+ }
66
+ getWsKeyPendingSubscriptionStore(wsKey) {
67
+ if (!this.pendingTopicSubscriptionRequests[wsKey]) {
68
+ this.pendingTopicSubscriptionRequests[wsKey] = {};
69
+ }
70
+ return this.pendingTopicSubscriptionRequests[wsKey];
71
+ }
72
+ upsertPendingTopicSubscribeRequests(wsKey, requestData) {
73
+ // a unique identifier for this subscription request (e.g. csv of topics, or request id, etc)
74
+ const requestKey = requestData.requestKey;
75
+ // Should not be possible to see a requestKey collision in the current design, since the req ID increments automatically with every request, so this should never be true, but just in case a future mistake happens...
76
+ const pendingSubReqs = this.getWsKeyPendingSubscriptionStore(wsKey);
77
+ if (pendingSubReqs[requestKey]) {
78
+ throw new Error('Implementation error: attempted to upsert pending topics with duplicate request ID!');
79
+ }
80
+ return new Promise((resolver, rejector) => {
81
+ const pendingSubReqs = this.getWsKeyPendingSubscriptionStore(wsKey);
82
+ pendingSubReqs[requestKey] = {
83
+ requestData: requestData.requestEvent,
84
+ resolver,
85
+ rejector,
86
+ };
87
+ });
88
+ }
89
+ removeTopicPendingSubscription(wsKey, requestKey) {
90
+ const pendingSubReqs = this.getWsKeyPendingSubscriptionStore(wsKey);
91
+ delete pendingSubReqs[requestKey];
92
+ }
93
+ clearTopicsPendingSubscriptions(wsKey, rejectAll, rejectReason) {
94
+ if (rejectAll) {
95
+ const pendingSubReqs = this.getWsKeyPendingSubscriptionStore(wsKey);
96
+ for (const requestKey in pendingSubReqs) {
97
+ const request = pendingSubReqs[requestKey];
98
+ request === null || request === void 0 ? void 0 : request.rejector(request.requestData, rejectReason);
99
+ }
100
+ }
101
+ this.pendingTopicSubscriptionRequests[wsKey] = {};
102
+ }
103
+ /**
104
+ * Resolve/reject the promise for a midflight request.
105
+ *
106
+ * This will typically execute before the event is emitted.
107
+ */
108
+ updatePendingTopicSubscriptionStatus(wsKey, requestKey, msg, isTopicSubscriptionSuccessEvent) {
109
+ const wsKeyPendingRequests = this.getWsKeyPendingSubscriptionStore(wsKey);
110
+ if (!wsKeyPendingRequests) {
111
+ return;
112
+ }
113
+ const pendingSubscriptionRequest = wsKeyPendingRequests[requestKey];
114
+ if (!pendingSubscriptionRequest) {
115
+ return;
116
+ }
117
+ if (isTopicSubscriptionSuccessEvent) {
118
+ pendingSubscriptionRequest.resolver(pendingSubscriptionRequest.requestData);
119
+ }
120
+ else {
121
+ pendingSubscriptionRequest.rejector(pendingSubscriptionRequest.requestData, msg);
122
+ }
123
+ this.removeTopicPendingSubscription(wsKey, requestKey);
124
+ }
125
+ /**
126
+ * Don't call directly! Use subscribe() instead!
127
+ *
128
+ * Subscribe to one or more topics on a WS connection (identified by WS Key).
129
+ *
130
+ * - Topics are automatically cached
131
+ * - Connections are automatically opened, if not yet connected
132
+ * - Authentication is automatically handled
133
+ * - Topics are automatically resubscribed to, if something happens to the connection, unless you call unsubsribeTopicsForWsKey(topics, key).
134
+ *
135
+ * @param wsRequests array of topics to subscribe to
136
+ * @param wsKey ws key referring to the ws connection these topics should be subscribed on
137
+ */
138
+ subscribeTopicsForWsKey(wsTopicRequests, wsKey) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ var _a;
141
+ const normalisedTopicRequests = (0, websockets_1.getNormalisedTopicRequests)(wsTopicRequests);
142
+ // Store topics, so future automation (post-auth, post-reconnect) has everything needed to resubscribe automatically
143
+ for (const topic of normalisedTopicRequests) {
144
+ this.wsStore.addTopic(wsKey, topic);
145
+ }
146
+ const isConnected = this.wsStore.isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTED);
147
+ const isConnectionInProgress = this.wsStore.isConnectionAttemptInProgress(wsKey);
148
+ // start connection process if it hasn't yet begun. Topics are automatically subscribed to on-connect
149
+ if (!isConnected && !isConnectionInProgress) {
150
+ return this.connect(wsKey);
151
+ }
152
+ // Subscribe should happen automatically once connected, nothing to do here after topics are added to wsStore.
153
+ if (!isConnected) {
154
+ /**
155
+ * Are we in the process of connection? Nothing to send yet.
156
+ */
157
+ this.logger.trace('WS not connected - requests queued for retry once connected.', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey,
158
+ wsTopicRequests }));
159
+ return;
160
+ }
161
+ // We're connected. Check if auth is needed and if already authenticated
162
+ const isPrivateConnection = this.isPrivateWsKey(wsKey);
163
+ const isAuthenticated = (_a = this.wsStore.get(wsKey)) === null || _a === void 0 ? void 0 : _a.isAuthenticated;
164
+ if (isPrivateConnection && !isAuthenticated) {
165
+ /**
166
+ * If not authenticated yet and auth is required, don't request topics yet.
167
+ *
168
+ * Auth should already automatically be in progress, so no action needed from here. Topics will automatically subscribe post-auth success.
169
+ */
170
+ return false;
171
+ }
172
+ // Finally, request subscription to topics if the connection is healthy and ready
173
+ return this.requestSubscribeTopics(wsKey, normalisedTopicRequests);
174
+ });
175
+ }
176
+ unsubscribeTopicsForWsKey(wsTopicRequests, wsKey) {
177
+ return __awaiter(this, void 0, void 0, function* () {
178
+ var _a;
179
+ const normalisedTopicRequests = (0, websockets_1.getNormalisedTopicRequests)(wsTopicRequests);
180
+ // Store topics, so future automation (post-auth, post-reconnect) has everything needed to resubscribe automatically
181
+ for (const topic of normalisedTopicRequests) {
182
+ this.wsStore.deleteTopic(wsKey, topic);
183
+ }
184
+ const isConnected = this.wsStore.isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTED);
185
+ // If not connected, don't need to do anything.
186
+ // Removing the topic from the store is enough to stop it from being resubscribed to on reconnect.
187
+ if (!isConnected) {
188
+ return;
189
+ }
190
+ // We're connected. Check if auth is needed and if already authenticated
191
+ const isPrivateConnection = this.isPrivateWsKey(wsKey);
192
+ const isAuthenticated = (_a = this.wsStore.get(wsKey)) === null || _a === void 0 ? void 0 : _a.isAuthenticated;
193
+ if (isPrivateConnection && !isAuthenticated) {
194
+ /**
195
+ * If not authenticated yet and auth is required, don't need to do anything.
196
+ * We don't subscribe to topics until auth is complete anyway.
197
+ */
198
+ return;
199
+ }
200
+ // Finally, request subscription to topics if the connection is healthy and ready
201
+ return this.requestUnsubscribeTopics(wsKey, normalisedTopicRequests);
202
+ });
203
+ }
204
+ /**
205
+ * Splits topic requests into two groups, public & private topic requests
206
+ */
207
+ sortTopicRequestsIntoPublicPrivate(wsTopicRequests, wsKey) {
208
+ const publicTopicRequests = [];
209
+ const privateTopicRequests = [];
210
+ for (const topic of wsTopicRequests) {
211
+ if (this.isPrivateTopicRequest(topic, wsKey)) {
212
+ privateTopicRequests.push(topic);
213
+ }
214
+ else {
215
+ publicTopicRequests.push(topic);
216
+ }
217
+ }
218
+ return {
219
+ publicReqs: publicTopicRequests,
220
+ privateReqs: privateTopicRequests,
221
+ };
222
+ }
223
+ /** Get the WsStore that tracks websockets & topics */
224
+ getWsStore() {
225
+ return this.wsStore;
226
+ }
227
+ close(wsKey, force) {
228
+ this.logger.info('Closing connection', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
229
+ this.setWsState(wsKey, websockets_1.WsConnectionStateEnum.CLOSING);
230
+ this.clearTimers(wsKey);
231
+ const ws = this.getWs(wsKey);
232
+ ws === null || ws === void 0 ? void 0 : ws.close();
233
+ if (force) {
234
+ (0, websockets_1.safeTerminateWs)(ws);
235
+ }
236
+ }
237
+ closeAll(force) {
238
+ const keys = this.wsStore.getKeys();
239
+ this.logger.info(`Closing all ws connections: ${keys}`);
240
+ keys.forEach((key) => {
241
+ this.close(key, force);
242
+ });
243
+ }
244
+ isConnected(wsKey) {
245
+ return this.wsStore.isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTED);
246
+ }
247
+ /**
248
+ * Request connection to a specific websocket, instead of waiting for automatic connection.
249
+ */
250
+ connect(wsKey) {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ var _a;
253
+ try {
254
+ if (this.wsStore.isWsOpen(wsKey)) {
255
+ this.logger.error('Refused to connect to ws with existing active connection', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
256
+ return { wsKey };
257
+ }
258
+ if (this.wsStore.isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTING)) {
259
+ this.logger.error('Refused to connect to ws, connection attempt already active', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
260
+ return;
261
+ }
262
+ if (!this.wsStore.getConnectionState(wsKey) ||
263
+ this.wsStore.isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.INITIAL)) {
264
+ this.setWsState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTING);
265
+ }
266
+ if (!this.wsStore.getConnectionInProgressPromise(wsKey)) {
267
+ this.wsStore.createConnectionInProgressPromise(wsKey, false);
268
+ }
269
+ const url = yield this.getWsUrl(wsKey);
270
+ const ws = this.connectToWsUrl(url, wsKey);
271
+ this.wsStore.setWs(wsKey, ws);
272
+ return (_a = this.wsStore.getConnectionInProgressPromise(wsKey)) === null || _a === void 0 ? void 0 : _a.promise;
273
+ }
274
+ catch (err) {
275
+ this.parseWsError('Connection failed', err, wsKey);
276
+ this.reconnectWithDelay(wsKey, this.options.reconnectTimeout);
277
+ }
278
+ });
279
+ }
280
+ connectToWsUrl(url, wsKey) {
281
+ var _a;
282
+ this.logger.trace(`Opening WS connection to URL: ${url}`, Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
283
+ const agent = (_a = this.options.requestOptions) === null || _a === void 0 ? void 0 : _a.agent;
284
+ const ws = new isomorphic_ws_1.default(url, undefined, agent ? { agent } : undefined);
285
+ ws.onopen = (event) => this.onWsOpen(event, wsKey);
286
+ ws.onmessage = (event) => this.onWsMessage(event, wsKey, ws);
287
+ ws.onerror = (event) => this.parseWsError('Websocket onWsError', event, wsKey);
288
+ ws.onclose = (event) => this.onWsClose(event, wsKey);
289
+ return ws;
290
+ }
291
+ parseWsError(context, error, wsKey) {
292
+ if (!error.message) {
293
+ this.logger.error(`${context} due to unexpected error: `, error);
294
+ this.emit('response', Object.assign(Object.assign({}, error), { wsKey }));
295
+ this.emit('error', Object.assign(Object.assign({}, error), { wsKey }));
296
+ return;
297
+ }
298
+ switch (error.message) {
299
+ case 'Unexpected server response: 401':
300
+ this.logger.error(`${context} due to 401 authorization failure.`, Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
301
+ break;
302
+ default:
303
+ if (this.wsStore.getConnectionState(wsKey) !==
304
+ websockets_1.WsConnectionStateEnum.CLOSING) {
305
+ 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({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey, error }));
306
+ this.executeReconnectableClose(wsKey, 'unhandled onWsError');
307
+ }
308
+ else {
309
+ this.logger.info(`${wsKey} socket forcefully closed. Will not reconnect.`);
310
+ }
311
+ break;
312
+ }
313
+ this.emit('response', Object.assign(Object.assign({}, error), { wsKey }));
314
+ this.emit('error', Object.assign(Object.assign({}, error), { wsKey }));
315
+ }
316
+ /** Get a signature, build the auth request and send it */
317
+ sendAuthRequest(wsKey) {
318
+ return __awaiter(this, void 0, void 0, function* () {
319
+ var _a;
320
+ try {
321
+ this.logger.trace('Sending auth request...', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
322
+ yield this.assertIsConnected(wsKey);
323
+ if (!this.wsStore.getAuthenticationInProgressPromise(wsKey)) {
324
+ this.wsStore.createAuthenticationInProgressPromise(wsKey, false);
325
+ }
326
+ const request = yield this.getWsAuthRequestEvent(wsKey);
327
+ // console.log('ws auth req', request);
328
+ this.tryWsSend(wsKey, JSON.stringify(request));
329
+ return (_a = this.wsStore.getAuthenticationInProgressPromise(wsKey)) === null || _a === void 0 ? void 0 : _a.promise;
330
+ }
331
+ catch (e) {
332
+ this.logger.trace(e, Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
333
+ }
334
+ });
335
+ }
336
+ reconnectWithDelay(wsKey, connectionDelayMs) {
337
+ var _a;
338
+ this.clearTimers(wsKey);
339
+ if (!this.wsStore.isConnectionAttemptInProgress(wsKey)) {
340
+ this.setWsState(wsKey, websockets_1.WsConnectionStateEnum.RECONNECTING);
341
+ }
342
+ if ((_a = this.wsStore.get(wsKey)) === null || _a === void 0 ? void 0 : _a.activeReconnectTimer) {
343
+ this.clearReconnectTimer(wsKey);
344
+ }
345
+ this.wsStore.get(wsKey, true).activeReconnectTimer = setTimeout(() => {
346
+ this.logger.info('Reconnecting to websocket', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
347
+ this.clearReconnectTimer(wsKey);
348
+ this.connect(wsKey);
349
+ }, connectionDelayMs);
350
+ }
351
+ ping(wsKey) {
352
+ if (this.wsStore.get(wsKey, true).activePongTimer) {
353
+ return;
354
+ }
355
+ this.clearPongTimer(wsKey);
356
+ this.logger.trace('Sending ping', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
357
+ const ws = this.wsStore.get(wsKey, true).ws;
358
+ if (!ws) {
359
+ this.logger.error(`Unable to send ping for wsKey "${wsKey}" - no connection found`);
360
+ return;
361
+ }
362
+ this.sendPingEvent(wsKey, ws);
363
+ this.wsStore.get(wsKey, true).activePongTimer = setTimeout(() => this.executeReconnectableClose(wsKey, 'Pong timeout'), this.options.pongTimeout);
364
+ }
365
+ /**
366
+ * Closes a connection, if it's even open. If open, this will trigger a reconnect asynchronously.
367
+ * If closed, trigger a reconnect immediately
368
+ */
369
+ executeReconnectableClose(wsKey, reason) {
370
+ this.logger.info(`${reason} - closing socket to reconnect`, Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey,
371
+ reason }));
372
+ const wasOpen = this.wsStore.isWsOpen(wsKey);
373
+ this.clearPingTimer(wsKey);
374
+ this.clearPongTimer(wsKey);
375
+ const ws = this.getWs(wsKey);
376
+ if (ws) {
377
+ ws.close();
378
+ (0, websockets_1.safeTerminateWs)(ws);
379
+ }
380
+ if (!wasOpen) {
381
+ this.logger.info(`${reason} - socket already closed - trigger immediate reconnect`, Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey,
382
+ reason }));
383
+ this.reconnectWithDelay(wsKey, this.options.reconnectTimeout);
384
+ }
385
+ }
386
+ clearTimers(wsKey) {
387
+ this.clearPingTimer(wsKey);
388
+ this.clearPongTimer(wsKey);
389
+ this.clearReconnectTimer(wsKey);
390
+ }
391
+ // Send a ping at intervals
392
+ clearPingTimer(wsKey) {
393
+ const wsState = this.wsStore.get(wsKey);
394
+ if (wsState === null || wsState === void 0 ? void 0 : wsState.activePingTimer) {
395
+ clearInterval(wsState.activePingTimer);
396
+ wsState.activePingTimer = undefined;
397
+ }
398
+ }
399
+ // Expect a pong within a time limit
400
+ clearPongTimer(wsKey) {
401
+ const wsState = this.wsStore.get(wsKey);
402
+ if (wsState === null || wsState === void 0 ? void 0 : wsState.activePongTimer) {
403
+ clearTimeout(wsState.activePongTimer);
404
+ wsState.activePongTimer = undefined;
405
+ // this.logger.trace(`Cleared pong timeout for "${wsKey}"`);
406
+ }
407
+ else {
408
+ // this.logger.trace(`No active pong timer for "${wsKey}"`);
409
+ }
410
+ }
411
+ clearReconnectTimer(wsKey) {
412
+ const wsState = this.wsStore.get(wsKey);
413
+ if (wsState === null || wsState === void 0 ? void 0 : wsState.activeReconnectTimer) {
414
+ clearTimeout(wsState.activeReconnectTimer);
415
+ wsState.activeReconnectTimer = undefined;
416
+ }
417
+ }
418
+ /**
419
+ * Returns a list of string events that can be individually sent upstream to complete subscribing/unsubscribing/etc to these topics
420
+ *
421
+ * If events are an object, these should be stringified (`return JSON.stringify(event);`)
422
+ * Each event returned by this will be sent one at a time
423
+ *
424
+ * Events are automatically split into smaller batches, by this method, if needed.
425
+ */
426
+ getWsOperationEventsForTopics(topics, wsKey, operation) {
427
+ return __awaiter(this, void 0, void 0, function* () {
428
+ // console.log(new Date(), `called getWsSubscribeEventsForTopics()`, topics);
429
+ // console.trace();
430
+ if (!topics.length) {
431
+ return [];
432
+ }
433
+ // Events that are ready to send (usually stringified JSON)
434
+ const requestEvents = [];
435
+ const market = 'all';
436
+ const maxTopicsPerEvent = this.getMaxTopicsPerSubscribeEvent(wsKey);
437
+ if (maxTopicsPerEvent &&
438
+ maxTopicsPerEvent !== null &&
439
+ topics.length > maxTopicsPerEvent) {
440
+ for (let i = 0; i < topics.length; i += maxTopicsPerEvent) {
441
+ const batch = topics.slice(i, i + maxTopicsPerEvent);
442
+ const subscribeRequestEvents = yield this.getWsRequestEvents(market, operation, batch, wsKey);
443
+ requestEvents.push(...subscribeRequestEvents);
444
+ }
445
+ return requestEvents;
446
+ }
447
+ const subscribeRequestEvents = yield this.getWsRequestEvents(market, operation, topics, wsKey);
448
+ return subscribeRequestEvents;
449
+ });
450
+ }
451
+ /**
452
+ * Simply builds and sends subscribe events for a list of topics for a ws key
453
+ *
454
+ * @private Use the `subscribe(topics)` or `subscribeTopicsForWsKey(topics, wsKey)` method to subscribe to topics.
455
+ */
456
+ requestSubscribeTopics(wsKey, wsTopicRequests) {
457
+ return __awaiter(this, void 0, void 0, function* () {
458
+ if (!wsTopicRequests.length) {
459
+ return;
460
+ }
461
+ // Automatically splits requests into smaller batches, if needed
462
+ const subscribeWsMessages = yield this.getWsOperationEventsForTopics(wsTopicRequests, wsKey, 'subscribe');
463
+ this.logger.trace(`Subscribing to ${wsTopicRequests.length} "${wsKey}" topics in ${subscribeWsMessages.length} batches.`);
464
+ // console.log(`batches: `, JSON.stringify(subscribeWsMessages, null, 2));
465
+ const promises = [];
466
+ for (const midflightRequest of subscribeWsMessages) {
467
+ const wsMessage = midflightRequest.requestEvent;
468
+ promises.push(this.upsertPendingTopicSubscribeRequests(wsKey, midflightRequest));
469
+ this.logger.trace(`Sending batch via message: "${JSON.stringify(wsMessage)}"`);
470
+ this.tryWsSend(wsKey, JSON.stringify(wsMessage));
471
+ }
472
+ this.logger.trace(`Finished subscribing to ${wsTopicRequests.length} "${wsKey}" topics in ${subscribeWsMessages.length} batches.`);
473
+ return Promise.all(promises);
474
+ });
475
+ }
476
+ /**
477
+ * Simply builds and sends unsubscribe events for a list of topics for a ws key
478
+ *
479
+ * @private Use the `unsubscribe(topics)` method to unsubscribe from topics. Send WS message to unsubscribe from topics.
480
+ */
481
+ requestUnsubscribeTopics(wsKey, wsTopicRequests) {
482
+ return __awaiter(this, void 0, void 0, function* () {
483
+ if (!wsTopicRequests.length) {
484
+ return;
485
+ }
486
+ const subscribeWsMessages = yield this.getWsOperationEventsForTopics(wsTopicRequests, wsKey, 'unsubscribe');
487
+ this.logger.trace(`Unsubscribing to ${wsTopicRequests.length} "${wsKey}" topics in ${subscribeWsMessages.length} batches. Events: "${JSON.stringify(wsTopicRequests)}"`);
488
+ const promises = [];
489
+ for (const midflightRequest of subscribeWsMessages) {
490
+ const wsMessage = midflightRequest.requestEvent;
491
+ promises.push(this.upsertPendingTopicSubscribeRequests(wsKey, midflightRequest));
492
+ this.logger.trace(`Sending batch via message: "${wsMessage}"`);
493
+ this.tryWsSend(wsKey, JSON.stringify(wsMessage));
494
+ }
495
+ this.logger.trace(`Finished unsubscribing to ${wsTopicRequests.length} "${wsKey}" topics in ${subscribeWsMessages.length} batches.`);
496
+ return Promise.all(promises);
497
+ });
498
+ }
499
+ /**
500
+ * Try sending a string event on a WS connection (identified by the WS Key)
501
+ */
502
+ tryWsSend(wsKey, wsMessage, throwExceptions) {
503
+ try {
504
+ this.logger.trace('Sending upstream ws message: ', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsMessage,
505
+ wsKey }));
506
+ if (!wsKey) {
507
+ throw new Error('Cannot send message due to no known websocket for this wsKey');
508
+ }
509
+ const ws = this.getWs(wsKey);
510
+ if (!ws) {
511
+ throw new Error(`${wsKey} socket not connected yet, call "connectAll()" first then try again when the "open" event arrives`);
512
+ }
513
+ ws.send(wsMessage);
514
+ }
515
+ catch (e) {
516
+ this.logger.error('Failed to send WS message', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsMessage,
517
+ wsKey, exception: e }));
518
+ if (throwExceptions) {
519
+ throw e;
520
+ }
521
+ }
522
+ }
523
+ onWsOpen(event, wsKey) {
524
+ return __awaiter(this, void 0, void 0, function* () {
525
+ const isFreshConnectionAttempt = this.wsStore.isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTING);
526
+ const isReconnectionAttempt = this.wsStore.isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.RECONNECTING);
527
+ if (isFreshConnectionAttempt) {
528
+ this.logger.info('Websocket connected', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey, testnet: this.options.testnet === true, market: this.options.market }));
529
+ this.emit('open', { wsKey, event });
530
+ }
531
+ else if (isReconnectionAttempt) {
532
+ this.logger.info('Websocket reconnected', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey, testnet: this.options.testnet === true, market: this.options.market }));
533
+ this.emit('reconnected', { wsKey, event });
534
+ }
535
+ this.setWsState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTED);
536
+ this.logger.trace('Enabled ping timer', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
537
+ this.wsStore.get(wsKey, true).activePingTimer = setInterval(() => this.ping(wsKey), this.options.pingInterval);
538
+ // Resolve & cleanup deferred "connection attempt in progress" promise
539
+ try {
540
+ const connectionInProgressPromise = this.wsStore.getConnectionInProgressPromise(wsKey);
541
+ if (connectionInProgressPromise === null || connectionInProgressPromise === void 0 ? void 0 : connectionInProgressPromise.resolve) {
542
+ connectionInProgressPromise.resolve({
543
+ wsKey,
544
+ });
545
+ }
546
+ }
547
+ catch (e) {
548
+ this.logger.error('Exception trying to resolve "connectionInProgress" promise');
549
+ }
550
+ // Remove before continuing, in case there's more requests queued
551
+ this.wsStore.removeConnectingInProgressPromise(wsKey);
552
+ // Reconnect to topics known before it connected
553
+ const { privateReqs, publicReqs } = this.sortTopicRequestsIntoPublicPrivate([...this.wsStore.getTopics(wsKey)], wsKey);
554
+ // Request sub to public topics, if any
555
+ this.requestSubscribeTopics(wsKey, publicReqs);
556
+ // Request sub to private topics, if auth on connect isn't needed
557
+ // Else, this is automatic after authentication is successfully confirmed
558
+ if (!this.options.authPrivateConnectionsOnConnect) {
559
+ this.requestSubscribeTopics(wsKey, privateReqs);
560
+ }
561
+ // Some websockets require an auth packet to be sent after opening the connection
562
+ if (this.isAuthOnConnectWsKey(wsKey) &&
563
+ this.options.authPrivateConnectionsOnConnect) {
564
+ yield this.sendAuthRequest(wsKey);
565
+ }
566
+ });
567
+ }
568
+ /**
569
+ * Handle subscription to private topics _after_ authentication successfully completes asynchronously.
570
+ *
571
+ * Only used for exchanges that require auth before sending private topic subscription requests
572
+ */
573
+ onWsAuthenticated(wsKey, event) {
574
+ const wsState = this.wsStore.get(wsKey, true);
575
+ wsState.isAuthenticated = true;
576
+ // Resolve & cleanup deferred "connection attempt in progress" promise
577
+ try {
578
+ const inProgressPromise = this.wsStore.getAuthenticationInProgressPromise(wsKey);
579
+ if (inProgressPromise === null || inProgressPromise === void 0 ? void 0 : inProgressPromise.resolve) {
580
+ inProgressPromise.resolve({
581
+ wsKey,
582
+ event,
583
+ });
584
+ }
585
+ }
586
+ catch (e) {
587
+ this.logger.error('Exception trying to resolve "connectionInProgress" promise');
588
+ }
589
+ // Remove before continuing, in case there's more requests queued
590
+ this.wsStore.removeAuthenticationInProgressPromise(wsKey);
591
+ if (this.options.authPrivateConnectionsOnConnect) {
592
+ const topics = [...this.wsStore.getTopics(wsKey)];
593
+ const privateTopics = topics.filter((topic) => this.isPrivateTopicRequest(topic, wsKey));
594
+ if (privateTopics.length) {
595
+ this.subscribeTopicsForWsKey(privateTopics, wsKey);
596
+ }
597
+ }
598
+ }
599
+ onWsMessage(event, wsKey, ws) {
600
+ try {
601
+ // console.log('onMessageRaw: ', (event as any).data);
602
+ // any message can clear the pong timer - wouldn't get a message if the ws wasn't working
603
+ this.clearPongTimer(wsKey);
604
+ if (this.isWsPong(event)) {
605
+ this.logger.trace('Received pong', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey, event: event === null || event === void 0 ? void 0 : event.data }));
606
+ return;
607
+ }
608
+ if (this.isWsPing(event)) {
609
+ this.logger.trace('Received ping', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey,
610
+ event }));
611
+ this.sendPongEvent(wsKey, ws);
612
+ return;
613
+ }
614
+ if ((0, types_1.isMessageEvent)(event)) {
615
+ const data = event.data;
616
+ const dataType = event.type;
617
+ const emittableEvents = this.resolveEmittableEvents(wsKey, event);
618
+ if (!emittableEvents.length) {
619
+ // console.log(`raw event: `, { data, dataType, emittableEvents });
620
+ this.logger.error('Unhandled/unrecognised ws event message - returned no emittable data', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { message: data || 'no message', dataType,
621
+ event,
622
+ wsKey }));
623
+ return this.emit('update', Object.assign(Object.assign({}, event), { wsKey }));
624
+ }
625
+ for (const emittable of emittableEvents) {
626
+ // if (emittable.event?.op) {
627
+ // console.log('emittable: ', emittable);
628
+ // }
629
+ if (this.isWsPong(emittable)) {
630
+ this.logger.trace('Received pong2', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey,
631
+ data }));
632
+ continue;
633
+ }
634
+ const emittableFinalEvent = Object.assign(Object.assign({}, emittable.event), { wsKey, isWSAPIResponse: emittable.isWSAPIResponse });
635
+ if (emittable.eventType === 'authenticated') {
636
+ this.logger.trace('Successfully authenticated', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey,
637
+ emittable }));
638
+ this.emit(emittable.eventType, emittableFinalEvent);
639
+ this.onWsAuthenticated(wsKey, emittable.event);
640
+ continue;
641
+ }
642
+ this.emit(emittable.eventType, emittableFinalEvent);
643
+ }
644
+ return;
645
+ }
646
+ this.logger.error('Unhandled/unrecognised ws event message - unexpected message format', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { message: event || 'no message', event,
647
+ wsKey }));
648
+ }
649
+ catch (e) {
650
+ this.logger.error('Failed to parse ws event message', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { error: e, event,
651
+ wsKey }));
652
+ }
653
+ }
654
+ onWsClose(event, wsKey) {
655
+ this.logger.info('Websocket connection closed', Object.assign(Object.assign({}, websockets_1.WS_LOGGER_CATEGORY), { wsKey }));
656
+ const wsState = this.wsStore.get(wsKey, true);
657
+ wsState.isAuthenticated = false;
658
+ if (this.wsStore.getConnectionState(wsKey) !== websockets_1.WsConnectionStateEnum.CLOSING) {
659
+ // clean up any pending promises for this connection
660
+ this.getWsStore().rejectAllDeferredPromises(wsKey, 'connection lost, reconnecting');
661
+ this.clearTopicsPendingSubscriptions(wsKey, true, 'WS Closed');
662
+ this.setWsState(wsKey, websockets_1.WsConnectionStateEnum.INITIAL);
663
+ this.reconnectWithDelay(wsKey, this.options.reconnectTimeout);
664
+ this.emit('reconnect', { wsKey, event });
665
+ }
666
+ else {
667
+ // clean up any pending promises for this connection
668
+ this.getWsStore().rejectAllDeferredPromises(wsKey, 'disconnected');
669
+ this.setWsState(wsKey, websockets_1.WsConnectionStateEnum.INITIAL);
670
+ this.emit('close', { wsKey, event });
671
+ }
672
+ }
673
+ getWs(wsKey) {
674
+ return this.wsStore.getWs(wsKey);
675
+ }
676
+ setWsState(wsKey, state) {
677
+ this.wsStore.setConnectionState(wsKey, state);
678
+ }
679
+ /**
680
+ * Promise-driven method to assert that a ws has successfully connected (will await until connection is open)
681
+ */
682
+ assertIsConnected(wsKey) {
683
+ return __awaiter(this, void 0, void 0, function* () {
684
+ const isConnected = this.getWsStore().isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTED);
685
+ if (!isConnected) {
686
+ const inProgressPromise = this.getWsStore().getConnectionInProgressPromise(wsKey);
687
+ // Already in progress? Await shared promise and retry
688
+ if (inProgressPromise) {
689
+ this.logger.trace('assertIsConnected(): awaiting...');
690
+ yield inProgressPromise.promise;
691
+ this.logger.trace('assertIsConnected(): connected!');
692
+ return inProgressPromise.promise;
693
+ }
694
+ // Start connection, it should automatically store/return a promise.
695
+ this.logger.trace('assertIsConnected(): connecting...');
696
+ yield this.connect(wsKey);
697
+ this.logger.trace('assertIsConnected(): newly connected!');
698
+ }
699
+ });
700
+ }
701
+ /**
702
+ * Promise-driven method to assert that a ws has been successfully authenticated (will await until auth is confirmed)
703
+ */
704
+ assertIsAuthenticated(wsKey) {
705
+ return __awaiter(this, void 0, void 0, function* () {
706
+ var _a;
707
+ const isConnected = this.getWsStore().isConnectionState(wsKey, websockets_1.WsConnectionStateEnum.CONNECTED);
708
+ if (!isConnected) {
709
+ this.logger.trace('assertIsAuthenticated(): connecting...');
710
+ yield this.assertIsConnected(wsKey);
711
+ }
712
+ const inProgressPromise = this.getWsStore().getAuthenticationInProgressPromise(wsKey);
713
+ // Already in progress? Await shared promise and retry
714
+ if (inProgressPromise) {
715
+ this.logger.trace('assertIsAuthenticated(): awaiting...');
716
+ yield inProgressPromise.promise;
717
+ this.logger.trace('assertIsAuthenticated(): authenticated!');
718
+ return;
719
+ }
720
+ const isAuthenticated = (_a = this.wsStore.get(wsKey)) === null || _a === void 0 ? void 0 : _a.isAuthenticated;
721
+ if (isAuthenticated) {
722
+ this.logger.trace('assertIsAuthenticated(): ok');
723
+ return;
724
+ }
725
+ // Start authentication, it should automatically store/return a promise.
726
+ this.logger.trace('assertIsAuthenticated(): authenticating...');
727
+ yield this.sendAuthRequest(wsKey);
728
+ this.logger.trace('assertIsAuthenticated(): newly authenticated!');
729
+ });
730
+ }
731
+ }
732
+ exports.BaseWebsocketClient = BaseWebsocketClient;
733
+ //# sourceMappingURL=BaseWSClient.js.map