@n1xyz/nord-ts 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/actions.js +39 -82
  2. package/dist/bundle.js +79181 -0
  3. package/dist/client/Nord.d.ts +13 -2
  4. package/dist/client/Nord.js +68 -78
  5. package/dist/client/NordAdmin.d.ts +2 -2
  6. package/dist/client/NordAdmin.js +57 -89
  7. package/dist/client/NordUser.js +118 -147
  8. package/dist/const.js +5 -8
  9. package/dist/error.js +7 -5
  10. package/dist/gen/nord_pb.js +88 -92
  11. package/dist/gen/openapi.d.ts +83 -6
  12. package/dist/gen/openapi.js +1 -2
  13. package/dist/index.js +10 -49
  14. package/dist/types.d.ts +3 -0
  15. package/dist/types.js +21 -60
  16. package/dist/utils.js +38 -86
  17. package/dist/websocket/NordWebSocketClient.js +12 -17
  18. package/dist/websocket/Subscriber.js +6 -7
  19. package/dist/websocket/events.js +1 -2
  20. package/dist/websocket/index.js +10 -15
  21. package/package.json +3 -4
  22. package/dist/api/client.d.ts +0 -14
  23. package/dist/api/client.js +0 -45
  24. package/dist/bridge/client.d.ts +0 -151
  25. package/dist/bridge/client.js +0 -434
  26. package/dist/bridge/const.d.ts +0 -23
  27. package/dist/bridge/const.js +0 -47
  28. package/dist/bridge/index.d.ts +0 -4
  29. package/dist/bridge/index.js +0 -23
  30. package/dist/bridge/types.d.ts +0 -120
  31. package/dist/bridge/types.js +0 -18
  32. package/dist/bridge/utils.d.ts +0 -64
  33. package/dist/bridge/utils.js +0 -131
  34. package/dist/gen/common.d.ts +0 -68
  35. package/dist/gen/common.js +0 -215
  36. package/dist/gen/nord.d.ts +0 -882
  37. package/dist/gen/nord.js +0 -6520
  38. package/dist/idl/bridge.d.ts +0 -569
  39. package/dist/idl/bridge.js +0 -8
  40. package/dist/idl/bridge.json +0 -1506
  41. package/dist/idl/index.d.ts +0 -607
  42. package/dist/idl/index.js +0 -8
  43. package/dist/nord/api/actions.d.ts +0 -126
  44. package/dist/nord/api/actions.js +0 -397
  45. package/dist/nord/api/core.d.ts +0 -16
  46. package/dist/nord/api/core.js +0 -81
  47. package/dist/nord/api/market.d.ts +0 -36
  48. package/dist/nord/api/market.js +0 -96
  49. package/dist/nord/api/metrics.d.ts +0 -67
  50. package/dist/nord/api/metrics.js +0 -229
  51. package/dist/nord/api/queries.d.ts +0 -46
  52. package/dist/nord/api/queries.js +0 -109
  53. package/dist/nord/api/triggers.d.ts +0 -7
  54. package/dist/nord/api/triggers.js +0 -38
  55. package/dist/nord/client/Nord.d.ts +0 -396
  56. package/dist/nord/client/Nord.js +0 -747
  57. package/dist/nord/client/NordAdmin.d.ts +0 -259
  58. package/dist/nord/client/NordAdmin.js +0 -395
  59. package/dist/nord/client/NordClient.d.ts +0 -33
  60. package/dist/nord/client/NordClient.js +0 -45
  61. package/dist/nord/client/NordUser.d.ts +0 -362
  62. package/dist/nord/client/NordUser.js +0 -781
  63. package/dist/nord/index.d.ts +0 -11
  64. package/dist/nord/index.js +0 -36
  65. package/dist/nord/models/Subscriber.d.ts +0 -37
  66. package/dist/nord/models/Subscriber.js +0 -25
  67. package/dist/nord/utils/NordError.d.ts +0 -35
  68. package/dist/nord/utils/NordError.js +0 -49
  69. package/src/actions.ts +0 -333
  70. package/src/client/Nord.ts +0 -934
  71. package/src/client/NordAdmin.ts +0 -484
  72. package/src/client/NordUser.ts +0 -1122
  73. package/src/const.ts +0 -34
  74. package/src/error.ts +0 -76
  75. package/src/gen/.gitkeep +0 -0
  76. package/src/gen/nord_pb.ts +0 -5053
  77. package/src/gen/openapi.ts +0 -2904
  78. package/src/index.ts +0 -11
  79. package/src/types.ts +0 -327
  80. package/src/utils.ts +0 -266
  81. package/src/websocket/NordWebSocketClient.ts +0 -316
  82. package/src/websocket/Subscriber.ts +0 -56
  83. package/src/websocket/events.ts +0 -31
  84. package/src/websocket/index.ts +0 -105
