coinbase-api 0.3.2 → 0.5.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.
- package/README.md +438 -14
- package/dist/cjs/CBAdvancedTradeClient.d.ts +559 -0
- package/dist/cjs/CBAdvancedTradeClient.js +574 -0
- package/dist/cjs/CBAdvancedTradeClient.js.map +1 -0
- package/dist/cjs/CBAppClient.d.ts +359 -0
- package/dist/cjs/CBAppClient.js +336 -0
- package/dist/cjs/CBAppClient.js.map +1 -0
- package/dist/cjs/CBCommerceClient.d.ts +110 -0
- package/dist/cjs/CBCommerceClient.js +105 -0
- package/dist/cjs/CBCommerceClient.js.map +1 -0
- package/dist/cjs/CBExchangeClient.d.ts +640 -0
- package/dist/cjs/CBExchangeClient.js +751 -0
- package/dist/cjs/CBExchangeClient.js.map +1 -0
- package/dist/cjs/CBInternationalClient.d.ts +381 -0
- package/dist/cjs/CBInternationalClient.js +437 -0
- package/dist/cjs/CBInternationalClient.js.map +1 -0
- package/dist/cjs/CBPrimeClient.d.ts +363 -0
- package/dist/cjs/CBPrimeClient.js +451 -0
- package/dist/cjs/CBPrimeClient.js.map +1 -0
- package/dist/cjs/WebsocketClient.d.ts +78 -0
- package/dist/cjs/WebsocketClient.js +534 -0
- package/dist/cjs/WebsocketClient.js.map +1 -0
- package/dist/cjs/index.d.ts +13 -0
- package/dist/cjs/index.js +30 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lib/BaseRestClient.d.ts +66 -0
- package/dist/cjs/lib/BaseRestClient.js +436 -0
- package/dist/cjs/lib/BaseRestClient.js.map +1 -0
- package/dist/cjs/lib/BaseWSClient.d.ts +169 -0
- package/dist/cjs/lib/BaseWSClient.js +638 -0
- package/dist/cjs/lib/BaseWSClient.js.map +1 -0
- package/dist/cjs/lib/jwtNode.d.ts +13 -0
- package/dist/cjs/lib/jwtNode.js +52 -0
- package/dist/cjs/lib/jwtNode.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 +98 -0
- package/dist/cjs/lib/requestUtils.js +75 -0
- package/dist/cjs/lib/requestUtils.js.map +1 -0
- package/dist/cjs/lib/webCryptoAPI.d.ts +10 -0
- package/dist/cjs/lib/webCryptoAPI.js +83 -0
- package/dist/cjs/lib/webCryptoAPI.js.map +1 -0
- package/dist/cjs/lib/websocket/WsStore.d.ts +63 -0
- package/dist/cjs/lib/websocket/WsStore.js +254 -0
- package/dist/cjs/lib/websocket/WsStore.js.map +1 -0
- package/dist/cjs/lib/websocket/WsStore.types.d.ts +49 -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 +6 -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/typeGuards.d.ts +27 -0
- package/dist/cjs/lib/websocket/typeGuards.js +86 -0
- package/dist/cjs/lib/websocket/typeGuards.js.map +1 -0
- package/dist/cjs/lib/websocket/websocket-util.d.ts +120 -0
- package/dist/cjs/lib/websocket/websocket-util.js +173 -0
- package/dist/cjs/lib/websocket/websocket-util.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/types/request/advanced-trade-client.d.ts +194 -0
- package/dist/cjs/types/request/advanced-trade-client.js +18 -0
- package/dist/cjs/types/request/advanced-trade-client.js.map +1 -0
- package/dist/cjs/types/request/coinbase-app-client.d.ts +80 -0
- package/dist/cjs/types/request/coinbase-app-client.js +28 -0
- package/dist/cjs/types/request/coinbase-app-client.js.map +1 -0
- package/dist/cjs/types/request/coinbase-exchange.d.ts +332 -0
- package/dist/cjs/types/request/coinbase-exchange.js +3 -0
- package/dist/cjs/types/request/coinbase-exchange.js.map +1 -0
- package/dist/cjs/types/request/coinbase-international.d.ts +160 -0
- package/dist/cjs/types/request/coinbase-international.js +13 -0
- package/dist/cjs/types/request/coinbase-international.js.map +1 -0
- package/dist/cjs/types/request/coinbase-prime.d.ts +298 -0
- package/dist/cjs/types/request/coinbase-prime.js +8 -0
- package/dist/cjs/types/request/coinbase-prime.js.map +1 -0
- package/dist/cjs/types/response/advanced-trade-client.d.ts +759 -0
- package/dist/cjs/types/response/advanced-trade-client.js +8 -0
- package/dist/cjs/types/response/advanced-trade-client.js.map +1 -0
- package/dist/cjs/types/response/coinbase-app-client.d.ts +168 -0
- package/dist/cjs/types/response/coinbase-app-client.js +18 -0
- package/dist/cjs/types/response/coinbase-app-client.js.map +1 -0
- package/dist/cjs/types/response/coinbase-exchange.d.ts +80 -0
- package/dist/cjs/types/response/coinbase-exchange.js +82 -0
- package/dist/cjs/types/response/coinbase-exchange.js.map +1 -0
- package/dist/cjs/types/response/coinbase-international.d.ts +40 -0
- package/dist/cjs/types/response/coinbase-international.js +42 -0
- package/dist/cjs/types/response/coinbase-international.js.map +1 -0
- package/dist/cjs/types/response/coinbase-prime.d.ts +70 -0
- package/dist/cjs/types/response/coinbase-prime.js +72 -0
- package/dist/cjs/types/response/coinbase-prime.js.map +1 -0
- package/dist/cjs/types/response/ws.d.ts +7 -0
- package/dist/cjs/types/response/ws.js +3 -0
- package/dist/cjs/types/response/ws.js.map +1 -0
- package/dist/cjs/types/shared.types.d.ts +60 -0
- package/dist/cjs/types/shared.types.js +3 -0
- package/dist/cjs/types/shared.types.js.map +1 -0
- package/dist/cjs/types/websockets/client.d.ts +73 -0
- package/dist/cjs/types/websockets/client.js +3 -0
- package/dist/cjs/types/websockets/client.js.map +1 -0
- package/dist/cjs/types/websockets/events.d.ts +40 -0
- package/dist/cjs/types/websockets/events.js +3 -0
- package/dist/cjs/types/websockets/events.js.map +1 -0
- package/dist/cjs/types/websockets/requests.d.ts +76 -0
- package/dist/cjs/types/websockets/requests.js +3 -0
- package/dist/cjs/types/websockets/requests.js.map +1 -0
- package/dist/cjs/types/websockets/wsAPI.d.ts +9 -0
- package/dist/cjs/types/websockets/wsAPI.js +3 -0
- package/dist/cjs/types/websockets/wsAPI.js.map +1 -0
- package/dist/mjs/CBAdvancedTradeClient.d.ts +559 -0
- package/dist/mjs/CBAdvancedTradeClient.js +570 -0
- package/dist/mjs/CBAdvancedTradeClient.js.map +1 -0
- package/dist/mjs/CBAppClient.d.ts +359 -0
- package/dist/mjs/CBAppClient.js +332 -0
- package/dist/mjs/CBAppClient.js.map +1 -0
- package/dist/mjs/CBCommerceClient.d.ts +110 -0
- package/dist/mjs/CBCommerceClient.js +101 -0
- package/dist/mjs/CBCommerceClient.js.map +1 -0
- package/dist/mjs/CBExchangeClient.d.ts +640 -0
- package/dist/mjs/CBExchangeClient.js +747 -0
- package/dist/mjs/CBExchangeClient.js.map +1 -0
- package/dist/mjs/CBInternationalClient.d.ts +381 -0
- package/dist/mjs/CBInternationalClient.js +433 -0
- package/dist/mjs/CBInternationalClient.js.map +1 -0
- package/dist/mjs/CBPrimeClient.d.ts +363 -0
- package/dist/mjs/CBPrimeClient.js +447 -0
- package/dist/mjs/CBPrimeClient.js.map +1 -0
- package/dist/mjs/WebsocketClient.d.ts +78 -0
- package/dist/mjs/WebsocketClient.js +530 -0
- package/dist/mjs/WebsocketClient.js.map +1 -0
- package/dist/mjs/index.d.ts +13 -0
- package/dist/mjs/index.js +14 -0
- package/dist/mjs/index.js.map +1 -0
- package/dist/mjs/lib/BaseRestClient.d.ts +66 -0
- package/dist/mjs/lib/BaseRestClient.js +429 -0
- package/dist/mjs/lib/BaseRestClient.js.map +1 -0
- package/dist/mjs/lib/BaseWSClient.d.ts +169 -0
- package/dist/mjs/lib/BaseWSClient.js +631 -0
- package/dist/mjs/lib/BaseWSClient.js.map +1 -0
- package/dist/mjs/lib/jwtNode.d.ts +13 -0
- package/dist/mjs/lib/jwtNode.js +45 -0
- package/dist/mjs/lib/jwtNode.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 +98 -0
- package/dist/mjs/lib/requestUtils.js +69 -0
- package/dist/mjs/lib/requestUtils.js.map +1 -0
- package/dist/mjs/lib/webCryptoAPI.d.ts +10 -0
- package/dist/mjs/lib/webCryptoAPI.js +79 -0
- package/dist/mjs/lib/webCryptoAPI.js.map +1 -0
- package/dist/mjs/lib/websocket/WsStore.d.ts +63 -0
- package/dist/mjs/lib/websocket/WsStore.js +249 -0
- package/dist/mjs/lib/websocket/WsStore.js.map +1 -0
- package/dist/mjs/lib/websocket/WsStore.types.d.ts +49 -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 +6 -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/typeGuards.d.ts +27 -0
- package/dist/mjs/lib/websocket/typeGuards.js +78 -0
- package/dist/mjs/lib/websocket/typeGuards.js.map +1 -0
- package/dist/mjs/lib/websocket/websocket-util.d.ts +120 -0
- package/dist/mjs/lib/websocket/websocket-util.js +164 -0
- package/dist/mjs/lib/websocket/websocket-util.js.map +1 -0
- package/dist/mjs/package.json +3 -0
- package/dist/mjs/types/request/advanced-trade-client.d.ts +194 -0
- package/dist/mjs/types/request/advanced-trade-client.js +17 -0
- package/dist/mjs/types/request/advanced-trade-client.js.map +1 -0
- package/dist/mjs/types/request/coinbase-app-client.d.ts +80 -0
- package/dist/mjs/types/request/coinbase-app-client.js +27 -0
- package/dist/mjs/types/request/coinbase-app-client.js.map +1 -0
- package/dist/mjs/types/request/coinbase-exchange.d.ts +332 -0
- package/dist/mjs/types/request/coinbase-exchange.js +2 -0
- package/dist/mjs/types/request/coinbase-exchange.js.map +1 -0
- package/dist/mjs/types/request/coinbase-international.d.ts +160 -0
- package/dist/mjs/types/request/coinbase-international.js +12 -0
- package/dist/mjs/types/request/coinbase-international.js.map +1 -0
- package/dist/mjs/types/request/coinbase-prime.d.ts +298 -0
- package/dist/mjs/types/request/coinbase-prime.js +7 -0
- package/dist/mjs/types/request/coinbase-prime.js.map +1 -0
- package/dist/mjs/types/response/advanced-trade-client.d.ts +759 -0
- package/dist/mjs/types/response/advanced-trade-client.js +7 -0
- package/dist/mjs/types/response/advanced-trade-client.js.map +1 -0
- package/dist/mjs/types/response/coinbase-app-client.d.ts +168 -0
- package/dist/mjs/types/response/coinbase-app-client.js +17 -0
- package/dist/mjs/types/response/coinbase-app-client.js.map +1 -0
- package/dist/mjs/types/response/coinbase-exchange.d.ts +80 -0
- package/dist/mjs/types/response/coinbase-exchange.js +82 -0
- package/dist/mjs/types/response/coinbase-exchange.js.map +1 -0
- package/dist/mjs/types/response/coinbase-international.d.ts +40 -0
- package/dist/mjs/types/response/coinbase-international.js +42 -0
- package/dist/mjs/types/response/coinbase-international.js.map +1 -0
- package/dist/mjs/types/response/coinbase-prime.d.ts +70 -0
- package/dist/mjs/types/response/coinbase-prime.js +72 -0
- package/dist/mjs/types/response/coinbase-prime.js.map +1 -0
- package/dist/mjs/types/response/ws.d.ts +7 -0
- package/dist/mjs/types/response/ws.js +2 -0
- package/dist/mjs/types/response/ws.js.map +1 -0
- package/dist/mjs/types/shared.types.d.ts +60 -0
- package/dist/mjs/types/shared.types.js +2 -0
- package/dist/mjs/types/shared.types.js.map +1 -0
- package/dist/mjs/types/websockets/client.d.ts +73 -0
- package/dist/mjs/types/websockets/client.js +2 -0
- package/dist/mjs/types/websockets/client.js.map +1 -0
- package/dist/mjs/types/websockets/events.d.ts +40 -0
- package/dist/mjs/types/websockets/events.js +2 -0
- package/dist/mjs/types/websockets/events.js.map +1 -0
- package/dist/mjs/types/websockets/requests.d.ts +76 -0
- package/dist/mjs/types/websockets/requests.js +2 -0
- package/dist/mjs/types/websockets/requests.js.map +1 -0
- package/dist/mjs/types/websockets/wsAPI.d.ts +9 -0
- package/dist/mjs/types/websockets/wsAPI.js +2 -0
- package/dist/mjs/types/websockets/wsAPI.js.map +1 -0
- package/package.json +42 -30
- package/index.js +0 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -16
- package/lib/index.js.map +0 -1
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WsStore = void 0;
|
|
4
|
+
exports.isDeepObjectMatch = isDeepObjectMatch;
|
|
5
|
+
const logger_js_1 = require("./logger.js");
|
|
6
|
+
const WsStore_types_js_1 = require("./WsStore.types.js");
|
|
7
|
+
/**
|
|
8
|
+
* Simple comparison of two objects, only checks 1-level deep (nested objects won't match)
|
|
9
|
+
*/
|
|
10
|
+
function isDeepObjectMatch(object1, object2) {
|
|
11
|
+
if (typeof object1 === 'string' && typeof object2 === 'string') {
|
|
12
|
+
return object1 === object2;
|
|
13
|
+
}
|
|
14
|
+
if (typeof object1 !== 'object' || typeof object2 !== 'object') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
for (const key in object1) {
|
|
18
|
+
const value1 = object1[key];
|
|
19
|
+
const value2 = object2[key];
|
|
20
|
+
if (value1 !== value2) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
const DEFERRED_PROMISE_REF = {
|
|
27
|
+
CONNECTION_IN_PROGRESS: 'CONNECTION_IN_PROGRESS',
|
|
28
|
+
};
|
|
29
|
+
class WsStore {
|
|
30
|
+
wsState = {};
|
|
31
|
+
logger;
|
|
32
|
+
constructor(logger) {
|
|
33
|
+
this.logger = logger || logger_js_1.DefaultLogger;
|
|
34
|
+
}
|
|
35
|
+
get(key, createIfMissing) {
|
|
36
|
+
if (this.wsState[key]) {
|
|
37
|
+
return this.wsState[key];
|
|
38
|
+
}
|
|
39
|
+
if (createIfMissing) {
|
|
40
|
+
return this.create(key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
getKeys() {
|
|
44
|
+
return Object.keys(this.wsState);
|
|
45
|
+
}
|
|
46
|
+
create(key) {
|
|
47
|
+
if (this.hasExistingActiveConnection(key)) {
|
|
48
|
+
this.logger.info('WsStore setConnection() overwriting existing open connection: ', this.getWs(key));
|
|
49
|
+
}
|
|
50
|
+
this.wsState[key] = {
|
|
51
|
+
subscribedTopics: new Set(),
|
|
52
|
+
connectionState: WsStore_types_js_1.WsConnectionStateEnum.INITIAL,
|
|
53
|
+
deferredPromiseStore: {},
|
|
54
|
+
};
|
|
55
|
+
return this.get(key);
|
|
56
|
+
}
|
|
57
|
+
delete(key) {
|
|
58
|
+
// TODO: should we allow this at all? Perhaps block this from happening...
|
|
59
|
+
if (this.hasExistingActiveConnection(key)) {
|
|
60
|
+
const ws = this.getWs(key);
|
|
61
|
+
this.logger.info('WsStore deleting state for connection still open: ', ws);
|
|
62
|
+
ws?.close();
|
|
63
|
+
}
|
|
64
|
+
delete this.wsState[key];
|
|
65
|
+
}
|
|
66
|
+
/* connection websocket */
|
|
67
|
+
hasExistingActiveConnection(key) {
|
|
68
|
+
return this.get(key) && this.isWsOpen(key);
|
|
69
|
+
}
|
|
70
|
+
getWs(key) {
|
|
71
|
+
return this.get(key)?.ws;
|
|
72
|
+
}
|
|
73
|
+
setWs(key, wsConnection) {
|
|
74
|
+
if (this.isWsOpen(key)) {
|
|
75
|
+
this.logger.info('WsStore setConnection() overwriting existing open connection: ', this.getWs(key));
|
|
76
|
+
}
|
|
77
|
+
this.get(key, true).ws = wsConnection;
|
|
78
|
+
return wsConnection;
|
|
79
|
+
}
|
|
80
|
+
getDeferredPromise(wsKey, promiseRef) {
|
|
81
|
+
const storeForKey = this.get(wsKey);
|
|
82
|
+
if (!storeForKey) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const deferredPromiseStore = storeForKey.deferredPromiseStore;
|
|
86
|
+
return deferredPromiseStore[promiseRef];
|
|
87
|
+
}
|
|
88
|
+
createDeferredPromise(wsKey, promiseRef, throwIfExists) {
|
|
89
|
+
const existingPromise = this.getDeferredPromise(wsKey, promiseRef);
|
|
90
|
+
if (existingPromise) {
|
|
91
|
+
if (throwIfExists) {
|
|
92
|
+
throw new Error(`Promise exists for "${wsKey}"`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// console.log('existing promise');
|
|
96
|
+
return existingPromise;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// console.log('create promise');
|
|
100
|
+
const createIfMissing = true;
|
|
101
|
+
const storeForKey = this.get(wsKey, createIfMissing);
|
|
102
|
+
// TODO: Once stable, use Promise.withResolvers in future
|
|
103
|
+
const deferredPromise = {};
|
|
104
|
+
deferredPromise.promise = new Promise((resolve, reject) => {
|
|
105
|
+
deferredPromise.resolve = resolve;
|
|
106
|
+
deferredPromise.reject = reject;
|
|
107
|
+
});
|
|
108
|
+
const deferredPromiseStore = storeForKey.deferredPromiseStore;
|
|
109
|
+
deferredPromiseStore[promiseRef] = deferredPromise;
|
|
110
|
+
return deferredPromise;
|
|
111
|
+
}
|
|
112
|
+
resolveDeferredPromise(wsKey, promiseRef, value, removeAfter) {
|
|
113
|
+
const promise = this.getDeferredPromise(wsKey, promiseRef);
|
|
114
|
+
if (promise?.resolve) {
|
|
115
|
+
promise.resolve(value);
|
|
116
|
+
}
|
|
117
|
+
if (removeAfter) {
|
|
118
|
+
this.removeDeferredPromise(wsKey, promiseRef);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
rejectDeferredPromise(wsKey, promiseRef, value, removeAfter) {
|
|
122
|
+
const promise = this.getDeferredPromise(wsKey, promiseRef);
|
|
123
|
+
if (promise?.reject) {
|
|
124
|
+
promise.reject(value);
|
|
125
|
+
}
|
|
126
|
+
if (removeAfter) {
|
|
127
|
+
this.removeDeferredPromise(wsKey, promiseRef);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
removeDeferredPromise(wsKey, promiseRef) {
|
|
131
|
+
const storeForKey = this.get(wsKey);
|
|
132
|
+
if (!storeForKey) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const deferredPromise = storeForKey.deferredPromiseStore[promiseRef];
|
|
136
|
+
if (deferredPromise) {
|
|
137
|
+
// Just in case it's pending
|
|
138
|
+
if (deferredPromise.resolve) {
|
|
139
|
+
deferredPromise.resolve('promiseRemoved');
|
|
140
|
+
}
|
|
141
|
+
delete storeForKey.deferredPromiseStore[promiseRef];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
rejectAllDeferredPromises(wsKey, reason) {
|
|
145
|
+
const storeForKey = this.get(wsKey);
|
|
146
|
+
const deferredPromiseStore = storeForKey.deferredPromiseStore;
|
|
147
|
+
if (!storeForKey || !deferredPromiseStore) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const reservedKeys = Object.values(DEFERRED_PROMISE_REF);
|
|
151
|
+
for (const promiseRef in deferredPromiseStore) {
|
|
152
|
+
// Skip reserved keys, such as the connection promise
|
|
153
|
+
if (reservedKeys.includes(promiseRef)) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
this.rejectDeferredPromise(wsKey, promiseRef, reason, true);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
this.logger.error(`rejectAllDeferredPromises(): Exception rejecting deferred promise`, { wsKey: wsKey, reason, promiseRef, exception: e });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Get promise designed to track a connection attempt in progress. Resolves once connected. */
|
|
165
|
+
getConnectionInProgressPromise(wsKey) {
|
|
166
|
+
return this.getDeferredPromise(wsKey, DEFERRED_PROMISE_REF.CONNECTION_IN_PROGRESS);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create a deferred promise designed to track a connection attempt in progress.
|
|
170
|
+
*
|
|
171
|
+
* Will throw if existing promise is found.
|
|
172
|
+
*/
|
|
173
|
+
createConnectionInProgressPromise(wsKey, throwIfExists) {
|
|
174
|
+
return this.createDeferredPromise(wsKey, DEFERRED_PROMISE_REF.CONNECTION_IN_PROGRESS, throwIfExists);
|
|
175
|
+
}
|
|
176
|
+
/** Remove promise designed to track a connection attempt in progress */
|
|
177
|
+
removeConnectingInProgressPromise(wsKey) {
|
|
178
|
+
return this.removeDeferredPromise(wsKey, DEFERRED_PROMISE_REF.CONNECTION_IN_PROGRESS);
|
|
179
|
+
}
|
|
180
|
+
/* connection state */
|
|
181
|
+
isWsOpen(key) {
|
|
182
|
+
const existingConnection = this.getWs(key);
|
|
183
|
+
return (!!existingConnection &&
|
|
184
|
+
existingConnection.readyState === existingConnection.OPEN);
|
|
185
|
+
}
|
|
186
|
+
getConnectionState(key) {
|
|
187
|
+
return this.get(key, true).connectionState;
|
|
188
|
+
}
|
|
189
|
+
setConnectionState(key, state) {
|
|
190
|
+
// console.log(new Date(), `setConnectionState(${key}, ${state})`);
|
|
191
|
+
this.get(key, true).connectionState = state;
|
|
192
|
+
}
|
|
193
|
+
isConnectionState(key, state) {
|
|
194
|
+
return this.getConnectionState(key) === state;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check if we're currently in the process of opening a connection for any reason. Safer than only checking "CONNECTING" as the state
|
|
198
|
+
* @param key
|
|
199
|
+
* @returns
|
|
200
|
+
*/
|
|
201
|
+
isConnectionAttemptInProgress(key) {
|
|
202
|
+
const isConnectionInProgress = this.isConnectionState(key, WsStore_types_js_1.WsConnectionStateEnum.CONNECTING) ||
|
|
203
|
+
this.isConnectionState(key, WsStore_types_js_1.WsConnectionStateEnum.RECONNECTING);
|
|
204
|
+
return isConnectionInProgress;
|
|
205
|
+
}
|
|
206
|
+
/* subscribed topics */
|
|
207
|
+
getTopics(key) {
|
|
208
|
+
return this.get(key, true).subscribedTopics;
|
|
209
|
+
}
|
|
210
|
+
getTopicsByKey() {
|
|
211
|
+
const result = {};
|
|
212
|
+
for (const refKey in this.wsState) {
|
|
213
|
+
result[refKey] = this.getTopics(refKey);
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
// Since topics are objects we can't rely on the set to detect duplicates
|
|
218
|
+
/**
|
|
219
|
+
* Find matching "topic" request from the store
|
|
220
|
+
* @param key
|
|
221
|
+
* @param topic
|
|
222
|
+
* @returns
|
|
223
|
+
*/
|
|
224
|
+
getMatchingTopic(key, topic) {
|
|
225
|
+
// if (typeof topic === 'string') {
|
|
226
|
+
// return this.getMatchingTopic(key, { channel: topic });
|
|
227
|
+
// }
|
|
228
|
+
const allTopics = this.getTopics(key).values();
|
|
229
|
+
for (const storedTopic of allTopics) {
|
|
230
|
+
if (isDeepObjectMatch(topic, storedTopic)) {
|
|
231
|
+
return storedTopic;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
addTopic(key, topic) {
|
|
236
|
+
// console.log(`wsStore.addTopic(${key}, ${topic})`);
|
|
237
|
+
// Check for duplicate topic. If already tracked, don't store this one
|
|
238
|
+
const existingTopic = this.getMatchingTopic(key, topic);
|
|
239
|
+
if (existingTopic) {
|
|
240
|
+
return this.getTopics(key);
|
|
241
|
+
}
|
|
242
|
+
return this.getTopics(key).add(topic);
|
|
243
|
+
}
|
|
244
|
+
deleteTopic(key, topic) {
|
|
245
|
+
// Check if we're subscribed to a topic like this
|
|
246
|
+
const storedTopic = this.getMatchingTopic(key, topic);
|
|
247
|
+
if (storedTopic) {
|
|
248
|
+
this.getTopics(key).delete(storedTopic);
|
|
249
|
+
}
|
|
250
|
+
return this.getTopics(key);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
exports.WsStore = WsStore;
|
|
254
|
+
//# 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,49 @@
|
|
|
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_RECONNECTING = 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
|
+
}
|
|
18
|
+
export interface WsStoredState<TWSTopicSubscribeEvent extends string | object> {
|
|
19
|
+
/** The currently active websocket connection */
|
|
20
|
+
ws?: WebSocket;
|
|
21
|
+
/** The current lifecycle state of the connection (enum) */
|
|
22
|
+
connectionState?: WsConnectionStateEnum;
|
|
23
|
+
/** A timer that will send an upstream heartbeat (ping) when it expires */
|
|
24
|
+
activePingTimer?: ReturnType<typeof setTimeout> | undefined;
|
|
25
|
+
/** A timer tracking that an upstream heartbeat was sent, expecting a reply before it expires */
|
|
26
|
+
activePongTimer?: ReturnType<typeof setTimeout> | undefined;
|
|
27
|
+
/** If a reconnection is in progress, this will have the timer for the delayed reconnect */
|
|
28
|
+
activeReconnectTimer?: ReturnType<typeof setTimeout> | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* When a connection attempt is in progress (even for reconnect), a promise is stored here.
|
|
31
|
+
*
|
|
32
|
+
* This promise will resolve once connected (and will then get removed);
|
|
33
|
+
*/
|
|
34
|
+
deferredPromiseStore: Record<string, DeferredPromise>;
|
|
35
|
+
/**
|
|
36
|
+
* All the topics we are expected to be subscribed to on this connection (and we automatically resubscribe to if the connection drops)
|
|
37
|
+
*
|
|
38
|
+
* 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)
|
|
39
|
+
*/
|
|
40
|
+
subscribedTopics: Set<TWSTopicSubscribeEvent>;
|
|
41
|
+
/** Whether this connection is ready for events (welcome message received after connection) */
|
|
42
|
+
isReadyForEvents?: boolean;
|
|
43
|
+
/** Whether this connection has completed authentication (only applies to private connections) */
|
|
44
|
+
isAuthenticated?: boolean;
|
|
45
|
+
/** Whether this connection has completed authentication before for the Websocket API, so it knows to automatically reauth if reconnected */
|
|
46
|
+
didAuthWSAPI?: boolean;
|
|
47
|
+
/** To reauthenticate on the WS API, which channel do we send to? */
|
|
48
|
+
WSAPIAuthChannel?: string;
|
|
49
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WsConnectionStateEnum = void 0;
|
|
4
|
+
var WsConnectionStateEnum;
|
|
5
|
+
(function (WsConnectionStateEnum) {
|
|
6
|
+
WsConnectionStateEnum[WsConnectionStateEnum["INITIAL"] = 0] = "INITIAL";
|
|
7
|
+
WsConnectionStateEnum[WsConnectionStateEnum["CONNECTING"] = 1] = "CONNECTING";
|
|
8
|
+
WsConnectionStateEnum[WsConnectionStateEnum["CONNECTED"] = 2] = "CONNECTED";
|
|
9
|
+
WsConnectionStateEnum[WsConnectionStateEnum["CLOSING"] = 3] = "CLOSING";
|
|
10
|
+
WsConnectionStateEnum[WsConnectionStateEnum["RECONNECTING"] = 4] = "RECONNECTING";
|
|
11
|
+
WsConnectionStateEnum[WsConnectionStateEnum["ERROR_RECONNECTING"] = 5] = "ERROR_RECONNECTING";
|
|
12
|
+
// ERROR = 5,
|
|
13
|
+
})(WsConnectionStateEnum || (exports.WsConnectionStateEnum = WsConnectionStateEnum = {}));
|
|
14
|
+
//# 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,IAAY,qBAQX;AARD,WAAY,qBAAqB;IAC/B,uEAAW,CAAA;IACX,6EAAc,CAAA;IACd,2EAAa,CAAA;IACb,uEAAW,CAAA;IACX,iFAAgB,CAAA;IAChB,6FAAsB,CAAA;IACtB,aAAa;AACf,CAAC,EARW,qBAAqB,qCAArB,qBAAqB,QAQhC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultLogger = void 0;
|
|
4
|
+
exports.DefaultLogger = {
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6
|
+
trace: (..._params) => {
|
|
7
|
+
// console.log(_params);
|
|
8
|
+
},
|
|
9
|
+
info: (...params) => {
|
|
10
|
+
console.info(params);
|
|
11
|
+
},
|
|
12
|
+
error: (...params) => {
|
|
13
|
+
console.error(params);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../src/lib/websocket/logger.ts"],"names":[],"mappings":";;;AAEa,QAAA,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,27 @@
|
|
|
1
|
+
import { CBAdvancedTradeErrorEvent, CBAdvancedTradeEvent, CBExchangeBaseEvent } from '../../types/websockets/events.js';
|
|
2
|
+
import { WsExchangeRequestOperation, WsInternationalRequestOperation, WsPrimeRequestOperation } from '../../types/websockets/requests.js';
|
|
3
|
+
import { WsKey } from './websocket-util.js';
|
|
4
|
+
export declare function isCBAdvancedTradeWSEvent(event: unknown): event is CBAdvancedTradeEvent;
|
|
5
|
+
/**
|
|
6
|
+
* Type guard that checks whether this event is/extends CBExchangeBaseEvent
|
|
7
|
+
*/
|
|
8
|
+
export declare function isCBExchangeWSEvent(event: unknown, wsKey: WsKey): event is CBExchangeBaseEvent;
|
|
9
|
+
/**
|
|
10
|
+
* Type guard for error-type response events seen for the Advnaced Trade WS channel
|
|
11
|
+
*/
|
|
12
|
+
export declare function isCBAdvancedTradeErrorEvent(event: unknown): event is CBAdvancedTradeErrorEvent;
|
|
13
|
+
/**
|
|
14
|
+
* Silly type guard for the structure of events being sent to the server
|
|
15
|
+
* (e.g. when subscribing to a topic)
|
|
16
|
+
*/
|
|
17
|
+
export declare function isCBExchangeWSRequestOperation<TWSTopic extends string = string>(evt: unknown, wsKey: WsKey): evt is WsExchangeRequestOperation<TWSTopic>;
|
|
18
|
+
/**
|
|
19
|
+
* Silly type guard for the structure of events being sent to the server
|
|
20
|
+
* (e.g. when subscribing to a topic)
|
|
21
|
+
*/
|
|
22
|
+
export declare function isCBINTXWSRequestOperation<TWSTopic extends string = string>(evt: unknown, wsKey: WsKey): evt is WsInternationalRequestOperation<TWSTopic>;
|
|
23
|
+
/**
|
|
24
|
+
* Silly type guard for the structure of events being sent to the server
|
|
25
|
+
* (e.g. when subscribing to a topic)
|
|
26
|
+
*/
|
|
27
|
+
export declare function isCBPrimeWSRequestOperation<TWSTopic extends string = string>(evt: unknown, wsKey: WsKey): evt is WsPrimeRequestOperation<TWSTopic>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isCBAdvancedTradeWSEvent = isCBAdvancedTradeWSEvent;
|
|
4
|
+
exports.isCBExchangeWSEvent = isCBExchangeWSEvent;
|
|
5
|
+
exports.isCBAdvancedTradeErrorEvent = isCBAdvancedTradeErrorEvent;
|
|
6
|
+
exports.isCBExchangeWSRequestOperation = isCBExchangeWSRequestOperation;
|
|
7
|
+
exports.isCBINTXWSRequestOperation = isCBINTXWSRequestOperation;
|
|
8
|
+
exports.isCBPrimeWSRequestOperation = isCBPrimeWSRequestOperation;
|
|
9
|
+
const websocket_util_js_1 = require("./websocket-util.js");
|
|
10
|
+
function isDefinedObject(value) {
|
|
11
|
+
return typeof value === 'object' || !value;
|
|
12
|
+
}
|
|
13
|
+
function isCBAdvancedTradeWSEvent(event) {
|
|
14
|
+
if (!isDefinedObject(event)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const message = event;
|
|
18
|
+
return typeof message.channel === 'string';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Type guard that checks whether this event is/extends CBExchangeBaseEvent
|
|
22
|
+
*/
|
|
23
|
+
function isCBExchangeWSEvent(event, wsKey) {
|
|
24
|
+
if (!isDefinedObject(event)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return (wsKey === websocket_util_js_1.WS_KEY_MAP.exchangeMarketData ||
|
|
28
|
+
wsKey === websocket_util_js_1.WS_KEY_MAP.exchangeDirectMarketData);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Type guard for error-type response events seen for the Advnaced Trade WS channel
|
|
32
|
+
*/
|
|
33
|
+
function isCBAdvancedTradeErrorEvent(event) {
|
|
34
|
+
if (!isDefinedObject(event)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const message = event;
|
|
38
|
+
return message.type === 'error';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Silly type guard for the structure of events being sent to the server
|
|
42
|
+
* (e.g. when subscribing to a topic)
|
|
43
|
+
*/
|
|
44
|
+
function isCBExchangeWSRequestOperation(evt, wsKey) {
|
|
45
|
+
if (!isDefinedObject(evt)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const looselyTypedEvent = evt;
|
|
49
|
+
if (typeof looselyTypedEvent.type !== 'string' ||
|
|
50
|
+
!Array.isArray(looselyTypedEvent.channels)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
return (wsKey === websocket_util_js_1.WS_KEY_MAP.exchangeDirectMarketData ||
|
|
54
|
+
wsKey === websocket_util_js_1.WS_KEY_MAP.exchangeMarketData);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Silly type guard for the structure of events being sent to the server
|
|
58
|
+
* (e.g. when subscribing to a topic)
|
|
59
|
+
*/
|
|
60
|
+
function isCBINTXWSRequestOperation(evt, wsKey) {
|
|
61
|
+
if (!isDefinedObject(evt)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const looselyTypedEvent = evt;
|
|
65
|
+
if (typeof looselyTypedEvent.type !== 'string' ||
|
|
66
|
+
!Array.isArray(looselyTypedEvent.channels)) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return wsKey === websocket_util_js_1.WS_KEY_MAP.internationalMarketData;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Silly type guard for the structure of events being sent to the server
|
|
73
|
+
* (e.g. when subscribing to a topic)
|
|
74
|
+
*/
|
|
75
|
+
function isCBPrimeWSRequestOperation(evt, wsKey) {
|
|
76
|
+
if (!isDefinedObject(evt)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const looselyTypedEvent = evt;
|
|
80
|
+
if (typeof looselyTypedEvent.type !== 'string' ||
|
|
81
|
+
typeof looselyTypedEvent.channel !== 'string') {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return wsKey === websocket_util_js_1.WS_KEY_MAP.internationalMarketData;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=typeGuards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeGuards.js","sourceRoot":"","sources":["../../../../src/lib/websocket/typeGuards.ts"],"names":[],"mappings":";;AAiBA,4DASC;AAKD,kDAYC;AAKD,kEASC;AAMD,wEAoBC;AAMD,gEAkBC;AAMD,kEAkBC;AAxHD,2DAAwD;AAExD,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC;AAC7C,CAAC;AAED,SAAgB,wBAAwB,CACtC,KAAc;IAEd,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,KAA6B,CAAC;IAC9C,OAAO,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,KAAc,EACd,KAAY;IAEZ,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,KAAK,KAAK,8BAAU,CAAC,kBAAkB;QACvC,KAAK,KAAK,8BAAU,CAAC,wBAAwB,CAC9C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,2BAA2B,CACzC,KAAc;IAEd,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,KAAkC,CAAC;IACnD,OAAO,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAgB,8BAA8B,CAE5C,GAAY,EAAE,KAAY;IAC1B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,iBAAiB,GAAG,GAA2C,CAAC;IAEtE,IACE,OAAO,iBAAiB,CAAC,IAAI,KAAK,QAAQ;QAC1C,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,KAAK,KAAK,8BAAU,CAAC,wBAAwB;QAC7C,KAAK,KAAK,8BAAU,CAAC,kBAAkB,CACxC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CACxC,GAAY,EACZ,KAAY;IAEZ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,iBAAiB,GAAG,GAAgD,CAAC;IAE3E,IACE,OAAO,iBAAiB,CAAC,IAAI,KAAK,QAAQ;QAC1C,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,KAAK,8BAAU,CAAC,uBAAuB,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CACzC,GAAY,EACZ,KAAY;IAEZ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,iBAAiB,GAAG,GAAwC,CAAC;IAEnE,IACE,OAAO,iBAAiB,CAAC,IAAI,KAAK,QAAQ;QAC1C,OAAO,iBAAiB,CAAC,OAAO,KAAK,QAAQ,EAC7C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,KAAK,8BAAU,CAAC,uBAAuB,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import WebSocket from 'isomorphic-ws';
|
|
2
|
+
import { WsExchangeRequestOperation, WsInternationalRequestOperation } from '../../types/websockets/requests.js';
|
|
3
|
+
/**
|
|
4
|
+
* Each websocket URL (domain + endpoint) is represented as a "WS Key". Authentication is handled automatically if required.
|
|
5
|
+
*/
|
|
6
|
+
export declare const WS_KEY_MAP: {
|
|
7
|
+
/**
|
|
8
|
+
* Market Data is the traditional feed that provides updates for both orders and trades.
|
|
9
|
+
* Most channels are now available without authentication.
|
|
10
|
+
*
|
|
11
|
+
* https://docs.cdp.coinbase.com/advanced-trade/docs/ws-overview
|
|
12
|
+
*/
|
|
13
|
+
readonly advTradeMarketData: "advTradeMarketData";
|
|
14
|
+
/**
|
|
15
|
+
* User Order Data provides updates for the orders of the user.
|
|
16
|
+
*
|
|
17
|
+
* https://docs.cdp.coinbase.com/advanced-trade/docs/ws-overview
|
|
18
|
+
*/
|
|
19
|
+
readonly advTradeUserData: "advTradeUserData";
|
|
20
|
+
/**
|
|
21
|
+
* Coinbase Market Data (part of Coinbase Exchange API) is the traditional feed which is available without authentication.
|
|
22
|
+
*
|
|
23
|
+
* https://docs.cdp.coinbase.com/exchange/docs/websocket-overview
|
|
24
|
+
*/
|
|
25
|
+
readonly exchangeMarketData: "exchangeMarketData";
|
|
26
|
+
/**
|
|
27
|
+
* Coinbase Direct Market Data has direct access to Coinbase Exchange servers and requires Authentication.
|
|
28
|
+
*
|
|
29
|
+
* https://docs.cdp.coinbase.com/exchange/docs/websocket-overview
|
|
30
|
+
*/
|
|
31
|
+
readonly exchangeDirectMarketData: "exchangeDirectMarketData";
|
|
32
|
+
/**
|
|
33
|
+
* The INTX WebSocket feed is publicly available and provides real-time market data updates for orders and trades.
|
|
34
|
+
* The SDK must authenticate when subscribing to the WebSocket Feed the very first time.
|
|
35
|
+
*
|
|
36
|
+
* https://docs.cdp.coinbase.com/intx/docs/websocket-overview
|
|
37
|
+
*/
|
|
38
|
+
readonly internationalMarketData: "internationalMarketData";
|
|
39
|
+
/**
|
|
40
|
+
* The Prime WebSocket feed provides real-time market data updates for orders and trades. To begin
|
|
41
|
+
* receiving feed messages, you must send a signed subscribe message to the server indicating
|
|
42
|
+
* which channels and products to receive. The SDK will handle this automatically.
|
|
43
|
+
*
|
|
44
|
+
* https://docs.cdp.coinbase.com/prime/docs/websocket-feed
|
|
45
|
+
*/
|
|
46
|
+
readonly primeMarketData: "primeMarketData";
|
|
47
|
+
};
|
|
48
|
+
/** This is used to differentiate between each of the available websocket streams */
|
|
49
|
+
export type WsKey = (typeof WS_KEY_MAP)[keyof typeof WS_KEY_MAP];
|
|
50
|
+
/**
|
|
51
|
+
* Normalised internal format for a request (subscribe/unsubscribe/etc) on a topic, with optional parameters.
|
|
52
|
+
*
|
|
53
|
+
* - Topic: the topic this event is for
|
|
54
|
+
* - Payload: the parameters to include, optional. E.g. auth requires key + sign. Some topics allow configurable parameters.
|
|
55
|
+
*/
|
|
56
|
+
export interface WsTopicRequest<TWSTopic extends string = string, TWSPayload = any> {
|
|
57
|
+
topic: TWSTopic;
|
|
58
|
+
/**
|
|
59
|
+
* Any parameters to include with the request. These are automatically merged into the request.
|
|
60
|
+
*/
|
|
61
|
+
payload?: TWSPayload;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Conveniently allow users to request a topic either as string topics or objects (containing string topic + params)
|
|
65
|
+
*/
|
|
66
|
+
export type WsTopicRequestOrStringTopic<TWSTopic extends string, TWSPayload = any> = WsTopicRequest<TWSTopic, TWSPayload> | string;
|
|
67
|
+
export interface MessageEventLike {
|
|
68
|
+
target: WebSocket;
|
|
69
|
+
type: 'message';
|
|
70
|
+
data: string;
|
|
71
|
+
}
|
|
72
|
+
export declare function isMessageEvent(msg: unknown): msg is MessageEventLike;
|
|
73
|
+
/**
|
|
74
|
+
* Some exchanges have two livenet environments, some have test environments, some dont. This allows easy flexibility for different exchanges.
|
|
75
|
+
* Examples:
|
|
76
|
+
* - One livenet and one testnet: NetworkMap<'livenet' | 'testnet'>
|
|
77
|
+
* - One livenet, sometimes two, one testnet: NetworkMap<'livenet' | 'testnet', 'livenet2'>
|
|
78
|
+
* - Only one livenet, no other networks: NetworkMap<'livenet'>
|
|
79
|
+
*/
|
|
80
|
+
type NetworkMap<TRequiredKeys extends string, TOptionalKeys extends string | undefined = undefined> = Record<TRequiredKeys, string> & (TOptionalKeys extends string ? Record<TOptionalKeys, string | undefined> : Record<TRequiredKeys, string>);
|
|
81
|
+
export declare const WS_URL_MAP: Record<WsKey, NetworkMap<'livenet' | 'testnet'>>;
|
|
82
|
+
/**
|
|
83
|
+
* Merge one or more WS Request operations (e.g. subscribe request) for
|
|
84
|
+
* CB Exchange into one, allowing them to be sent as one request
|
|
85
|
+
*/
|
|
86
|
+
export declare function getMergedCBExchangeWSRequestOperations<TWSTopic extends string = string>(operations: WsExchangeRequestOperation<TWSTopic>[]): WsExchangeRequestOperation<TWSTopic>;
|
|
87
|
+
/**
|
|
88
|
+
* Merge one or more WS Request operations (e.g. subscribe request) for
|
|
89
|
+
* CB Exchange into one, allowing them to be sent as one request
|
|
90
|
+
*/
|
|
91
|
+
export declare function getMergedCBINTXRequestOperations<TWSTopic extends string = string>(operations: WsInternationalRequestOperation<TWSTopic>[]): WsInternationalRequestOperation<TWSTopic>;
|
|
92
|
+
/**
|
|
93
|
+
* Return sign used to authenticate CB Exchange WS requests
|
|
94
|
+
*/
|
|
95
|
+
export declare function getCBExchangeWSSign(apiSecret: string): Promise<{
|
|
96
|
+
timestampInSeconds: string;
|
|
97
|
+
sign: string;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Return sign used to authenticate CB INTX WS requests
|
|
101
|
+
*/
|
|
102
|
+
export declare function getCBInternationalWSSign(apiKey: string, apiSecret: string, apiPassphrase: string): Promise<{
|
|
103
|
+
timestampInSeconds: string;
|
|
104
|
+
sign: string;
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Return sign used to authenticate CB Prime WS requests
|
|
108
|
+
*/
|
|
109
|
+
export declare function getCBPrimeWSSign(params: {
|
|
110
|
+
channelName: string;
|
|
111
|
+
svcAccountId: string;
|
|
112
|
+
portfolioId: string;
|
|
113
|
+
apiKey: string;
|
|
114
|
+
apiSecret: string;
|
|
115
|
+
product_ids?: string[];
|
|
116
|
+
}): Promise<{
|
|
117
|
+
timestampInSeconds: string;
|
|
118
|
+
sign: string;
|
|
119
|
+
}>;
|
|
120
|
+
export {};
|