@n1xyz/nord-ts 0.0.1 → 0.0.4

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 (237) hide show
  1. package/.eslintrc.js +11 -0
  2. package/README.md +148 -65
  3. package/dist/bridge/NordUser.d.ts +78 -0
  4. package/dist/bridge/NordUser.js +196 -0
  5. package/dist/bridge/client.d.ts +150 -0
  6. package/dist/bridge/client.js +394 -0
  7. package/dist/bridge/const.d.ts +23 -0
  8. package/dist/bridge/const.js +47 -0
  9. package/dist/bridge/index.d.ts +5 -0
  10. package/dist/bridge/index.js +23 -0
  11. package/dist/bridge/types.d.ts +118 -0
  12. package/dist/bridge/types.js +16 -0
  13. package/dist/bridge/utils.d.ts +64 -0
  14. package/dist/bridge/utils.js +131 -0
  15. package/dist/client.d.ts +70 -0
  16. package/dist/client.js +129 -0
  17. package/dist/const.d.ts +2 -5
  18. package/dist/const.js +18 -22
  19. package/dist/constants/endpoints.d.ts +65 -0
  20. package/dist/constants/endpoints.js +68 -0
  21. package/dist/gen/common.d.ts +6 -1
  22. package/dist/gen/common.js +19 -9
  23. package/dist/gen/nord.d.ts +75 -17
  24. package/dist/gen/nord.js +987 -423
  25. package/dist/idl/bridge.d.ts +2 -0
  26. package/dist/idl/bridge.js +703 -0
  27. package/dist/index.d.ts +8 -5
  28. package/dist/index.js +18 -2
  29. package/dist/models/account.d.ts +58 -0
  30. package/dist/models/account.js +6 -0
  31. package/dist/models/index.d.ts +8 -0
  32. package/dist/models/index.js +28 -0
  33. package/dist/models/market.d.ts +137 -0
  34. package/dist/models/market.js +6 -0
  35. package/dist/models/order.d.ts +211 -0
  36. package/dist/models/order.js +6 -0
  37. package/dist/models/token.d.ts +50 -0
  38. package/dist/models/token.js +6 -0
  39. package/dist/nord/Nord.d.ts +222 -49
  40. package/dist/nord/Nord.js +290 -278
  41. package/dist/nord/NordError.d.ts +23 -0
  42. package/dist/nord/NordError.js +48 -0
  43. package/dist/nord/NordImpl.d.ts +6 -2
  44. package/dist/nord/NordImpl.js +21 -1
  45. package/dist/nord/NordUser.d.ts +208 -42
  46. package/dist/nord/NordUser.js +389 -157
  47. package/dist/nord/Subscriber.d.ts +37 -0
  48. package/dist/nord/Subscriber.js +29 -0
  49. package/dist/nord/api/actions.d.ts +101 -0
  50. package/dist/nord/api/actions.js +250 -0
  51. package/dist/nord/api/core.d.ts +49 -0
  52. package/dist/nord/api/core.js +121 -0
  53. package/dist/nord/api/index.d.ts +1 -0
  54. package/dist/nord/api/index.js +17 -0
  55. package/dist/nord/api/market.d.ts +36 -0
  56. package/dist/nord/api/market.js +98 -0
  57. package/dist/nord/api/metrics.d.ts +67 -0
  58. package/dist/nord/api/metrics.js +132 -0
  59. package/dist/nord/api/orderFunctions.d.ts +168 -0
  60. package/dist/nord/api/orderFunctions.js +133 -0
  61. package/dist/nord/api/queries.d.ts +81 -0
  62. package/dist/nord/api/queries.js +187 -0
  63. package/dist/nord/client/Nord.d.ts +335 -0
  64. package/dist/nord/client/Nord.js +532 -0
  65. package/dist/nord/client/NordUser.d.ts +320 -0
  66. package/dist/nord/client/NordUser.js +701 -0
  67. package/dist/nord/core.d.ts +48 -0
  68. package/dist/nord/core.js +97 -0
  69. package/dist/nord/index.d.ts +9 -2
  70. package/dist/nord/index.js +30 -6
  71. package/dist/nord/market.d.ts +36 -0
  72. package/dist/nord/market.js +90 -0
  73. package/dist/nord/metrics.d.ts +67 -0
  74. package/dist/nord/metrics.js +124 -0
  75. package/dist/nord/models/Subscriber.d.ts +37 -0
  76. package/dist/nord/models/Subscriber.js +29 -0
  77. package/dist/nord/queries.d.ts +81 -0
  78. package/dist/nord/queries.js +181 -0
  79. package/dist/nord/types.d.ts +88 -0
  80. package/dist/nord/types.js +2 -0
  81. package/dist/nord/utils/NordError.d.ts +35 -0
  82. package/dist/nord/utils/NordError.js +46 -0
  83. package/dist/nord/websocket.d.ts +49 -0
  84. package/dist/nord/websocket.js +107 -0
  85. package/dist/operations/account.d.ts +58 -0
  86. package/dist/operations/account.js +112 -0
  87. package/dist/operations/market.d.ts +65 -0
  88. package/dist/operations/market.js +131 -0
  89. package/dist/operations/orders.d.ts +57 -0
  90. package/dist/operations/orders.js +129 -0
  91. package/dist/solana/NordUser.d.ts +78 -0
  92. package/dist/solana/NordUser.js +196 -0
  93. package/dist/solana/client.d.ts +139 -0
  94. package/dist/solana/client.js +360 -0
  95. package/dist/solana/const.d.ts +23 -0
  96. package/dist/solana/const.js +47 -0
  97. package/dist/solana/index.d.ts +5 -0
  98. package/dist/solana/index.js +23 -0
  99. package/dist/solana/types.d.ts +118 -0
  100. package/dist/solana/types.js +16 -0
  101. package/dist/solana/utils.d.ts +64 -0
  102. package/dist/solana/utils.js +131 -0
  103. package/dist/types/api.d.ts +152 -0
  104. package/dist/types/api.js +6 -0
  105. package/dist/types/config.d.ts +34 -0
  106. package/dist/types/config.js +6 -0
  107. package/dist/types.d.ts +144 -87
  108. package/dist/types.js +13 -2
  109. package/dist/utils/errors.d.ts +96 -0
  110. package/dist/utils/errors.js +132 -0
  111. package/dist/utils/http.d.ts +35 -0
  112. package/dist/utils/http.js +105 -0
  113. package/dist/utils.d.ts +14 -5
  114. package/dist/utils.js +26 -7
  115. package/dist/websocket/NordWebSocketClient.d.ts +71 -0
  116. package/dist/websocket/NordWebSocketClient.js +343 -0
  117. package/dist/websocket/client.d.ts +93 -0
  118. package/dist/websocket/client.js +222 -0
  119. package/dist/websocket/events.d.ts +19 -0
  120. package/dist/websocket/events.js +2 -0
  121. package/dist/websocket/index.d.ts +2 -0
  122. package/dist/websocket/index.js +5 -0
  123. package/dist/websocket.d.ts +55 -0
  124. package/dist/websocket.js +211 -0
  125. package/docs/assets/navigation.js +1 -1
  126. package/docs/assets/search.js +1 -1
  127. package/docs/classes/Nord.html +2 -15
  128. package/docs/classes/NordUser.html +4 -4
  129. package/docs/enums/FillMode.html +2 -2
  130. package/docs/enums/KeyType.html +2 -2
  131. package/docs/enums/PeakTpsPeriodUnit.html +2 -2
  132. package/docs/enums/Side.html +2 -2
  133. package/docs/functions/assert.html +1 -1
  134. package/docs/functions/bigIntToProtoU128.html +1 -1
  135. package/docs/functions/checkPubKeyLength.html +1 -1
  136. package/docs/functions/checkedFetch.html +1 -1
  137. package/docs/functions/decodeLengthDelimited.html +1 -1
  138. package/docs/functions/encodeLengthDelimited.html +1 -1
  139. package/docs/functions/fillModeToProtoFillMode.html +1 -1
  140. package/docs/functions/findMarket.html +1 -1
  141. package/docs/functions/findToken.html +1 -1
  142. package/docs/functions/makeWalletSignFn.html +1 -1
  143. package/docs/functions/optExpect.html +1 -1
  144. package/docs/functions/optMap.html +1 -1
  145. package/docs/functions/optUnwrap.html +1 -1
  146. package/docs/functions/panic.html +1 -1
  147. package/docs/functions/signAction.html +1 -1
  148. package/docs/functions/toScaledU128.html +1 -1
  149. package/docs/functions/toScaledU64.html +1 -1
  150. package/docs/interfaces/Account.html +2 -2
  151. package/docs/interfaces/ActionInfo.html +2 -2
  152. package/docs/interfaces/ActionQuery.html +2 -2
  153. package/docs/interfaces/ActionResponse.html +2 -2
  154. package/docs/interfaces/ActionsExtendedInfo.html +2 -2
  155. package/docs/interfaces/ActionsQuery.html +2 -2
  156. package/docs/interfaces/ActionsResponse.html +2 -2
  157. package/docs/interfaces/AggregateMetrics.html +2 -2
  158. package/docs/interfaces/BlockQuery.html +2 -2
  159. package/docs/interfaces/BlockResponse.html +2 -2
  160. package/docs/interfaces/BlockSummary.html +2 -2
  161. package/docs/interfaces/BlockSummaryResponse.html +2 -2
  162. package/docs/interfaces/DeltaEvent.html +2 -2
  163. package/docs/interfaces/ERC20TokenInfo.html +2 -2
  164. package/docs/interfaces/Info.html +2 -2
  165. package/docs/interfaces/Market.html +2 -2
  166. package/docs/interfaces/MarketStats.html +2 -2
  167. package/docs/interfaces/MarketsStatsResponse.html +2 -2
  168. package/docs/interfaces/NordConfig.html +2 -2
  169. package/docs/interfaces/Order.html +2 -2
  170. package/docs/interfaces/OrderInfo.html +2 -2
  171. package/docs/interfaces/PerpMarketStats.html +2 -2
  172. package/docs/interfaces/RollmanActionExtendedInfo.html +2 -2
  173. package/docs/interfaces/RollmanActionInfo.html +2 -2
  174. package/docs/interfaces/RollmanActionResponse.html +2 -2
  175. package/docs/interfaces/RollmanActionsResponse.html +2 -2
  176. package/docs/interfaces/RollmanBlockResponse.html +2 -2
  177. package/docs/interfaces/SubscriberConfig.html +2 -2
  178. package/docs/interfaces/Token.html +2 -2
  179. package/docs/interfaces/Trade.html +2 -2
  180. package/docs/interfaces/Trades.html +2 -2
  181. package/docs/modules.html +0 -7
  182. package/docs/types/BigIntValue.html +1 -1
  183. package/docs/variables/DEBUG_KEYS.html +1 -1
  184. package/docs/variables/DEFAULT_FUNDING_AMOUNTS.html +1 -1
  185. package/docs/variables/DEV_CONTRACT_ADDRESS.html +1 -1
  186. package/docs/variables/DEV_TOKEN_INFOS.html +1 -1
  187. package/docs/variables/DEV_URL.html +1 -1
  188. package/docs/variables/ERC20_ABI.html +1 -1
  189. package/docs/variables/EVM_DEV_URL.html +1 -1
  190. package/docs/variables/FAUCET_PRIVATE_ADDRESS.html +1 -1
  191. package/docs/variables/MAX_BUFFER_LEN.html +1 -1
  192. package/docs/variables/NORD_GETTERS_FACET_ABI.html +1 -1
  193. package/docs/variables/NORD_RAMP_FACET_ABI.html +1 -1
  194. package/docs/variables/SESSION_TTL.html +1 -1
  195. package/docs/variables/WEBSERVER_DEV_URL.html +1 -1
  196. package/docs/variables/ZERO_DECIMAL.html +1 -1
  197. package/package.json +10 -12
  198. package/src/bridge/client.ts +487 -0
  199. package/src/bridge/const.ts +53 -0
  200. package/src/bridge/index.ts +7 -0
  201. package/src/bridge/types.ts +127 -0
  202. package/src/bridge/utils.ts +140 -0
  203. package/src/const.ts +20 -25
  204. package/src/gen/common.ts +27 -10
  205. package/src/gen/nord.ts +1044 -483
  206. package/src/idl/bridge.ts +702 -0
  207. package/src/index.ts +24 -5
  208. package/src/nord/{actions.ts → api/actions.ts} +33 -37
  209. package/src/nord/api/core.ts +130 -0
  210. package/src/nord/api/market.ts +125 -0
  211. package/src/nord/api/metrics.ts +154 -0
  212. package/src/nord/api/queries.ts +236 -0
  213. package/src/nord/client/Nord.ts +652 -0
  214. package/src/nord/client/NordUser.ts +1105 -0
  215. package/src/nord/index.ts +16 -2
  216. package/src/nord/models/Subscriber.ts +57 -0
  217. package/src/nord/utils/NordError.ts +72 -0
  218. package/src/types.ts +170 -99
  219. package/src/utils.ts +40 -19
  220. package/src/websocket/NordWebSocketClient.ts +432 -0
  221. package/src/websocket/events.ts +31 -0
  222. package/src/websocket/index.ts +2 -0
  223. package/tests/utils.spec.ts +24 -24
  224. package/docs/classes/Subscriber.html +0 -6
  225. package/docs/functions/createWebSocketSubscription.html +0 -12
  226. package/docs/interfaces/OrderbookOrder.html +0 -6
  227. package/docs/interfaces/OrderbookResponse.html +0 -10
  228. package/docs/interfaces/TradeInfo.html +0 -20
  229. package/docs/interfaces/TradesQueryParams.html +0 -10
  230. package/docs/interfaces/TradesResponse.html +0 -12
  231. package/src/abis/ERC20_ABI.ts +0 -310
  232. package/src/abis/NORD_GETTERS_FACET_ABI.ts +0 -192
  233. package/src/abis/NORD_RAMP_FACET_ABI.ts +0 -141
  234. package/src/abis/index.ts +0 -3
  235. package/src/nord/Nord.ts +0 -504
  236. package/src/nord/NordImpl.ts +0 -8
  237. package/src/nord/NordUser.ts +0 -469