@@ -1,316 +0,0 @@
1
- import { EventEmitter } from "events";
2
- import WebSocket from "ws";
3
- import {
4
- WebSocketAccountUpdate,
5
- WebSocketDeltaUpdate,
6
- WebSocketMessage,
7
- WebSocketTradeUpdate,
8
- } from "../types";
9
- import { NordWebSocketClientEvents } from "./events";
10
-
11
- // Define a type that works for both Node.js ws and browser WebSocket
12
- type BrowserWebSocket = {
13
- OPEN: number;
14
- CONNECTING: number;
15
- CLOSING: number;
16
- CLOSED: number;
17
- readyState: number;
18
- send: (data: string) => void;
19
- close: () => void;
20
- onopen: ((this: any, ev: any) => any) | null;
21
- onmessage: ((this: any, ev: { data: any }) => any) | null;
22
- onclose: ((this: any, ev: any) => any) | null;
23
- onerror: ((this: any, ev: any) => any) | null;
24
- };
25
-
26
- type WebSocketInstance = WebSocket | BrowserWebSocket;
27
-
28
- const VALID_STREAM_TYPES = ["trades", "delta", "account"];
29
-
30
- /**
31
- * WebSocket client for Nord exchange
32
- *
33
- * This client connects to one of the specific Nord WebSocket endpoints:
34
- *
35
- * Each endpoint handles a specific type of data and subscriptions must match
36
- * the endpoint type (e.g., only 'trades@BTCUSDC' subscriptions are valid on
37
- * the /ws/trades endpoint).
38
- */
39
- export class NordWebSocketClient
40
- extends EventEmitter
41
- implements NordWebSocketClientEvents
42
- {
43
- private ws: WebSocketInstance | null = null;
44
- private url: string;
45
- private reconnectAttempts: number = 0;
46
- private maxReconnectAttempts: number = 5;
47
- private reconnectDelay: number = 1000;
48
- private pingInterval: NodeJS.Timeout | null = null;
49
- private pingTimeout: NodeJS.Timeout | null = null;
50
- private isBrowser: boolean;
51
-
52
- /**
53
- * Create a new NordWebSocketClient
54
- * @param url WebSocket server URL
55
- */
56
- constructor(url: string) {
57
- super();
58
- this.url = url;
59
- // Check if we're in a browser environment
60
- // The most reliable way is to check for Node.js process
61
- this.isBrowser =
62
- typeof process === "undefined" ||
63
- !process.versions ||
64
- !process.versions.node;
65
- }
66
-
67
- /**
68
- * Validate stream format
69
- * @param stream Stream identifier to validate
70
- * @throws Error if stream format is invalid
71
- */
72
- private validateStream(stream: string): void {
73
- const [type, params] = stream.split("@");
74
-
75
- if (!type || !params) {
76
- throw new Error(
77
- `Invalid stream format: ${stream}. Expected format: <type>@<params>`,
78
- );
79
- }
80
-
81
- // Extract the endpoint from the URL
82
- const urlPath = new URL(this.url).pathname;
83
- const endpoint = urlPath.split("/").pop();
84
-
85
- // Ensure the stream type matches the endpoint we're connected to
86
- if (endpoint && type !== endpoint) {
87
- throw new Error(
88
- `Stream type '${type}' doesn't match the connected endpoint '${endpoint}'`,
89
- );
90
- }
91
-
92
- if (!VALID_STREAM_TYPES.includes(type)) {
93
- throw new Error(
94
- `Invalid stream type: ${type}. Valid types are: ${VALID_STREAM_TYPES.join(", ")}`,
95
- );
96
- }
97
-
98
- if (type === "account" && !/^\d+$/.test(params)) {
99
- throw new Error(
100
- `Invalid account ID in stream: ${params}. Expected numeric ID`,
101
- );
102
- }
103
- }
104
-
105
- /**
106
- * Setup WebSocket ping/pong heartbeat
107
- */
108
- private setupHeartbeat(): void {
109
- if (this.pingInterval) {
110
- clearInterval(this.pingInterval);
111
- }
112
- if (this.pingTimeout) {
113
- clearTimeout(this.pingTimeout);
114
- }
115
-
116
- // In browser, we rely on the browser's WebSocket implementation to handle ping/pong
117
- if (this.isBrowser) {
118
- return;
119
- }
120
-
121
- this.pingInterval = setInterval(() => {
122
- if (this.ws && !this.isBrowser) {
123
- // Only use ping() method in Node.js environment
124
- (this.ws as WebSocket).ping();
125
-
126
- // Set timeout for pong response
127
- this.pingTimeout = setTimeout(() => {
128
- this.emit("error", new Error("WebSocket ping timeout"));
129
- this.close();
130
- this.reconnect();
131
- }, 5000); // 5 second timeout
132
- }
133
- }, 30000); // Send ping every 30 seconds
134
- }
135
-
136
- /**
137
- * Get the appropriate WebSocket class based on environment
138
- */
139
- private getWebSocketClass(): any {
140
- if (this.isBrowser) {
141
- // In browser environments
142
- if (typeof globalThis !== "undefined" && globalThis.WebSocket) {
143
- return globalThis.WebSocket;
144
- }
145
- throw new Error("WebSocket is not available in this environment");
146
- } else {
147
- // In Node.js
148
- return WebSocket;
149
- }
150
- }
151
-
152
- /**
153
- * Connect to the Nord WebSocket server
154
- */
155
- public connect(): void {
156
- if (this.ws) {
157
- return;
158
- }
159
-
160
- try {
161
- const WebSocketClass = this.getWebSocketClass();
162
-
163
- if (this.isBrowser) {
164
- // Browser WebSocket setup
165
- this.ws = new WebSocketClass(this.url) as BrowserWebSocket;
166
-
167
- (this.ws as BrowserWebSocket).onopen = () => {
168
- this.emit("connected");
169
- this.reconnectAttempts = 0;
170
- this.reconnectDelay = 1000;
171
- };
172
-
173
- (this.ws as BrowserWebSocket).onmessage = (event: { data: any }) => {
174
- try {
175
- const message = JSON.parse(
176
- event.data as string,
177
- ) as WebSocketMessage;
178
- this.handleMessage(message);
179
- } catch (error) {
180
- this.emit(
181
- "error",
182
- new Error(
183
- `Failed to parse message: ${error instanceof Error ? error.message : String(error)}`,
184
- ),
185
- );
186
- }
187
- };
188
-
189
- (this.ws as BrowserWebSocket).onclose = (_event: any) => {
190
- this.emit("disconnected");
191
- this.reconnect();
192
- };
193
-
194
- (this.ws as BrowserWebSocket).onerror = (event: any) => {
195
- const errorMsg = `WebSocket error: ${event && event.type ? event.type : "unknown"}`;
196
- this.emit("error", new Error(errorMsg));
197
- };
198
- } else {
199
- // Node.js WebSocket setup
200
- const nodeWs = new WebSocketClass(this.url) as WebSocket;
201
- this.ws = nodeWs;
202
-
203
- nodeWs.on("open", () => {
204
- this.emit("connected");
205
- this.reconnectAttempts = 0;
206
- this.reconnectDelay = 1000;
207
- this.setupHeartbeat();
208
- });
209
-
210
- nodeWs.on("message", (data: WebSocket.Data) => {
211
- try {
212
- const message = JSON.parse(data.toString()) as WebSocketMessage;
213
- this.handleMessage(message);
214
- } catch (error) {
215
- this.emit(
216
- "error",
217
- new Error(
218
- `Failed to parse message: ${error instanceof Error ? error.message : String(error)}`,
219
- ),
220
- );
221
- }
222
- });
223
-
224
- nodeWs.on("close", (_code: number, _reason: string) => {
225
- this.emit("disconnected");
226
- if (this.pingInterval) {
227
- clearInterval(this.pingInterval);
228
- }
229
- if (this.pingTimeout) {
230
- clearTimeout(this.pingTimeout);
231
- }
232
- this.reconnect();
233
- });
234
-
235
- nodeWs.on("error", (error: Error) => {
236
- this.emit("error", error);
237
- });
238
-
239
- nodeWs.on("pong", () => {
240
- if (this.pingTimeout) {
241
- clearTimeout(this.pingTimeout);
242
- }
243
- });
244
- }
245
- } catch (error) {
246
- const errorMsg = `Failed to initialize WebSocket: ${error instanceof Error ? error.message : String(error)}`;
247
- this.emit("error", new Error(errorMsg));
248
- }
249
- }
250
-
251
- /**
252
- * Close the WebSocket connection
253
- */
254
- public close(): void {
255
- if (this.ws) {
256
- if (this.isBrowser) {
257
- (this.ws as BrowserWebSocket).close();
258
- } else {
259
- (this.ws as WebSocket).close();
260
- }
261
- this.ws = null;
262
- }
263
- if (this.pingInterval) {
264
- clearInterval(this.pingInterval);
265
- this.pingInterval = null;
266
- }
267
- if (this.pingTimeout) {
268
- clearTimeout(this.pingTimeout);
269
- this.pingTimeout = null;
270
- }
271
- }
272
-
273
- /**
274
- * Handle incoming WebSocket messages
275
- * @param message WebSocket message
276
- */
277
- private handleMessage(message: WebSocketMessage): void {
278
- if (!message || typeof message !== "object") {
279
- this.emit("error", new Error(`Unexpected message type: ${message}`));
280
- return;
281
- }
282
-
283
- const hasOwn = (k: string) =>
284
- Object.prototype.hasOwnProperty.call(message, k);
285
- if (hasOwn("trades")) {
286
- this.emit("trades", message as WebSocketTradeUpdate);
287
- return;
288
- }
289
- if (hasOwn("delta")) {
290
- this.emit("delta", message as WebSocketDeltaUpdate);
291
- return;
292
- }
293
- if (hasOwn("account")) {
294
- this.emit("account", message as WebSocketAccountUpdate);
295
- return;
296
- }
297
-
298
- this.emit("error", new Error(`Unexpected message type: ${message}`));
299
- }
300
-
301
- /**
302
- * Attempt to reconnect to the WebSocket server
303
- */
304
- private reconnect(): void {
305
- if (this.reconnectAttempts >= this.maxReconnectAttempts) {
306
- this.emit("error", new Error("Max reconnection attempts reached"));
307
- return;
308
- }
309
-
310
- setTimeout(() => {
311
- this.reconnectAttempts++;
312
- this.reconnectDelay *= 2; // Exponential backoff
313
- this.connect();
314
- }, this.reconnectDelay);
315
- }
316
- }
@@ -1,56 +0,0 @@
1
- import { EventEmitter } from "events";
2
- import {
3
- Account,
4
- DeltaEvent,
5
- OrderbookResponse,
6
- SubscriberConfig,
7
- StreamTrade,
8
- Trades,
9
- } from "../types";
10
- import { MAX_BUFFER_LEN } from "../utils";
11
-
12
- /**
13
- * Subscriber class for handling WebSocket subscriptions
14
- */
15
- export class Subscriber {
16
- streamURL: string;
17
- buffer: (DeltaEvent | Trades | Account)[];
18
- maxBufferLen: number;
19
-
20
- /**
21
- * Create a new Subscriber instance
22
- * @param config Subscriber configuration
23
- */
24
- constructor(config: SubscriberConfig) {
25
- this.streamURL = config.streamURL;
26
- this.buffer = [];
27
- this.maxBufferLen = config.maxBufferLen ?? MAX_BUFFER_LEN;
28
- }
29
-
30
- /**
31
- * Subscribe to WebSocket events
32
- */
33
- subscribe(): void {
34
- // TODO: Implement subscription logic
35
- }
36
- }
37
-
38
- /**
39
- * Interface for orderbook subscription
40
- */
41
- export interface OrderbookSubscription extends EventEmitter {
42
- on(event: "message", listener: (data: OrderbookResponse) => void): this;
43
- on(event: "error", listener: (error: Error) => void): this;
44
- close(): void;
45
- removeAllListeners(event?: string): this;
46
- }
47
-
48
- /**
49
- * Interface for trade subscription
50
- */
51
- export interface TradeSubscription extends EventEmitter {
52
- on(event: "message", listener: (data: StreamTrade[]) => void): this;
53
- on(event: "error", listener: (error: Error) => void): this;
54
- close(): void;
55
- removeAllListeners(event?: string): this;
56
- }
@@ -1,31 +0,0 @@
1
- import {
2
- WebSocketTradeUpdate,
3
- WebSocketDeltaUpdate,
4
- WebSocketAccountUpdate,
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
- account: (update: WebSocketAccountUpdate) => 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
- }
@@ -1,105 +0,0 @@
1
- import { NordWebSocketClient } from "./NordWebSocketClient";
2
- import { NordError } from "../error";
3
- import type { SubscriptionPattern } from "../types";
4
- import type { NordWebSocketEvents, NordWebSocketClientEvents } from "./events";
5
- import { Subscriber } from "./Subscriber";
6
-
7
- export {
8
- NordWebSocketClient,
9
- NordWebSocketEvents,
10
- NordWebSocketClientEvents,
11
- Subscriber,
12
- };
13
-
14
- /**
15
- * Initialize a WebSocket client for Nord
16
- *
17
- * Connects to the Nord WebSocket endpoint with support for multiple subscription types:
18
- * - trades@SYMBOL - For trade updates
19
- * - deltas@SYMBOL - For orderbook delta updates
20
- * - account@ACCOUNT_ID - For user-specific updates
21
- *
22
- * @param webServerUrl - Base URL for the Nord web server
23
- * @param subscriptions - Array of subscriptions (e.g., ["trades@BTCUSDC", "deltas@BTCUSDC", "account@42"])
24
- * @returns WebSocket client
25
- * @throws {NordError} If initialization fails or invalid subscription is provided
26
- */
27
- export function initWebSocketClient(
28
- webServerUrl: string,
29
- subscriptions?: SubscriptionPattern[] | "trades" | "delta" | "account",
30
- ): NordWebSocketClient {
31
- try {
32
- // Determine URL and subscriptions based on parameters
33
- let wsUrl = webServerUrl.replace(/^http/, "ws") + `/ws`;
34
-
35
- // Validate subscriptions parameter
36
- if (typeof subscriptions === "string") {
37
- // Legacy mode - handle endpoint string
38
- if (
39
- subscriptions === "trades" ||
40
- subscriptions === "delta" ||
41
- subscriptions === "account"
42
- ) {
43
- wsUrl += `/${subscriptions}`;
44
- } else {
45
- throw new NordError(
46
- `Invalid endpoint: ${subscriptions}. Must be "trades", "deltas", or "account".`,
47
- );
48
- }
49
- } else if (Array.isArray(subscriptions) && subscriptions.length > 0) {
50
- // New mode - validate and combine subscriptions in URL
51
- subscriptions.forEach(validateSubscription);
52
- wsUrl += `/${subscriptions.join("&")}`;
53
- } else {
54
- // Default to trades endpoint if no subscriptions specified
55
- wsUrl += `/trades`;
56
- }
57
-
58
- console.log(`Initializing WebSocket client with URL: ${wsUrl}`);
59
-
60
- // Create and connect the WebSocket client
61
- const ws = new NordWebSocketClient(wsUrl);
62
-
63
- // Add error handler
64
- ws.on("error", (error) => {
65
- console.error("Nord WebSocket error:", error);
66
- });
67
-
68
- // Add connected handler for debugging
69
- ws.on("connected", () => {
70
- console.log("Nord WebSocket connected successfully");
71
- });
72
-
73
- // Connect the WebSocket
74
- ws.connect();
75
- return ws;
76
- } catch (error) {
77
- console.error("Failed to initialize WebSocket client:", error);
78
- throw new NordError("Failed to initialize WebSocket client", {
79
- cause: error,
80
- });
81
- }
82
- }
83
-
84
- /**
85
- * Validates a subscription string follows the correct format
86
- *
87
- * @param subscription - The subscription to validate
88
- * @throws {NordError} If the subscription format is invalid
89
- */
90
- function validateSubscription(subscription: string): void {
91
- const [type, param] = subscription.split("@");
92
-
93
- if (!type || !param || !["trades", "deltas", "account"].includes(type)) {
94
- throw new NordError(
95
- `Invalid subscription format: ${subscription}. Expected format: "trades@SYMBOL", "deltas@SYMBOL", or "account@ID"`,
96
- );
97
- }
98
-
99
- // Additional validation for account subscriptions
100
- if (type === "account" && isNaN(Number(param))) {
101
- throw new NordError(
102
- `Invalid account ID in subscription: ${subscription}. Account ID must be a number.`,
103
- );
104
- }
105
- }