@siebly/kraken-api 0.0.9
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.
- package/LICENSE.md +7 -0
- package/README.md +624 -0
- package/dist/cjs/DerivativesClient.d.ts +657 -0
- package/dist/cjs/DerivativesClient.js +726 -0
- package/dist/cjs/DerivativesClient.js.map +1 -0
- package/dist/cjs/InstitutionalClient.d.ts +183 -0
- package/dist/cjs/InstitutionalClient.js +266 -0
- package/dist/cjs/InstitutionalClient.js.map +1 -0
- package/dist/cjs/PartnerClient.d.ts +257 -0
- package/dist/cjs/PartnerClient.js +344 -0
- package/dist/cjs/PartnerClient.js.map +1 -0
- package/dist/cjs/SpotClient.d.ts +547 -0
- package/dist/cjs/SpotClient.js +607 -0
- package/dist/cjs/SpotClient.js.map +1 -0
- package/dist/cjs/WebsocketAPIClient.d.ts +95 -0
- package/dist/cjs/WebsocketAPIClient.js +136 -0
- package/dist/cjs/WebsocketAPIClient.js.map +1 -0
- package/dist/cjs/WebsocketClient.d.ts +120 -0
- package/dist/cjs/WebsocketClient.js +669 -0
- package/dist/cjs/WebsocketClient.js.map +1 -0
- package/dist/cjs/index.d.ts +24 -0
- package/dist/cjs/index.js +41 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lib/BaseRestClient.d.ts +66 -0
- package/dist/cjs/lib/BaseRestClient.js +548 -0
- package/dist/cjs/lib/BaseRestClient.js.map +1 -0
- package/dist/cjs/lib/BaseWSClient.d.ts +230 -0
- package/dist/cjs/lib/BaseWSClient.js +935 -0
- package/dist/cjs/lib/BaseWSClient.js.map +1 -0
- package/dist/cjs/lib/misc-util.d.ts +1 -0
- package/dist/cjs/lib/misc-util.js +7 -0
- package/dist/cjs/lib/misc-util.js.map +1 -0
- package/dist/cjs/lib/requestUtils.d.ts +68 -0
- package/dist/cjs/lib/requestUtils.js +82 -0
- package/dist/cjs/lib/requestUtils.js.map +1 -0
- package/dist/cjs/lib/webCryptoAPI.d.ts +15 -0
- package/dist/cjs/lib/webCryptoAPI.js +85 -0
- package/dist/cjs/lib/webCryptoAPI.js.map +1 -0
- package/dist/cjs/lib/websocket/WsStore.d.ts +75 -0
- package/dist/cjs/lib/websocket/WsStore.js +303 -0
- package/dist/cjs/lib/websocket/WsStore.js.map +1 -0
- package/dist/cjs/lib/websocket/WsStore.types.d.ts +51 -0
- package/dist/cjs/lib/websocket/WsStore.types.js +14 -0
- package/dist/cjs/lib/websocket/WsStore.types.js.map +1 -0
- package/dist/cjs/lib/websocket/logger.d.ts +7 -0
- package/dist/cjs/lib/websocket/logger.js +16 -0
- package/dist/cjs/lib/websocket/logger.js.map +1 -0
- package/dist/cjs/lib/websocket/rest-client-cache.d.ts +22 -0
- package/dist/cjs/lib/websocket/rest-client-cache.js +66 -0
- package/dist/cjs/lib/websocket/rest-client-cache.js.map +1 -0
- package/dist/cjs/lib/websocket/websocket-util.d.ts +76 -0
- package/dist/cjs/lib/websocket/websocket-util.js +59 -0
- package/dist/cjs/lib/websocket/websocket-util.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/types/request/derivatives.types.d.ts +186 -0
- package/dist/cjs/types/request/derivatives.types.js +6 -0
- package/dist/cjs/types/request/derivatives.types.js.map +1 -0
- package/dist/cjs/types/request/institutional.types.d.ts +313 -0
- package/dist/cjs/types/request/institutional.types.js +4 -0
- package/dist/cjs/types/request/institutional.types.js.map +1 -0
- package/dist/cjs/types/request/partner.types.d.ts +291 -0
- package/dist/cjs/types/request/partner.types.js +4 -0
- package/dist/cjs/types/request/partner.types.js.map +1 -0
- package/dist/cjs/types/request/spot.types.d.ts +324 -0
- package/dist/cjs/types/request/spot.types.js +6 -0
- package/dist/cjs/types/request/spot.types.js.map +1 -0
- package/dist/cjs/types/request/wsapi.types.d.ts +90 -0
- package/dist/cjs/types/request/wsapi.types.js +6 -0
- package/dist/cjs/types/request/wsapi.types.js.map +1 -0
- package/dist/cjs/types/response/derivatives.types.d.ts +712 -0
- package/dist/cjs/types/response/derivatives.types.js +6 -0
- package/dist/cjs/types/response/derivatives.types.js.map +1 -0
- package/dist/cjs/types/response/institutional.types.d.ts +318 -0
- package/dist/cjs/types/response/institutional.types.js +4 -0
- package/dist/cjs/types/response/institutional.types.js.map +1 -0
- package/dist/cjs/types/response/partner.types.d.ts +332 -0
- package/dist/cjs/types/response/partner.types.js +4 -0
- package/dist/cjs/types/response/partner.types.js.map +1 -0
- package/dist/cjs/types/response/shared.types.d.ts +27 -0
- package/dist/cjs/types/response/shared.types.js +3 -0
- package/dist/cjs/types/response/shared.types.js.map +1 -0
- package/dist/cjs/types/response/spot.types.d.ts +590 -0
- package/dist/cjs/types/response/spot.types.js +6 -0
- package/dist/cjs/types/response/spot.types.js.map +1 -0
- package/dist/cjs/types/response/ws.d.ts +11 -0
- package/dist/cjs/types/response/ws.js +3 -0
- package/dist/cjs/types/response/ws.js.map +1 -0
- package/dist/cjs/types/response/wsapi.types.d.ts +44 -0
- package/dist/cjs/types/response/wsapi.types.js +6 -0
- package/dist/cjs/types/response/wsapi.types.js.map +1 -0
- package/dist/cjs/types/websockets/ws-api.d.ts +71 -0
- package/dist/cjs/types/websockets/ws-api.js +18 -0
- package/dist/cjs/types/websockets/ws-api.js.map +1 -0
- package/dist/cjs/types/websockets/ws-events.d.ts +11 -0
- package/dist/cjs/types/websockets/ws-events.js +11 -0
- package/dist/cjs/types/websockets/ws-events.js.map +1 -0
- package/dist/cjs/types/websockets/ws-general.d.ts +67 -0
- package/dist/cjs/types/websockets/ws-general.js +3 -0
- package/dist/cjs/types/websockets/ws-general.js.map +1 -0
- package/dist/cjs/types/websockets/ws-subscriptions.d.ts +11 -0
- package/dist/cjs/types/websockets/ws-subscriptions.js +31 -0
- package/dist/cjs/types/websockets/ws-subscriptions.js.map +1 -0
- package/dist/mjs/DerivativesClient.d.ts +657 -0
- package/dist/mjs/DerivativesClient.js +722 -0
- package/dist/mjs/DerivativesClient.js.map +1 -0
- package/dist/mjs/InstitutionalClient.d.ts +183 -0
- package/dist/mjs/InstitutionalClient.js +262 -0
- package/dist/mjs/InstitutionalClient.js.map +1 -0
- package/dist/mjs/PartnerClient.d.ts +257 -0
- package/dist/mjs/PartnerClient.js +340 -0
- package/dist/mjs/PartnerClient.js.map +1 -0
- package/dist/mjs/SpotClient.d.ts +547 -0
- package/dist/mjs/SpotClient.js +603 -0
- package/dist/mjs/SpotClient.js.map +1 -0
- package/dist/mjs/WebsocketAPIClient.d.ts +95 -0
- package/dist/mjs/WebsocketAPIClient.js +132 -0
- package/dist/mjs/WebsocketAPIClient.js.map +1 -0
- package/dist/mjs/WebsocketClient.d.ts +120 -0
- package/dist/mjs/WebsocketClient.js +665 -0
- package/dist/mjs/WebsocketClient.js.map +1 -0
- package/dist/mjs/index.d.ts +24 -0
- package/dist/mjs/index.js +25 -0
- package/dist/mjs/index.js.map +1 -0
- package/dist/mjs/lib/BaseRestClient.d.ts +66 -0
- package/dist/mjs/lib/BaseRestClient.js +541 -0
- package/dist/mjs/lib/BaseRestClient.js.map +1 -0
- package/dist/mjs/lib/BaseWSClient.d.ts +230 -0
- package/dist/mjs/lib/BaseWSClient.js +928 -0
- package/dist/mjs/lib/BaseWSClient.js.map +1 -0
- package/dist/mjs/lib/misc-util.d.ts +1 -0
- package/dist/mjs/lib/misc-util.js +4 -0
- package/dist/mjs/lib/misc-util.js.map +1 -0
- package/dist/mjs/lib/requestUtils.d.ts +68 -0
- package/dist/mjs/lib/requestUtils.js +76 -0
- package/dist/mjs/lib/requestUtils.js.map +1 -0
- package/dist/mjs/lib/webCryptoAPI.d.ts +15 -0
- package/dist/mjs/lib/webCryptoAPI.js +80 -0
- package/dist/mjs/lib/webCryptoAPI.js.map +1 -0
- package/dist/mjs/lib/websocket/WsStore.d.ts +75 -0
- package/dist/mjs/lib/websocket/WsStore.js +298 -0
- package/dist/mjs/lib/websocket/WsStore.js.map +1 -0
- package/dist/mjs/lib/websocket/WsStore.types.d.ts +51 -0
- package/dist/mjs/lib/websocket/WsStore.types.js +11 -0
- package/dist/mjs/lib/websocket/WsStore.types.js.map +1 -0
- package/dist/mjs/lib/websocket/logger.d.ts +7 -0
- package/dist/mjs/lib/websocket/logger.js +13 -0
- package/dist/mjs/lib/websocket/logger.js.map +1 -0
- package/dist/mjs/lib/websocket/rest-client-cache.d.ts +22 -0
- package/dist/mjs/lib/websocket/rest-client-cache.js +62 -0
- package/dist/mjs/lib/websocket/rest-client-cache.js.map +1 -0
- package/dist/mjs/lib/websocket/websocket-util.d.ts +76 -0
- package/dist/mjs/lib/websocket/websocket-util.js +54 -0
- package/dist/mjs/lib/websocket/websocket-util.js.map +1 -0
- package/dist/mjs/package.json +3 -0
- package/dist/mjs/types/request/derivatives.types.d.ts +186 -0
- package/dist/mjs/types/request/derivatives.types.js +5 -0
- package/dist/mjs/types/request/derivatives.types.js.map +1 -0
- package/dist/mjs/types/request/institutional.types.d.ts +313 -0
- package/dist/mjs/types/request/institutional.types.js +3 -0
- package/dist/mjs/types/request/institutional.types.js.map +1 -0
- package/dist/mjs/types/request/partner.types.d.ts +291 -0
- package/dist/mjs/types/request/partner.types.js +3 -0
- package/dist/mjs/types/request/partner.types.js.map +1 -0
- package/dist/mjs/types/request/spot.types.d.ts +324 -0
- package/dist/mjs/types/request/spot.types.js +5 -0
- package/dist/mjs/types/request/spot.types.js.map +1 -0
- package/dist/mjs/types/request/wsapi.types.d.ts +90 -0
- package/dist/mjs/types/request/wsapi.types.js +5 -0
- package/dist/mjs/types/request/wsapi.types.js.map +1 -0
- package/dist/mjs/types/response/derivatives.types.d.ts +712 -0
- package/dist/mjs/types/response/derivatives.types.js +5 -0
- package/dist/mjs/types/response/derivatives.types.js.map +1 -0
- package/dist/mjs/types/response/institutional.types.d.ts +318 -0
- package/dist/mjs/types/response/institutional.types.js +3 -0
- package/dist/mjs/types/response/institutional.types.js.map +1 -0
- package/dist/mjs/types/response/partner.types.d.ts +332 -0
- package/dist/mjs/types/response/partner.types.js +3 -0
- package/dist/mjs/types/response/partner.types.js.map +1 -0
- package/dist/mjs/types/response/shared.types.d.ts +27 -0
- package/dist/mjs/types/response/shared.types.js +2 -0
- package/dist/mjs/types/response/shared.types.js.map +1 -0
- package/dist/mjs/types/response/spot.types.d.ts +590 -0
- package/dist/mjs/types/response/spot.types.js +5 -0
- package/dist/mjs/types/response/spot.types.js.map +1 -0
- package/dist/mjs/types/response/ws.d.ts +11 -0
- package/dist/mjs/types/response/ws.js +2 -0
- package/dist/mjs/types/response/ws.js.map +1 -0
- package/dist/mjs/types/response/wsapi.types.d.ts +44 -0
- package/dist/mjs/types/response/wsapi.types.js +5 -0
- package/dist/mjs/types/response/wsapi.types.js.map +1 -0
- package/dist/mjs/types/websockets/ws-api.d.ts +71 -0
- package/dist/mjs/types/websockets/ws-api.js +15 -0
- package/dist/mjs/types/websockets/ws-api.js.map +1 -0
- package/dist/mjs/types/websockets/ws-events.d.ts +11 -0
- package/dist/mjs/types/websockets/ws-events.js +8 -0
- package/dist/mjs/types/websockets/ws-events.js.map +1 -0
- package/dist/mjs/types/websockets/ws-general.d.ts +67 -0
- package/dist/mjs/types/websockets/ws-general.js +2 -0
- package/dist/mjs/types/websockets/ws-general.js.map +1 -0
- package/dist/mjs/types/websockets/ws-subscriptions.d.ts +11 -0
- package/dist/mjs/types/websockets/ws-subscriptions.js +28 -0
- package/dist/mjs/types/websockets/ws-subscriptions.js.map +1 -0
- package/llms.txt +10925 -0
- package/package.json +89 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { DefaultLogger } from './logger.js';
|
|
2
|
+
import { WsConnectionStateEnum, } from './WsStore.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Simple comparison of two objects, recursive for nested objects. Adoped from OKX SDK.
|
|
5
|
+
*/
|
|
6
|
+
export function isDeepObjectMatch(object1, object2) {
|
|
7
|
+
if (typeof object2 !== typeof object1) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const keys1 = Object.keys(object1).sort();
|
|
11
|
+
const keys2 = Object.keys(object2).sort();
|
|
12
|
+
const hasSameKeyCount = keys1.length === keys2.length;
|
|
13
|
+
if (!hasSameKeyCount) {
|
|
14
|
+
// console.log('not same key count', { keys1, keys2 });
|
|
15
|
+
// not the same amount of keys or keys don't match
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const hasSameKeyNames = keys1.every((val, i) => val === keys2[i]);
|
|
19
|
+
if (!hasSameKeyNames) {
|
|
20
|
+
// console.log('not same key names: ', { keys1, keys2 });
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
for (const key in object1) {
|
|
24
|
+
const value1 = object1[key];
|
|
25
|
+
const value2 = object2[key];
|
|
26
|
+
if (typeof value1 === 'object' && typeof value2 === 'object') {
|
|
27
|
+
if (!isDeepObjectMatch(value1, value2)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (value1 !== value2) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
const DEFERRED_PROMISE_REF = {
|
|
38
|
+
CONNECTION_IN_PROGRESS: 'CONNECTION_IN_PROGRESS',
|
|
39
|
+
AUTHENTICATION_IN_PROGRESS: 'AUTHENTICATION_IN_PROGRESS',
|
|
40
|
+
};
|
|
41
|
+
export class WsStore {
|
|
42
|
+
wsState = {};
|
|
43
|
+
logger;
|
|
44
|
+
constructor(logger) {
|
|
45
|
+
this.logger = logger || DefaultLogger;
|
|
46
|
+
}
|
|
47
|
+
get(key, createIfMissing) {
|
|
48
|
+
if (this.wsState[key]) {
|
|
49
|
+
return this.wsState[key];
|
|
50
|
+
}
|
|
51
|
+
if (createIfMissing) {
|
|
52
|
+
return this.create(key);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
getKeys() {
|
|
56
|
+
return Object.keys(this.wsState);
|
|
57
|
+
}
|
|
58
|
+
create(key) {
|
|
59
|
+
if (this.hasExistingActiveConnection(key)) {
|
|
60
|
+
this.logger.info('WsStore setConnection() overwriting existing open connection: ', this.getWs(key));
|
|
61
|
+
}
|
|
62
|
+
this.wsState[key] = {
|
|
63
|
+
subscribedTopics: new Set(),
|
|
64
|
+
connectionState: WsConnectionStateEnum.INITIAL,
|
|
65
|
+
deferredPromiseStore: {},
|
|
66
|
+
};
|
|
67
|
+
return this.get(key);
|
|
68
|
+
}
|
|
69
|
+
delete(key) {
|
|
70
|
+
// TODO: should we allow this at all? Perhaps block this from happening...
|
|
71
|
+
if (this.hasExistingActiveConnection(key)) {
|
|
72
|
+
const ws = this.getWs(key);
|
|
73
|
+
this.logger.info('WsStore deleting state for connection still open: ', ws);
|
|
74
|
+
ws?.close();
|
|
75
|
+
}
|
|
76
|
+
delete this.wsState[key];
|
|
77
|
+
}
|
|
78
|
+
/* connection websocket */
|
|
79
|
+
hasExistingActiveConnection(key) {
|
|
80
|
+
return this.get(key) && this.isWsOpen(key);
|
|
81
|
+
}
|
|
82
|
+
getWs(key) {
|
|
83
|
+
return this.get(key)?.ws;
|
|
84
|
+
}
|
|
85
|
+
setWs(key, wsConnection) {
|
|
86
|
+
if (this.isWsOpen(key)) {
|
|
87
|
+
this.logger.info('WsStore setConnection() overwriting existing open connection: ', this.getWs(key));
|
|
88
|
+
}
|
|
89
|
+
this.get(key, true).ws = wsConnection;
|
|
90
|
+
return wsConnection;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* deferred promises
|
|
94
|
+
*/
|
|
95
|
+
getDeferredPromise(wsKey, promiseRef) {
|
|
96
|
+
const storeForKey = this.get(wsKey);
|
|
97
|
+
if (!storeForKey) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const deferredPromiseStore = storeForKey.deferredPromiseStore;
|
|
101
|
+
return deferredPromiseStore[promiseRef];
|
|
102
|
+
}
|
|
103
|
+
createDeferredPromise(wsKey, promiseRef, throwIfExists) {
|
|
104
|
+
const existingPromise = this.getDeferredPromise(wsKey, promiseRef);
|
|
105
|
+
if (existingPromise) {
|
|
106
|
+
if (throwIfExists) {
|
|
107
|
+
throw new Error(`Promise exists for "${wsKey}"`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// console.log('existing promise');
|
|
111
|
+
return existingPromise;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// console.log('create promise');
|
|
115
|
+
const createIfMissing = true;
|
|
116
|
+
const storeForKey = this.get(wsKey, createIfMissing);
|
|
117
|
+
// TODO: Once stable, use Promise.withResolvers in future
|
|
118
|
+
const deferredPromise = {};
|
|
119
|
+
deferredPromise.promise = new Promise((resolve, reject) => {
|
|
120
|
+
deferredPromise.resolve = resolve;
|
|
121
|
+
deferredPromise.reject = reject;
|
|
122
|
+
});
|
|
123
|
+
const deferredPromiseStore = storeForKey.deferredPromiseStore;
|
|
124
|
+
deferredPromiseStore[promiseRef] = deferredPromise;
|
|
125
|
+
return deferredPromise;
|
|
126
|
+
}
|
|
127
|
+
resolveDeferredPromise(wsKey, promiseRef, value, removeAfter) {
|
|
128
|
+
const promise = this.getDeferredPromise(wsKey, promiseRef);
|
|
129
|
+
if (promise?.resolve) {
|
|
130
|
+
promise.resolve(value);
|
|
131
|
+
}
|
|
132
|
+
if (removeAfter) {
|
|
133
|
+
this.removeDeferredPromise(wsKey, promiseRef);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
rejectDeferredPromise(wsKey, promiseRef, value, removeAfter) {
|
|
137
|
+
const promise = this.getDeferredPromise(wsKey, promiseRef);
|
|
138
|
+
if (promise?.reject) {
|
|
139
|
+
this.logger.trace(`rejectDeferredPromise(): rejecting ${wsKey}/${promiseRef}`, value);
|
|
140
|
+
if (typeof value === 'string') {
|
|
141
|
+
promise.reject(new Error(value));
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
promise.reject(value);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (removeAfter) {
|
|
148
|
+
this.removeDeferredPromise(wsKey, promiseRef);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
removeDeferredPromise(wsKey, promiseRef) {
|
|
152
|
+
const storeForKey = this.get(wsKey);
|
|
153
|
+
if (!storeForKey) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const deferredPromise = storeForKey.deferredPromiseStore[promiseRef];
|
|
157
|
+
if (deferredPromise) {
|
|
158
|
+
// Just in case it's pending
|
|
159
|
+
if (deferredPromise.resolve) {
|
|
160
|
+
deferredPromise.resolve('promiseRemoved');
|
|
161
|
+
}
|
|
162
|
+
delete storeForKey.deferredPromiseStore[promiseRef];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
rejectAllDeferredPromises(wsKey, reason) {
|
|
166
|
+
const storeForKey = this.get(wsKey);
|
|
167
|
+
const deferredPromiseStore = storeForKey.deferredPromiseStore;
|
|
168
|
+
if (!storeForKey || !deferredPromiseStore) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const reservedKeys = Object.values(DEFERRED_PROMISE_REF);
|
|
172
|
+
for (const promiseRef in deferredPromiseStore) {
|
|
173
|
+
// Skip reserved keys, such as the connection promise
|
|
174
|
+
if (reservedKeys.includes(promiseRef)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
this.logger.trace(`rejectAllDeferredPromises(): rejecting ${wsKey}/${promiseRef}/${reason}`);
|
|
179
|
+
this.rejectDeferredPromise(wsKey, promiseRef, reason, true);
|
|
180
|
+
}
|
|
181
|
+
catch (e) {
|
|
182
|
+
this.logger.error('rejectAllDeferredPromises(): Exception rejecting deferred promise', { wsKey: wsKey, reason, promiseRef, exception: e });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/** Get promise designed to track a connection attempt in progress. Resolves once connected. */
|
|
187
|
+
getConnectionInProgressPromise(wsKey) {
|
|
188
|
+
return this.getDeferredPromise(wsKey, DEFERRED_PROMISE_REF.CONNECTION_IN_PROGRESS);
|
|
189
|
+
}
|
|
190
|
+
getAuthenticationInProgressPromise(wsKey) {
|
|
191
|
+
return this.getDeferredPromise(wsKey, DEFERRED_PROMISE_REF.AUTHENTICATION_IN_PROGRESS);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create a deferred promise designed to track a connection attempt in progress.
|
|
195
|
+
*
|
|
196
|
+
* Will throw if existing promise is found.
|
|
197
|
+
*/
|
|
198
|
+
createConnectionInProgressPromise(wsKey, throwIfExists) {
|
|
199
|
+
return this.createDeferredPromise(wsKey, DEFERRED_PROMISE_REF.CONNECTION_IN_PROGRESS, throwIfExists);
|
|
200
|
+
}
|
|
201
|
+
createAuthenticationInProgressPromise(wsKey, throwIfExists) {
|
|
202
|
+
return this.createDeferredPromise(wsKey, DEFERRED_PROMISE_REF.AUTHENTICATION_IN_PROGRESS, throwIfExists);
|
|
203
|
+
}
|
|
204
|
+
/** Remove promise designed to track a connection attempt in progress */
|
|
205
|
+
removeConnectingInProgressPromise(wsKey) {
|
|
206
|
+
return this.removeDeferredPromise(wsKey, DEFERRED_PROMISE_REF.CONNECTION_IN_PROGRESS);
|
|
207
|
+
}
|
|
208
|
+
removeAuthenticationInProgressPromise(wsKey) {
|
|
209
|
+
return this.removeDeferredPromise(wsKey, DEFERRED_PROMISE_REF.AUTHENTICATION_IN_PROGRESS);
|
|
210
|
+
}
|
|
211
|
+
/* connection state */
|
|
212
|
+
isWsOpen(key) {
|
|
213
|
+
const existingConnection = this.getWs(key);
|
|
214
|
+
return (!!existingConnection &&
|
|
215
|
+
existingConnection.readyState === existingConnection.OPEN);
|
|
216
|
+
}
|
|
217
|
+
getConnectionState(key) {
|
|
218
|
+
return this.get(key, true).connectionState;
|
|
219
|
+
}
|
|
220
|
+
setConnectionState(key, state) {
|
|
221
|
+
this.get(key, true).connectionState = state;
|
|
222
|
+
this.get(key, true).connectionStateChangedAt = new Date();
|
|
223
|
+
}
|
|
224
|
+
isConnectionState(key, state) {
|
|
225
|
+
return this.getConnectionState(key) === state;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Check if we're currently in the process of opening a connection for any reason. Safer than only checking "CONNECTING" as the state
|
|
229
|
+
* @param key
|
|
230
|
+
* @returns
|
|
231
|
+
*/
|
|
232
|
+
isConnectionAttemptInProgress(key) {
|
|
233
|
+
const isConnectionInProgress = this.isConnectionState(key, WsConnectionStateEnum.CONNECTING) ||
|
|
234
|
+
this.isConnectionState(key, WsConnectionStateEnum.RECONNECTING);
|
|
235
|
+
if (isConnectionInProgress) {
|
|
236
|
+
const wsState = this.get(key, true);
|
|
237
|
+
const stateLastChangedAt = wsState?.connectionStateChangedAt;
|
|
238
|
+
const stateChangedAtTimestamp = stateLastChangedAt?.getTime();
|
|
239
|
+
if (stateChangedAtTimestamp) {
|
|
240
|
+
const timestampNow = new Date().getTime();
|
|
241
|
+
const stateChangedTimeAgo = timestampNow - stateChangedAtTimestamp;
|
|
242
|
+
const stateChangeTimeout = 15000; // allow a max 15 second timeout since the last state change before assuming stuck;
|
|
243
|
+
if (stateChangedTimeAgo >= stateChangeTimeout) {
|
|
244
|
+
const msg = 'State change timed out, reconnect workflow stuck?';
|
|
245
|
+
this.logger.error(msg, { key, wsState });
|
|
246
|
+
this.setConnectionState(key, WsConnectionStateEnum.ERROR);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return isConnectionInProgress;
|
|
251
|
+
}
|
|
252
|
+
/* subscribed topics */
|
|
253
|
+
getTopics(key) {
|
|
254
|
+
return this.get(key, true).subscribedTopics;
|
|
255
|
+
}
|
|
256
|
+
getTopicsAsArray(key) {
|
|
257
|
+
return [...this.getTopics(key).values()];
|
|
258
|
+
}
|
|
259
|
+
getTopicsByKey() {
|
|
260
|
+
const result = {};
|
|
261
|
+
for (const refKey in this.wsState) {
|
|
262
|
+
result[refKey] = this.getTopics(refKey);
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Find matching "topic" request from the store
|
|
268
|
+
* @param key
|
|
269
|
+
* @param topic
|
|
270
|
+
* @returns
|
|
271
|
+
*/
|
|
272
|
+
getMatchingTopic(key, topic) {
|
|
273
|
+
const allTopics = this.getTopics(key).values();
|
|
274
|
+
for (const storedTopic of allTopics) {
|
|
275
|
+
const matchesStoredTopic = isDeepObjectMatch(topic, storedTopic);
|
|
276
|
+
if (matchesStoredTopic) {
|
|
277
|
+
return storedTopic;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
addTopic(key, topic) {
|
|
282
|
+
// Check for duplicate topic. If already tracked, don't store this one
|
|
283
|
+
const existingTopic = this.getMatchingTopic(key, topic);
|
|
284
|
+
if (existingTopic) {
|
|
285
|
+
return this.getTopics(key);
|
|
286
|
+
}
|
|
287
|
+
return this.getTopics(key).add(topic);
|
|
288
|
+
}
|
|
289
|
+
deleteTopic(key, topic) {
|
|
290
|
+
// Check if we're subscribed to a topic like this
|
|
291
|
+
const storedTopic = this.getMatchingTopic(key, topic);
|
|
292
|
+
if (storedTopic) {
|
|
293
|
+
this.getTopics(key).delete(storedTopic);
|
|
294
|
+
}
|
|
295
|
+
return this.getTopics(key);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=WsStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WsStore.js","sourceRoot":"","sources":["../../../../src/lib/websocket/WsStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import WebSocket from 'isomorphic-ws';
|
|
2
|
+
export declare enum WsConnectionStateEnum {
|
|
3
|
+
INITIAL = 0,
|
|
4
|
+
CONNECTING = 1,
|
|
5
|
+
CONNECTED = 2,
|
|
6
|
+
CLOSING = 3,
|
|
7
|
+
RECONNECTING = 4,
|
|
8
|
+
ERROR = 5
|
|
9
|
+
}
|
|
10
|
+
export interface DeferredPromise<TSuccess = any, TError = any> {
|
|
11
|
+
resolve?: (value: TSuccess) => TSuccess;
|
|
12
|
+
reject?: (value: TError) => TError;
|
|
13
|
+
promise?: Promise<TSuccess>;
|
|
14
|
+
}
|
|
15
|
+
export interface WSConnectedResult {
|
|
16
|
+
wsKey: string;
|
|
17
|
+
ws: WebSocket;
|
|
18
|
+
}
|
|
19
|
+
export interface WsStoredState<TWSTopicSubscribeEvent extends string | object> {
|
|
20
|
+
/** The currently active websocket connection */
|
|
21
|
+
ws?: WebSocket;
|
|
22
|
+
/** The current lifecycle state of the connection (enum) */
|
|
23
|
+
connectionState?: WsConnectionStateEnum;
|
|
24
|
+
connectionStateChangedAt?: Date;
|
|
25
|
+
/** A timer that will send an upstream heartbeat (ping) when it expires */
|
|
26
|
+
activePingTimer?: ReturnType<typeof setTimeout> | undefined;
|
|
27
|
+
/** A timer tracking that an upstream heartbeat was sent, expecting a reply before it expires */
|
|
28
|
+
activePongTimer?: ReturnType<typeof setTimeout> | undefined;
|
|
29
|
+
/** If a reconnection is in progress, this will have the timer for the delayed reconnect */
|
|
30
|
+
activeReconnectTimer?: ReturnType<typeof setTimeout> | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* When a connection attempt is in progress (even for reconnect), a promise is stored here.
|
|
33
|
+
*
|
|
34
|
+
* This promise will resolve once connected (and will then get removed);
|
|
35
|
+
*/
|
|
36
|
+
deferredPromiseStore: Record<string, DeferredPromise>;
|
|
37
|
+
/**
|
|
38
|
+
* All the topics we are expected to be subscribed to on this connection (and we automatically resubscribe to if the connection drops)
|
|
39
|
+
*
|
|
40
|
+
* A "Set" and a deep-object-match are used to ensure we only subscribe to a topic once (tracking a list of unique topics we're expected to be connected to)
|
|
41
|
+
*/
|
|
42
|
+
subscribedTopics: Set<TWSTopicSubscribeEvent>;
|
|
43
|
+
/** Whether this connection has completed authentication (only applies to private connections) */
|
|
44
|
+
isAuthenticated?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether this connection has completed authentication before for the Websocket API, so it knows to automatically reauth if reconnected
|
|
47
|
+
*/
|
|
48
|
+
didAuthWSAPI?: boolean;
|
|
49
|
+
/** To reauthenticate on the WS API, which channel do we send to? */
|
|
50
|
+
WSAPIAuthChannel?: string;
|
|
51
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export var WsConnectionStateEnum;
|
|
2
|
+
(function (WsConnectionStateEnum) {
|
|
3
|
+
WsConnectionStateEnum[WsConnectionStateEnum["INITIAL"] = 0] = "INITIAL";
|
|
4
|
+
WsConnectionStateEnum[WsConnectionStateEnum["CONNECTING"] = 1] = "CONNECTING";
|
|
5
|
+
WsConnectionStateEnum[WsConnectionStateEnum["CONNECTED"] = 2] = "CONNECTED";
|
|
6
|
+
WsConnectionStateEnum[WsConnectionStateEnum["CLOSING"] = 3] = "CLOSING";
|
|
7
|
+
WsConnectionStateEnum[WsConnectionStateEnum["RECONNECTING"] = 4] = "RECONNECTING";
|
|
8
|
+
// ERROR_RECONNECTING = 5,
|
|
9
|
+
WsConnectionStateEnum[WsConnectionStateEnum["ERROR"] = 5] = "ERROR";
|
|
10
|
+
})(WsConnectionStateEnum || (WsConnectionStateEnum = {}));
|
|
11
|
+
//# sourceMappingURL=WsStore.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WsStore.types.js","sourceRoot":"","sources":["../../../../src/lib/websocket/WsStore.types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,qBAQX;AARD,WAAY,qBAAqB;IAC/B,uEAAW,CAAA;IACX,6EAAc,CAAA;IACd,2EAAa,CAAA;IACb,uEAAW,CAAA;IACX,iFAAgB,CAAA;IAChB,0BAA0B;IAC1B,mEAAS,CAAA;AACX,CAAC,EARW,qBAAqB,KAArB,qBAAqB,QAQhC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const DefaultLogger = {
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
|
+
trace: (..._params) => {
|
|
4
|
+
// console.log(_params);
|
|
5
|
+
},
|
|
6
|
+
info: (...params) => {
|
|
7
|
+
console.info(params);
|
|
8
|
+
},
|
|
9
|
+
error: (...params) => {
|
|
10
|
+
console.error(params);
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../src/lib/websocket/logger.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,6DAA6D;IAC7D,KAAK,EAAE,CAAC,GAAG,OAAkB,EAAQ,EAAE;QACrC,wBAAwB;IAC1B,CAAC;IACD,IAAI,EAAE,CAAC,GAAG,MAAiB,EAAQ,EAAE;QACnC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IACD,KAAK,EAAE,CAAC,GAAG,MAAiB,EAAQ,EAAE;QACpC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AxiosRequestConfig } from 'axios';
|
|
2
|
+
import { DerivativesClient } from '../../DerivativesClient.js';
|
|
3
|
+
import { SpotClient } from '../../SpotClient.js';
|
|
4
|
+
import { RestClientOptions } from '../requestUtils.js';
|
|
5
|
+
import { DefaultLogger } from './logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Caches REST clients and WebSocket tokens to avoid redundant requests.
|
|
8
|
+
*/
|
|
9
|
+
export declare class RestClientCache {
|
|
10
|
+
private logger;
|
|
11
|
+
private WS_LOGGER_CATEGORY;
|
|
12
|
+
private restClients;
|
|
13
|
+
private wsTokenCache;
|
|
14
|
+
setLogger(logger: DefaultLogger, loggerCategory: object): void;
|
|
15
|
+
getSpotRESTClient(restOptions: RestClientOptions, requestOptions?: AxiosRequestConfig): SpotClient;
|
|
16
|
+
fetchSpotWebSocketToken(restOptions: RestClientOptions, requestOptions?: AxiosRequestConfig): Promise<{
|
|
17
|
+
token: string;
|
|
18
|
+
expiresAtMs: number;
|
|
19
|
+
timeLeftMs: number;
|
|
20
|
+
}>;
|
|
21
|
+
getDerivativesRESTClient(restOptions: RestClientOptions, requestOptions?: AxiosRequestConfig): DerivativesClient;
|
|
22
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { DerivativesClient } from '../../DerivativesClient.js';
|
|
2
|
+
import { SpotClient } from '../../SpotClient.js';
|
|
3
|
+
/**
|
|
4
|
+
* Caches REST clients and WebSocket tokens to avoid redundant requests.
|
|
5
|
+
*/
|
|
6
|
+
export class RestClientCache {
|
|
7
|
+
logger;
|
|
8
|
+
WS_LOGGER_CATEGORY;
|
|
9
|
+
restClients = {};
|
|
10
|
+
wsTokenCache = {};
|
|
11
|
+
setLogger(logger, loggerCategory) {
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
this.WS_LOGGER_CATEGORY = loggerCategory;
|
|
14
|
+
}
|
|
15
|
+
getSpotRESTClient(restOptions, requestOptions) {
|
|
16
|
+
if (!this.restClients.spot) {
|
|
17
|
+
this.restClients.spot = new SpotClient(restOptions, requestOptions);
|
|
18
|
+
}
|
|
19
|
+
return this.restClients.spot;
|
|
20
|
+
}
|
|
21
|
+
async fetchSpotWebSocketToken(restOptions, requestOptions) {
|
|
22
|
+
if (this.wsTokenCache.spot) {
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const timeLeftMs = this.wsTokenCache.spot.expiresAtMs - now;
|
|
25
|
+
if (timeLeftMs > 10000) {
|
|
26
|
+
this.logger.trace('Using cached spot WebSocket token', {
|
|
27
|
+
...this.WS_LOGGER_CATEGORY,
|
|
28
|
+
nowMs: now,
|
|
29
|
+
expiresAtMs: this.wsTokenCache.spot.expiresAtMs,
|
|
30
|
+
remainingMs: +timeLeftMs.toFixed(0),
|
|
31
|
+
});
|
|
32
|
+
// still valid for at least 10s
|
|
33
|
+
return { ...this.wsTokenCache.spot, timeLeftMs };
|
|
34
|
+
}
|
|
35
|
+
this.logger.trace('Spot WebSocket token expired or expiring soon, fetching new token', {
|
|
36
|
+
...this.WS_LOGGER_CATEGORY,
|
|
37
|
+
nowMs: now,
|
|
38
|
+
expiresAtMs: this.wsTokenCache.spot.expiresAtMs,
|
|
39
|
+
remainingMs: +timeLeftMs.toFixed(0),
|
|
40
|
+
});
|
|
41
|
+
delete this.wsTokenCache.spot;
|
|
42
|
+
}
|
|
43
|
+
const client = this.getSpotRESTClient(restOptions, requestOptions);
|
|
44
|
+
const tokenResult = await client.getWebSocketsToken();
|
|
45
|
+
const token = tokenResult?.result?.token;
|
|
46
|
+
if (!token) {
|
|
47
|
+
throw new Error(`Failed to fetch spot WebSocket token: ${JSON.stringify(tokenResult)}`);
|
|
48
|
+
}
|
|
49
|
+
const expiresInSec = tokenResult?.result?.expires || 900;
|
|
50
|
+
const expiresInMs = expiresInSec * 1000;
|
|
51
|
+
const expiresAtMs = Date.now() + expiresInMs;
|
|
52
|
+
this.wsTokenCache.spot = { token, expiresAtMs };
|
|
53
|
+
return { ...this.wsTokenCache.spot, timeLeftMs: expiresInMs };
|
|
54
|
+
}
|
|
55
|
+
getDerivativesRESTClient(restOptions, requestOptions) {
|
|
56
|
+
if (!this.restClients.derivatives) {
|
|
57
|
+
this.restClients.derivatives = new DerivativesClient(restOptions, requestOptions);
|
|
58
|
+
}
|
|
59
|
+
return this.restClients.derivatives;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=rest-client-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest-client-cache.js","sourceRoot":"","sources":["../../../../src/lib/websocket/rest-client-cache.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAcjD;;GAEG;AACH,MAAM,OAAO,eAAe;IAClB,MAAM,CAAiB;IAEvB,kBAAkB,CAAU;IAE5B,WAAW,GAA6B,EAAE,CAAC;IAE3C,YAAY,GAAwB,EAAE,CAAC;IAExC,SAAS,CAAC,MAAqB,EAAE,cAAsB;QAC5D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC;IAC3C,CAAC;IAEM,iBAAiB,CACtB,WAA8B,EAC9B,cAAmC;QAEnC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAC3B,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAEM,KAAK,CAAC,uBAAuB,CAClC,WAA8B,EAC9B,cAAmC;QAEnC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;YAC5D,IAAI,UAAU,GAAG,KAAK,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE;oBACrD,GAAG,IAAI,CAAC,kBAAkB;oBAC1B,KAAK,EAAE,GAAG;oBACV,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW;oBAC/C,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;iBACpC,CAAC,CAAC;gBAEH,+BAA+B;gBAC/B,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;YACnD,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,mEAAmE,EACnE;gBACE,GAAG,IAAI,CAAC,kBAAkB;gBAC1B,KAAK,EAAE,GAAG;gBACV,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW;gBAC/C,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;aACpC,CACF,CAAC;YAEF,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;QAChC,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACnE,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAEtD,MAAM,KAAK,GAAG,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC;QACzC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,yCAAyC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CACvE,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,WAAW,EAAE,MAAM,EAAE,OAAO,IAAI,GAAG,CAAC;QACzD,MAAM,WAAW,GAAG,YAAY,GAAG,IAAI,CAAC;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;QAE7C,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QAEhD,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;IAChE,CAAC;IAEM,wBAAwB,CAC7B,WAA8B,EAC9B,cAAmC;QAEnC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC,WAAW,CAAC,WAAW,GAAG,IAAI,iBAAiB,CAClD,WAAW,EACX,cAAc,CACf,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import WebSocket from 'isomorphic-ws';
|
|
2
|
+
import { WSAPIRequestOperationKrakenSpot } from '../../types/websockets/ws-api.js';
|
|
3
|
+
import { WSTopic } from '../../types/websockets/ws-subscriptions.js';
|
|
4
|
+
/** Should be one WS key per unique URL */
|
|
5
|
+
export declare const WS_KEY_MAP: {
|
|
6
|
+
/**
|
|
7
|
+
* Public WebSocket subscriptions for Kraken Spot products, via the V2 API
|
|
8
|
+
*
|
|
9
|
+
* - Ref: https://docs.kraken.com/api/docs/guides/spot-ws-intro
|
|
10
|
+
* - Channels: https://docs.kraken.com/api/docs/websocket-v2/add_order
|
|
11
|
+
*
|
|
12
|
+
* Note: Use spotPrivateV2 for private channels (requires API keys).
|
|
13
|
+
*/
|
|
14
|
+
readonly spotPublicV2: "spotPublicV2";
|
|
15
|
+
readonly spotPrivateV2: "spotPrivateV2";
|
|
16
|
+
readonly spotBetaPublicV2: "spotBetaPublicV2";
|
|
17
|
+
readonly spotBetaPrivateV2: "spotBetaPrivateV2";
|
|
18
|
+
/**
|
|
19
|
+
* Public WebSocket subscriptions for Kraken Derivatives products, via the V1 API:
|
|
20
|
+
*
|
|
21
|
+
* - Ref: https://docs.kraken.com/api/docs/guides/futures-websockets
|
|
22
|
+
* - Channels: https://docs.kraken.com/api/docs/futures-api/websocket/open_orders
|
|
23
|
+
*
|
|
24
|
+
* Note: While both Public and Private channels use the same WebSocket URL, we will actually maintain separate connections for easier management. Private channels require authentication and the connection is authenticated automatically.
|
|
25
|
+
*/
|
|
26
|
+
readonly derivativesPublicV1: "derivativesPublicV1";
|
|
27
|
+
readonly derivativesPrivateV1: "derivativesPrivateV1";
|
|
28
|
+
};
|
|
29
|
+
/** This is used to differentiate between each of the available websocket streams */
|
|
30
|
+
export type WsKey = (typeof WS_KEY_MAP)[keyof typeof WS_KEY_MAP];
|
|
31
|
+
export type WSOperation = 'subscribe' | 'unsubscribe';
|
|
32
|
+
/**
|
|
33
|
+
* Normalised internal format for a request (subscribe/unsubscribe/etc) on a topic, with optional parameters.
|
|
34
|
+
*
|
|
35
|
+
* - Topic: the topic this event is for
|
|
36
|
+
* - Payload: the parameters to include, optional. E.g. auth requires key + sign. Some topics allow configurable parameters.
|
|
37
|
+
*/
|
|
38
|
+
export interface WSTopicRequest<TWSTopic extends WSTopic = WSTopic, TWSPayload = any> {
|
|
39
|
+
topic: TWSTopic;
|
|
40
|
+
payload?: TWSPayload;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Conveniently allow users to request a topic either as string topics or objects (containing string topic + params)
|
|
44
|
+
*/
|
|
45
|
+
export type WSTopicRequestOrStringTopic<TWSTopic extends WSTopic, TWSPayload = any> = WSTopicRequest<TWSTopic, TWSPayload> | string;
|
|
46
|
+
export interface WSRequestOperationKraken<TWSTopic extends string, TWSParams extends object = any> {
|
|
47
|
+
method?: WSOperation;
|
|
48
|
+
event?: WSOperation;
|
|
49
|
+
params: {
|
|
50
|
+
channel: (TWSTopic | string | number)[];
|
|
51
|
+
symbol?: string[];
|
|
52
|
+
event_trigger?: string;
|
|
53
|
+
snapshot?: boolean;
|
|
54
|
+
} | TWSParams;
|
|
55
|
+
req_id: number;
|
|
56
|
+
/**
|
|
57
|
+
* The following are needed for futures/derivatives requests
|
|
58
|
+
*/
|
|
59
|
+
feed?: TWSTopic;
|
|
60
|
+
api_key?: string;
|
|
61
|
+
original_challenge?: string;
|
|
62
|
+
signed_challenge?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* #305: ws.terminate() is undefined in browsers.
|
|
66
|
+
* This only works in node.js, not in browsers.
|
|
67
|
+
* Does nothing if `ws` is undefined. Does nothing in browsers.
|
|
68
|
+
*/
|
|
69
|
+
export declare function safeTerminateWs(ws?: WebSocket | any, fallbackToClose?: boolean): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* WS API promises are stored using a primary key. This key is constructed using
|
|
72
|
+
* properties found in every request & reply.
|
|
73
|
+
*
|
|
74
|
+
* The counterpart to this is in resolveEmittableEvents
|
|
75
|
+
*/
|
|
76
|
+
export declare function getPromiseRefForWSAPIRequest(wsKey: WsKey, requestEvent: WSAPIRequestOperationKrakenSpot): string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Should be one WS key per unique URL */
|
|
2
|
+
export const WS_KEY_MAP = {
|
|
3
|
+
/**
|
|
4
|
+
* Public WebSocket subscriptions for Kraken Spot products, via the V2 API
|
|
5
|
+
*
|
|
6
|
+
* - Ref: https://docs.kraken.com/api/docs/guides/spot-ws-intro
|
|
7
|
+
* - Channels: https://docs.kraken.com/api/docs/websocket-v2/add_order
|
|
8
|
+
*
|
|
9
|
+
* Note: Use spotPrivateV2 for private channels (requires API keys).
|
|
10
|
+
*/
|
|
11
|
+
spotPublicV2: 'spotPublicV2',
|
|
12
|
+
spotPrivateV2: 'spotPrivateV2',
|
|
13
|
+
spotBetaPublicV2: 'spotBetaPublicV2',
|
|
14
|
+
spotBetaPrivateV2: 'spotBetaPrivateV2',
|
|
15
|
+
/**
|
|
16
|
+
* Public WebSocket subscriptions for Kraken Derivatives products, via the V1 API:
|
|
17
|
+
*
|
|
18
|
+
* - Ref: https://docs.kraken.com/api/docs/guides/futures-websockets
|
|
19
|
+
* - Channels: https://docs.kraken.com/api/docs/futures-api/websocket/open_orders
|
|
20
|
+
*
|
|
21
|
+
* Note: While both Public and Private channels use the same WebSocket URL, we will actually maintain separate connections for easier management. Private channels require authentication and the connection is authenticated automatically.
|
|
22
|
+
*/
|
|
23
|
+
derivativesPublicV1: 'derivativesPublicV1',
|
|
24
|
+
derivativesPrivateV1: 'derivativesPrivateV1',
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* #305: ws.terminate() is undefined in browsers.
|
|
28
|
+
* This only works in node.js, not in browsers.
|
|
29
|
+
* Does nothing if `ws` is undefined. Does nothing in browsers.
|
|
30
|
+
*/
|
|
31
|
+
export function safeTerminateWs(ws, fallbackToClose) {
|
|
32
|
+
if (!ws) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (typeof ws['terminate'] === 'function') {
|
|
36
|
+
ws.terminate();
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
else if (fallbackToClose) {
|
|
40
|
+
ws.close();
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* WS API promises are stored using a primary key. This key is constructed using
|
|
46
|
+
* properties found in every request & reply.
|
|
47
|
+
*
|
|
48
|
+
* The counterpart to this is in resolveEmittableEvents
|
|
49
|
+
*/
|
|
50
|
+
export function getPromiseRefForWSAPIRequest(wsKey, requestEvent) {
|
|
51
|
+
const promiseRef = [wsKey, requestEvent.method, requestEvent.req_id].join('_');
|
|
52
|
+
return promiseRef;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=websocket-util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-util.js","sourceRoot":"","sources":["../../../../src/lib/websocket/websocket-util.ts"],"names":[],"mappings":"AAKA,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB;;;;;;;OAOG;IACH,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IACpC,iBAAiB,EAAE,mBAAmB;IACtC;;;;;;;OAOG;IACH,mBAAmB,EAAE,qBAAqB;IAC1C,oBAAoB,EAAE,sBAAsB;CACpC,CAAC;AAuDX;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,EAAoB,EACpB,eAAyB;IAEzB,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,EAAE,CAAC,WAAW,CAAC,KAAK,UAAU,EAAE,CAAC;QAC1C,EAAE,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;SAAM,IAAI,eAAe,EAAE,CAAC;QAC3B,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAC1C,KAAY,EACZ,YAA6C;IAE7C,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CACvE,GAAG,CACJ,CAAC;IACF,OAAO,UAAU,CAAC;AACpB,CAAC"}
|