@@ -0,0 +1,432 @@
1
+ import WebSocket from 'ws';
2
+ import { EventEmitter } from 'events';
3
+ import {
4
+ WebSocketMessage,
5
+ WebSocketMessageType,
6
+ WebSocketSubscription,
7
+ WebSocketTradeUpdate,
8
+ WebSocketDeltaUpdate,
9
+ WebSocketUserUpdate,
10
+ } from '../types';
11
+ import { NordWebSocketClientEvents } from './events';
12
+
13
+ // Define a type that works for both Node.js ws and browser WebSocket
14
+ type BrowserWebSocket = {
15
+ OPEN: number;
16
+ CONNECTING: number;
17
+ CLOSING: number;
18
+ CLOSED: number;
19
+ readyState: number;
20
+ send: (data: string) => void;
21
+ close: () => void;
22
+ onopen: ((this: any, ev: any) => any) | null;
23
+ onmessage: ((this: any, ev: { data: any }) => any) | null;
24
+ onclose: ((this: any, ev: any) => any) | null;
25
+ onerror: ((this: any, ev: any) => any) | null;
26
+ };
27
+
28
+ type WebSocketInstance = WebSocket | BrowserWebSocket;
29
+
30
+ const VALID_STREAM_TYPES = ['trades', 'deltas', 'user'];
31
+
32
+ // Constants for WebSocket readyState
33
+ const WS_OPEN = 1;
34
+
35
+ /**
36
+ * WebSocket client for Nord exchange
37
+ *
38
+ * This client connects to one of the specific Nord WebSocket endpoints:
39
+ * - /ws/trades - For trade updates
40
+ * - /ws/deltas - For orderbook delta updates
41
+ * - /ws/user - For user-specific updates
42
+ *
43
+ * Each endpoint handles a specific type of data and subscriptions must match
44
+ * the endpoint type (e.g., only 'trades@BTCUSDC' subscriptions are valid on
45
+ * the /ws/trades endpoint).
46
+ */
47
+ export class NordWebSocketClient
48
+ extends EventEmitter
49
+ implements NordWebSocketClientEvents
50
+ {
51
+ private ws: WebSocketInstance | null = null;
52
+ private url: string;
53
+ private subscriptions: Set<string> = new Set();
54
+ private reconnectAttempts: number = 0;
55
+ private maxReconnectAttempts: number = 5;
56
+ private reconnectDelay: number = 1000;
57
+ private pingInterval: NodeJS.Timeout | null = null;
58
+ private pingTimeout: NodeJS.Timeout | null = null;
59
+ private isBrowser: boolean;
60
+
61
+ /**
62
+ * Create a new NordWebSocketClient
63
+ * @param url WebSocket server URL
64
+ */
65
+ constructor(url: string) {
66
+ super();
67
+ this.url = url;
68
+ // Check if we're in a browser environment
69
+ // The most reliable way is to check for Node.js process
70
+ this.isBrowser =
71
+ typeof process === 'undefined' ||
72
+ !process.versions ||
73
+ !process.versions.node;
74
+ }
75
+
76
+ /**
77
+ * Validate stream format
78
+ * @param stream Stream identifier to validate
79
+ * @throws Error if stream format is invalid
80
+ */
81
+ private validateStream(stream: string): void {
82
+ const [type, params] = stream.split('@');
83
+
84
+ if (!type || !params) {
85
+ throw new Error(
86
+ `Invalid stream format: ${stream}. Expected format: <type>@<params>`,
87
+ );
88
+ }
89
+
90
+ // Extract the endpoint from the URL
91
+ const urlPath = new URL(this.url).pathname;
92
+ const endpoint = urlPath.split('/').pop();
93
+
94
+ // Ensure the stream type matches the endpoint we're connected to
95
+ if (endpoint && type !== endpoint) {
96
+ throw new Error(
97
+ `Stream type '${type}' doesn't match the connected endpoint '${endpoint}'`,
98
+ );
99
+ }
100
+
101
+ if (!VALID_STREAM_TYPES.includes(type)) {
102
+ throw new Error(
103
+ `Invalid stream type: ${type}. Valid types are: ${VALID_STREAM_TYPES.join(', ')}`,
104
+ );
105
+ }
106
+
107
+ if (type === 'user' && !/^\d+$/.test(params)) {
108
+ throw new Error(
109
+ `Invalid user ID in stream: ${params}. Expected numeric ID`,
110
+ );
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Setup WebSocket ping/pong heartbeat
116
+ */
117
+ private setupHeartbeat(): void {
118
+ if (this.pingInterval) {
119
+ clearInterval(this.pingInterval);
120
+ }
121
+ if (this.pingTimeout) {
122
+ clearTimeout(this.pingTimeout);
123
+ }
124
+
125
+ // In browser, we rely on the browser's WebSocket implementation to handle ping/pong
126
+ if (this.isBrowser) {
127
+ return;
128
+ }
129
+
130
+ this.pingInterval = setInterval(() => {
131
+ if (this.ws && !this.isBrowser) {
132
+ // Only use ping() method in Node.js environment
133
+ (this.ws as WebSocket).ping();
134
+
135
+ // Set timeout for pong response
136
+ this.pingTimeout = setTimeout(() => {
137
+ this.emit('error', new Error('WebSocket ping timeout'));
138
+ this.close();
139
+ this.reconnect();
140
+ }, 5000); // 5 second timeout
141
+ }
142
+ }, 30000); // Send ping every 30 seconds
143
+ }
144
+
145
+ /**
146
+ * Get the appropriate WebSocket class based on environment
147
+ */
148
+ private getWebSocketClass(): any {
149
+ if (this.isBrowser) {
150
+ // In browser environments
151
+ // @ts-ignore - Check for WebSocket in globalThis
152
+ if (typeof globalThis !== 'undefined' && globalThis.WebSocket) {
153
+ // @ts-ignore - Return WebSocket from globalThis
154
+ return globalThis.WebSocket;
155
+ }
156
+ throw new Error('WebSocket is not available in this environment');
157
+ } else {
158
+ // In Node.js
159
+ return WebSocket;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Connect to the Nord WebSocket server
165
+ */
166
+ public connect(): void {
167
+ if (this.ws) {
168
+ return;
169
+ }
170
+
171
+ try {
172
+ const WebSocketClass = this.getWebSocketClass();
173
+
174
+ if (this.isBrowser) {
175
+ // Browser WebSocket setup
176
+ this.ws = new WebSocketClass(this.url) as BrowserWebSocket;
177
+
178
+ (this.ws as BrowserWebSocket).onopen = () => {
179
+ this.emit('connected');
180
+ this.reconnectAttempts = 0;
181
+ this.reconnectDelay = 1000;
182
+
183
+ // Resubscribe to previous subscriptions
184
+ if (this.subscriptions.size > 0) {
185
+ this.subscribe([...this.subscriptions]);
186
+ }
187
+ };
188
+
189
+ (this.ws as BrowserWebSocket).onmessage = (event: { data: any }) => {
190
+ try {
191
+ const message = JSON.parse(
192
+ event.data as string,
193
+ ) as WebSocketMessage;
194
+ this.handleMessage(message);
195
+ } catch (error) {
196
+ this.emit(
197
+ 'error',
198
+ new Error(
199
+ `Failed to parse message: ${error instanceof Error ? error.message : String(error)}`,
200
+ ),
201
+ );
202
+ }
203
+ };
204
+
205
+ (this.ws as BrowserWebSocket).onclose = (event: any) => {
206
+ const reason =
207
+ event && event.reason ? ` Reason: ${event.reason}` : '';
208
+ const code = event && event.code ? ` Code: ${event.code}` : '';
209
+ this.emit('disconnected');
210
+ console.log(`WebSocket closed.${code}${reason}`);
211
+ this.reconnect();
212
+ };
213
+
214
+ (this.ws as BrowserWebSocket).onerror = (event: any) => {
215
+ const errorMsg = `WebSocket error: ${event && event.type ? event.type : 'unknown'}`;
216
+ console.error(errorMsg, event);
217
+ this.emit('error', new Error(errorMsg));
218
+ };
219
+ } else {
220
+ // Node.js WebSocket setup
221
+ const nodeWs = new WebSocketClass(this.url) as WebSocket;
222
+ this.ws = nodeWs;
223
+
224
+ nodeWs.on('open', () => {
225
+ this.emit('connected');
226
+ this.reconnectAttempts = 0;
227
+ this.reconnectDelay = 1000;
228
+ this.setupHeartbeat();
229
+
230
+ // Resubscribe to previous subscriptions
231
+ if (this.subscriptions.size > 0) {
232
+ this.subscribe([...this.subscriptions]);
233
+ }
234
+ });
235
+
236
+ nodeWs.on('message', (data: WebSocket.Data) => {
237
+ try {
238
+ const message = JSON.parse(data.toString()) as WebSocketMessage;
239
+ this.handleMessage(message);
240
+ } catch (error) {
241
+ this.emit(
242
+ 'error',
243
+ new Error(
244
+ `Failed to parse message: ${error instanceof Error ? error.message : String(error)}`,
245
+ ),
246
+ );
247
+ }
248
+ });
249
+
250
+ nodeWs.on('close', (code: number, reason: string) => {
251
+ this.emit('disconnected');
252
+ console.log(`WebSocket closed. Code: ${code} Reason: ${reason}`);
253
+ if (this.pingInterval) {
254
+ clearInterval(this.pingInterval);
255
+ }
256
+ if (this.pingTimeout) {
257
+ clearTimeout(this.pingTimeout);
258
+ }
259
+ this.reconnect();
260
+ });
261
+
262
+ nodeWs.on('error', (error: Error) => {
263
+ console.error('WebSocket error:', error);
264
+ this.emit('error', error);
265
+ });
266
+
267
+ nodeWs.on('pong', () => {
268
+ if (this.pingTimeout) {
269
+ clearTimeout(this.pingTimeout);
270
+ }
271
+ });
272
+ }
273
+ } catch (error) {
274
+ const errorMsg = `Failed to initialize WebSocket: ${error instanceof Error ? error.message : String(error)}`;
275
+ console.error(errorMsg);
276
+ this.emit('error', new Error(errorMsg));
277
+ }
278
+ }
279
+
280
+ /**
281
+ * Subscribe to one or more streams
282
+ * @param streams Array of streams to subscribe to (e.g. ["trades@BTCUSDC", "deltas@BTCUSDC"])
283
+ */
284
+ public subscribe(streams: string[]): void {
285
+ // Validate all streams first
286
+ try {
287
+ streams.forEach((stream) => this.validateStream(stream));
288
+ } catch (error) {
289
+ this.emit(
290
+ 'error',
291
+ error instanceof Error ? error : new Error(String(error)),
292
+ );
293
+ return;
294
+ }
295
+
296
+ if (
297
+ !this.ws ||
298
+ (this.isBrowser
299
+ ? (this.ws as BrowserWebSocket).readyState !== WS_OPEN
300
+ : (this.ws as WebSocket).readyState !== WebSocket.OPEN)
301
+ ) {
302
+ streams.forEach((stream) => this.subscriptions.add(stream));
303
+ return;
304
+ }
305
+
306
+ const message: WebSocketSubscription = {
307
+ type: WebSocketMessageType.Subscribe,
308
+ streams,
309
+ };
310
+
311
+ try {
312
+ const messageStr = JSON.stringify(message);
313
+ if (this.isBrowser) {
314
+ (this.ws as BrowserWebSocket).send(messageStr);
315
+ } else {
316
+ (this.ws as WebSocket).send(messageStr);
317
+ }
318
+ streams.forEach((stream) => this.subscriptions.add(stream));
319
+ } catch (error) {
320
+ this.emit(
321
+ 'error',
322
+ error instanceof Error ? error : new Error(String(error)),
323
+ );
324
+ }
325
+ }
326
+
327
+ /**
328
+ * Unsubscribe from one or more streams
329
+ * @param streams Array of streams to unsubscribe from
330
+ */
331
+ public unsubscribe(streams: string[]): void {
332
+ // Validate all streams first
333
+ try {
334
+ streams.forEach((stream) => this.validateStream(stream));
335
+ } catch (error) {
336
+ this.emit(
337
+ 'error',
338
+ error instanceof Error ? error : new Error(String(error)),
339
+ );
340
+ return;
341
+ }
342
+
343
+ if (
344
+ !this.ws ||
345
+ (this.isBrowser
346
+ ? (this.ws as BrowserWebSocket).readyState !== WS_OPEN
347
+ : (this.ws as WebSocket).readyState !== WebSocket.OPEN)
348
+ ) {
349
+ streams.forEach((stream) => this.subscriptions.delete(stream));
350
+ return;
351
+ }
352
+
353
+ const message: WebSocketSubscription = {
354
+ type: WebSocketMessageType.Unsubscribe,
355
+ streams,
356
+ };
357
+
358
+ try {
359
+ const messageStr = JSON.stringify(message);
360
+ if (this.isBrowser) {
361
+ (this.ws as BrowserWebSocket).send(messageStr);
362
+ } else {
363
+ (this.ws as WebSocket).send(messageStr);
364
+ }
365
+ streams.forEach((stream) => this.subscriptions.delete(stream));
366
+ } catch (error) {
367
+ this.emit(
368
+ 'error',
369
+ error instanceof Error ? error : new Error(String(error)),
370
+ );
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Close the WebSocket connection
376
+ */
377
+ public close(): void {
378
+ if (this.ws) {
379
+ if (this.isBrowser) {
380
+ (this.ws as BrowserWebSocket).close();
381
+ } else {
382
+ (this.ws as WebSocket).close();
383
+ }
384
+ this.ws = null;
385
+ }
386
+ if (this.pingInterval) {
387
+ clearInterval(this.pingInterval);
388
+ this.pingInterval = null;
389
+ }
390
+ if (this.pingTimeout) {
391
+ clearTimeout(this.pingTimeout);
392
+ this.pingTimeout = null;
393
+ }
394
+ this.subscriptions.clear();
395
+ }
396
+
397
+ /**
398
+ * Handle incoming WebSocket messages
399
+ * @param message WebSocket message
400
+ */
401
+ private handleMessage(message: WebSocketMessage): void {
402
+ switch (message.type) {
403
+ case WebSocketMessageType.TradeUpdate:
404
+ this.emit('trade', message as WebSocketTradeUpdate);
405
+ break;
406
+ case WebSocketMessageType.DeltaUpdate:
407
+ this.emit('delta', message as WebSocketDeltaUpdate);
408
+ break;
409
+ case WebSocketMessageType.UserUpdate:
410
+ this.emit('user', message as WebSocketUserUpdate);
411
+ break;
412
+ default:
413
+ this.emit('error', new Error(`Unknown message type: ${message.type}`));
414
+ }
415
+ }
416
+
417
+ /**
418
+ * Attempt to reconnect to the WebSocket server
419
+ */
420
+ private reconnect(): void {
421
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
422
+ this.emit('error', new Error('Max reconnection attempts reached'));
423
+ return;
424
+ }
425
+
426
+ setTimeout(() => {
427
+ this.reconnectAttempts++;
428
+ this.reconnectDelay *= 2; // Exponential backoff
429
+ this.connect();
430
+ }, this.reconnectDelay);
431
+ }
432
+ }
@@ -0,0 +1,31 @@
1
+ import {
2
+ WebSocketTradeUpdate,
3
+ WebSocketDeltaUpdate,
4
+ WebSocketUserUpdate,
5
+ } from '../types';
6
+
7
+ /**
8
+ * Event type definitions for the NordWebSocketClient
9
+ */
10
+ export interface NordWebSocketEvents {
11
+ connected: () => void;
12
+ disconnected: () => void;
13
+ error: (error: Error) => void;
14
+ trade: (update: WebSocketTradeUpdate) => void;
15
+ delta: (update: WebSocketDeltaUpdate) => void;
16
+ user: (update: WebSocketUserUpdate) => void;
17
+ }
18
+
19
+ /**
20
+ * Type declaration for NordWebSocketClient event methods
21
+ */
22
+ export declare interface NordWebSocketClientEvents {
23
+ on<E extends keyof NordWebSocketEvents>(
24
+ event: E,
25
+ listener: NordWebSocketEvents[E],
26
+ ): this;
27
+ emit<E extends keyof NordWebSocketEvents>(
28
+ event: E,
29
+ ...args: Parameters<NordWebSocketEvents[E]>
30
+ ): boolean;
31
+ }
@@ -0,0 +1,2 @@
1
+ export { NordWebSocketClient } from './NordWebSocketClient';
2
+ export { NordWebSocketEvents, NordWebSocketClientEvents } from './events';
@@ -1,15 +1,15 @@
1
- import { describe, it, expect } from "@jest/globals";
1
+ import { describe, it, expect } from '@jest/globals';
2
2
  import {
3
3
  bigIntToProtoU128,
4
4
  toScaledU64,
5
5
  toScaledU128,
6
6
  encodeLengthDelimited,
7
7
  decodeLengthDelimited,
8
- } from "../src/utils";
9
- import Decimal from "decimal.js";
10
- import * as proto from "../src/gen/nord";
8
+ } from '../src/utils';
9
+ import Decimal from 'decimal.js';
10
+ import * as proto from '../src/gen/nord';
11
11
 
12
- describe("toScaledU64", () => {
12
+ describe('toScaledU64', () => {
13
13
  // Used as scaling medium
14
14
  const D64 = Decimal.clone({
15
15
  precision: 20,
@@ -35,12 +35,12 @@ describe("toScaledU64", () => {
35
35
  });
36
36
 
37
37
  const failure: Array<[Decimal.Value, number, string]> = [
38
- [-1, 0, "Number is negative"],
39
- [-1000, 2, "Number is negative"],
40
- [0.1, 0, "Precision loss"],
41
- [0.0001, 3, "Precision loss"],
42
- [MaxDec.add(1), 0, "Integer is out of range"],
43
- [MaxDec.add(1).div(1000), 3, "Integer is out of range"],
38
+ [-1, 0, 'Number is negative'],
39
+ [-1000, 2, 'Number is negative'],
40
+ [0.1, 0, 'Precision loss'],
41
+ [0.0001, 3, 'Precision loss'],
42
+ [MaxDec.add(1), 0, 'Integer is out of range'],
43
+ [MaxDec.add(1).div(1000), 3, 'Integer is out of range'],
44
44
  ];
45
45
 
46
46
  failure.forEach((sample) => {
@@ -50,7 +50,7 @@ describe("toScaledU64", () => {
50
50
  });
51
51
  });
52
52
 
53
- describe("toScaledU128", () => {
53
+ describe('toScaledU128', () => {
54
54
  // Used as scaling medium
55
55
  const D128 = Decimal.clone({
56
56
  precision: 40,
@@ -76,12 +76,12 @@ describe("toScaledU128", () => {
76
76
  });
77
77
 
78
78
  const failure: Array<[Decimal.Value, number, string]> = [
79
- [-1, 0, "Number is negative"],
80
- [-1000, 2, "Number is negative"],
81
- [0.1, 0, "Precision loss"],
82
- [0.0001, 3, "Precision loss"],
83
- [MaxDec.add(1), 0, "Integer is out of range"],
84
- [MaxDec.add(1).div(1000), 3, "Integer is out of range"],
79
+ [-1, 0, 'Number is negative'],
80
+ [-1000, 2, 'Number is negative'],
81
+ [0.1, 0, 'Precision loss'],
82
+ [0.0001, 3, 'Precision loss'],
83
+ [MaxDec.add(1), 0, 'Integer is out of range'],
84
+ [MaxDec.add(1).div(1000), 3, 'Integer is out of range'],
85
85
  ];
86
86
 
87
87
  failure.forEach((sample) => {
@@ -94,7 +94,7 @@ describe("toScaledU128", () => {
94
94
  const U64_MAX = (1n << 64n) - 1n;
95
95
  const U128_MAX = (1n << 128n) - 1n;
96
96
 
97
- describe("bigIntToProtoU128", () => {
97
+ describe('bigIntToProtoU128', () => {
98
98
  const success: Array<[bigint, { lo: bigint; hi: bigint }]> = [
99
99
  [0n, { lo: 0n, hi: 0n }],
100
100
  [1n, { lo: 1n, hi: 0n }],
@@ -112,8 +112,8 @@ describe("bigIntToProtoU128", () => {
112
112
  });
113
113
 
114
114
  const failure: Array<[bigint, string]> = [
115
- [-1n, "Negative number"],
116
- [U128_MAX + 1n, "U128 overflow"],
115
+ [-1n, 'Negative number'],
116
+ [U128_MAX + 1n, 'U128 overflow'],
117
117
  ];
118
118
 
119
119
  failure.forEach((sample, index) => {
@@ -123,12 +123,12 @@ describe("bigIntToProtoU128", () => {
123
123
  });
124
124
  });
125
125
 
126
- describe("proto.Action encode-decode loop", () => {
126
+ describe('proto.Action encode-decode loop', () => {
127
127
  const action: proto.Action = {
128
128
  currentTimestamp: 0n,
129
129
  nonce: 0,
130
130
  kind: {
131
- $case: "placeOrder",
131
+ $case: 'placeOrder',
132
132
  value: {
133
133
  sessionId: 42n,
134
134
  marketId: 9,
@@ -145,7 +145,7 @@ describe("proto.Action encode-decode loop", () => {
145
145
  },
146
146
  };
147
147
 
148
- it("action encode-decode roundabout should succeed", () => {
148
+ it('action encode-decode roundabout should succeed', () => {
149
149
  const encoded = encodeLengthDelimited(action, proto.Action);
150
150
  const decoded: proto.Action = decodeLengthDelimited(encoded, proto.Action);
151
151
 
@@ -1,6 +0,0 @@
1
- <!DOCTYPE html><html class="default" lang="en"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Subscriber | @layer-n/nord-ts</title><meta name="description" content="Documentation for @layer-n/nord-ts"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search" data-base=".."><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">@layer-n/nord-ts</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">@layer-n/nord-ts</a></li><li><a href="Subscriber.html">Subscriber</a></li></ul><h1>Class Subscriber</h1></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/n1xyz/nord-ts/blob/381766a/src/nord/Nord.ts#L454">nord/Nord.ts:454</a></li></ul></aside><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-index-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Constructors</h3><div class="tsd-index-list"><a href="Subscriber.html#constructor" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-512"></use></svg><span>constructor</span></a>
2
- </div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Properties</h3><div class="tsd-index-list"><a href="Subscriber.html#buffer" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>buffer</span></a>
3
- <a href="Subscriber.html#maxBufferLen" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>max<wbr/>Buffer<wbr/>Len</span></a>
4
- <a href="Subscriber.html#streamURL" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>streamURL</span></a>
5
- </div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Methods</h3><div class="tsd-index-list"><a href="Subscriber.html#subscribe" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>subscribe</span></a>
6
- </div></section></div></details></section></section><section class="tsd-panel-group tsd-member-group"><h2>Constructors</h2><section class="tsd-panel tsd-member"><a id="constructor" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>constructor</span><a href="#constructor" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="constructor.new_Subscriber" class="tsd-anchor"></a><span class="tsd-kind-constructor-signature">new <wbr/>Subscriber</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">config</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="Subscriber.html" class="tsd-signature-type tsd-kind-class">Subscriber</a><a href="#constructor.new_Subscriber" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">config</span>: <a href="../interfaces/SubscriberConfig.html" class="tsd-signature-type tsd-kind-interface">SubscriberConfig</a></span></li></ul></div><h4 class="tsd-returns-title">Returns <a href="Subscriber.html" class="tsd-signature-type tsd-kind-class">Subscriber</a></h4><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/n1xyz/nord-ts/blob/381766a/src/nord/Nord.ts#L459">nord/Nord.ts:459</a></li></ul></aside></li></ul></section></section><section class="tsd-panel-group tsd-member-group"><h2>Properties</h2><section class="tsd-panel tsd-member"><a id="buffer" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>buffer</span><a href="#buffer" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">buffer</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">(</span><a href="../interfaces/DeltaEvent.html" class="tsd-signature-type tsd-kind-interface">DeltaEvent</a><span class="tsd-signature-symbol"> | </span><a href="../interfaces/Trades.html" class="tsd-signature-type tsd-kind-interface">Trades</a><span class="tsd-signature-symbol"> | </span><a href="../interfaces/Account.html" class="tsd-signature-type tsd-kind-interface">Account</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">[]</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/n1xyz/nord-ts/blob/381766a/src/nord/Nord.ts#L456">nord/Nord.ts:456</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="maxBufferLen" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>max<wbr/>Buffer<wbr/>Len</span><a href="#maxBufferLen" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">max<wbr/>Buffer<wbr/>Len</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/n1xyz/nord-ts/blob/381766a/src/nord/Nord.ts#L457">nord/Nord.ts:457</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="streamURL" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>streamURL</span><a href="#streamURL" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">streamURL</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/n1xyz/nord-ts/blob/381766a/src/nord/Nord.ts#L455">nord/Nord.ts:455</a></li></ul></aside></section></section><section class="tsd-panel-group tsd-member-group"><h2>Methods</h2><section class="tsd-panel tsd-member"><a id="subscribe" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>subscribe</span><a href="#subscribe" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="subscribe.subscribe-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">subscribe</span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span><a href="#subscribe.subscribe-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/n1xyz/nord-ts/blob/381766a/src/nord/Nord.ts#L465">nord/Nord.ts:465</a></li></ul></aside></li></ul></section></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-index-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><h4 class="uppercase">Member Visibility</h4><form><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-private" name="private"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Private</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></form></div><div class="tsd-theme-toggle"><h4 class="uppercase">Theme</h4><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-index-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#constructor" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-512"></use></svg><span>constructor</span></a><a href="#buffer" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>buffer</span></a><a href="#maxBufferLen" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>max<wbr/>Buffer<wbr/>Len</span></a><a href="#streamURL" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>streamURL</span></a><a href="#subscribe" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>subscribe</span></a></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1"></use></svg><span>@layer-n/nord-ts</span></a><ul class="tsd-small-nested-navigation" id="tsd-nav-container" data-base=".."><li>Loading...</li></ul></nav></div></div></div><div class="tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div></body></html>
@@ -1,12 +0,0 @@
1
- <!DOCTYPE html><html class="default" lang="en"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>createWebSocketSubscription | @layer-n/nord-ts</title><meta name="description" content="Documentation for @layer-n/nord-ts"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search" data-base=".."><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">@layer-n/nord-ts</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">@layer-n/nord-ts</a></li><li><a href="createWebSocketSubscription.html">createWebSocketSubscription</a></li></ul><h1>Function createWebSocketSubscription</h1></div><section class="tsd-panel"><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="createWebSocketSubscription" class="tsd-anchor"></a><span class="tsd-kind-call-signature">create<wbr/>Web<wbr/>Socket<wbr/>Subscription</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">baseUrl</span>, <span class="tsd-kind-parameter">streams</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../classes/Subscriber.html" class="tsd-signature-type tsd-kind-class">Subscriber</a><a href="#createWebSocketSubscription" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-comment tsd-typography"><p>Creates a WebSocket subscription to specified streams</p>
2
- </div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">baseUrl</span>: <span class="tsd-signature-type">string</span></span><div class="tsd-comment tsd-typography"><p>Base URL of the API</p>
3
- </div><div class="tsd-comment tsd-typography"></div></li><li><span><span class="tsd-kind-parameter">streams</span>: <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">[]</span></span><div class="tsd-comment tsd-typography"><p>Array of streams to subscribe to</p>
4
- </div><div class="tsd-comment tsd-typography"></div></li></ul></div><h4 class="tsd-returns-title">Returns <a href="../classes/Subscriber.html" class="tsd-signature-type tsd-kind-class">Subscriber</a></h4><p>A Subscriber instance</p>
5
- <p>Syntax for streams:</p>
6
- <ul>
7
- <li>trades@<symbol>: Subscribe to trades for a market</li>
8
- <li>deltas@<symbol>: Subscribe to orderbook deltas for a market</li>
9
- <li>user@<user id>: Subscribe to user account updates</li>
10
- </ul>
11
- <p>Example: createWebSocketSubscription(&#39;<a href="https://alpha-api.layern.network">https://alpha-api.layern.network</a>&#39;, [&#39;trades@BTCUSDC&#39;, &#39;deltas@BTCUSDC&#39;, &#39;user@0&#39;])</p>
12
- <div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/n1xyz/nord-ts/blob/381766a/src/nord/Nord.ts#L494">nord/Nord.ts:494</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-index-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><h4 class="uppercase">Member Visibility</h4><form><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-private" name="private"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Private</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></form></div><div class="tsd-theme-toggle"><h4 class="uppercase">Theme</h4><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1"></use></svg><span>@layer-n/nord-ts</span></a><ul class="tsd-small-nested-navigation" id="tsd-nav-container" data-base=".."><li>Loading...</li></ul></nav></div></div></div><div class="tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div></body></html>