@n1xyz/nord-ts 0.0.19 → 0.0.21

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 (52) hide show
  1. package/dist/const.d.ts +8 -0
  2. package/dist/const.js +30 -0
  3. package/dist/gen/nord.d.ts +882 -0
  4. package/dist/gen/nord.js +6520 -0
  5. package/dist/gen/openapi.d.ts +2244 -0
  6. package/dist/gen/openapi.js +6 -0
  7. package/dist/index.d.ts +5 -0
  8. package/dist/index.js +21 -0
  9. package/dist/nord/api/actions.d.ts +135 -0
  10. package/dist/nord/api/actions.js +313 -0
  11. package/dist/nord/api/core.d.ts +16 -0
  12. package/dist/nord/api/core.js +81 -0
  13. package/dist/nord/api/metrics.d.ts +67 -0
  14. package/dist/nord/api/metrics.js +229 -0
  15. package/dist/nord/client/Nord.d.ts +282 -0
  16. package/dist/nord/client/Nord.js +528 -0
  17. package/dist/nord/client/NordUser.d.ts +340 -0
  18. package/dist/nord/client/NordUser.js +652 -0
  19. package/dist/nord/index.d.ts +7 -0
  20. package/dist/nord/index.js +31 -0
  21. package/dist/nord/models/Subscriber.d.ts +37 -0
  22. package/dist/nord/models/Subscriber.js +25 -0
  23. package/dist/nord/utils/NordError.d.ts +35 -0
  24. package/dist/nord/utils/NordError.js +49 -0
  25. package/dist/types.d.ts +251 -0
  26. package/dist/types.js +101 -0
  27. package/dist/utils.d.ts +98 -0
  28. package/dist/utils.js +237 -0
  29. package/dist/websocket/NordWebSocketClient.d.ts +57 -0
  30. package/dist/websocket/NordWebSocketClient.js +251 -0
  31. package/dist/websocket/events.d.ts +19 -0
  32. package/dist/websocket/events.js +2 -0
  33. package/dist/websocket/index.d.ts +2 -0
  34. package/dist/websocket/index.js +5 -0
  35. package/package.json +8 -2
  36. package/src/gen/.gitkeep +0 -0
  37. package/src/gen/nord.ts +7593 -0
  38. package/src/gen/openapi.ts +2245 -0
  39. package/src/nord/api/core.ts +1 -16
  40. package/src/nord/client/Nord.ts +7 -11
  41. package/src/types.ts +0 -11
  42. package/src/websocket/NordWebSocketClient.ts +0 -113
  43. package/.claude/settings.local.json +0 -11
  44. package/.local/qa.ts +0 -77
  45. package/.local/test-atomic.ts +0 -112
  46. package/.prettierignore +0 -2
  47. package/check.sh +0 -4
  48. package/default.nix +0 -47
  49. package/eslint.config.mjs +0 -66
  50. package/tests/utils.spec.ts +0 -121
  51. package/tsconfig.eslint.json +0 -12
  52. package/tsconfig.json +0 -24
package/dist/utils.js ADDED
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.toScaledU128 = exports.toScaledU64 = exports.MAX_BUFFER_LEN = exports.ZERO_DECIMAL = exports.SESSION_TTL = void 0;
7
+ exports.panic = panic;
8
+ exports.isRfc3339 = isRfc3339;
9
+ exports.assert = assert;
10
+ exports.optExpect = optExpect;
11
+ exports.checkedFetch = checkedFetch;
12
+ exports.signAction = signAction;
13
+ exports.makeWalletSignFn = makeWalletSignFn;
14
+ exports.encodeLengthDelimited = encodeLengthDelimited;
15
+ exports.decodeLengthDelimited = decodeLengthDelimited;
16
+ exports.checkPubKeyLength = checkPubKeyLength;
17
+ exports.findMarket = findMarket;
18
+ exports.findToken = findToken;
19
+ exports.keypairFromPrivateKey = keypairFromPrivateKey;
20
+ const decimal_js_1 = require("decimal.js");
21
+ const ed25519_1 = require("@noble/curves/ed25519");
22
+ const bls12_381_1 = require("@noble/curves/bls12-381");
23
+ const secp256k1_1 = require("@noble/curves/secp256k1");
24
+ const sha256_1 = require("@noble/hashes/sha256");
25
+ const types_1 = require("./types");
26
+ const wire_1 = require("@bufbuild/protobuf/wire");
27
+ const ethers_1 = require("ethers");
28
+ const node_fetch_1 = __importDefault(require("node-fetch"));
29
+ const web3_js_1 = require("@solana/web3.js");
30
+ const bs58_1 = __importDefault(require("bs58"));
31
+ exports.SESSION_TTL = 60n * 60n * 24n * 30n;
32
+ exports.ZERO_DECIMAL = new decimal_js_1.Decimal(0);
33
+ exports.MAX_BUFFER_LEN = 10000;
34
+ const MAX_PAYLOAD_SIZE = 100 * 1024; // 100 kB
35
+ function panic(message) {
36
+ throw new Error(message);
37
+ }
38
+ function isRfc3339(s) {
39
+ const REGEX = /^((?:(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}(?:\.\d+)?))(Z|[\+-]\d{2}:\d{2})?)$/;
40
+ return REGEX.test(s);
41
+ }
42
+ function assert(predicate, message) {
43
+ if (!predicate)
44
+ panic(message ?? "Assertion violated");
45
+ }
46
+ /**
47
+ * Extracts value out of optional if it's defined, or throws error if it's not
48
+ * @param value Optional value to unwrap
49
+ * @param message Error message
50
+ * @returns Unwrapped value
51
+ */
52
+ function optExpect(value, message) {
53
+ if (value === undefined)
54
+ throw new Error(message);
55
+ return value;
56
+ }
57
+ /** Behaves same as `node-fetch/fetch` but throws if response is a failure
58
+ *
59
+ * @param url Request HTTP URL
60
+ * @param init Request parameters
61
+ * @returns Raw response if fetch succeeded
62
+ * @throws If response wasn't Ok
63
+ */
64
+ async function checkedFetch(url, init) {
65
+ const resp = await (0, node_fetch_1.default)(url, init);
66
+ assert(resp.ok, `Request failed with ${resp.status}: ${resp.statusText}`);
67
+ return resp;
68
+ }
69
+ /**
70
+ * Signs an action using the specified secret key and key type.
71
+ * @param action - The action data to be signed.
72
+ * @param sk - Secret key used for signing the action.
73
+ * @param keyType - Type of the key used for signing.
74
+ * @returns A new Uint8Array containing the action followed by its signature.
75
+ */
76
+ function signAction(action, sk, keyType) {
77
+ let sig;
78
+ if (keyType === types_1.KeyType.Ed25519) {
79
+ sig = ed25519_1.ed25519.sign(action, sk);
80
+ }
81
+ else if (keyType === types_1.KeyType.Bls12_381) {
82
+ sig = bls12_381_1.bls12_381.sign(action, sk);
83
+ }
84
+ else if (keyType === types_1.KeyType.Secp256k1) {
85
+ sig = secp256k1_1.secp256k1.sign((0, sha256_1.sha256)(action), sk).toCompactRawBytes();
86
+ }
87
+ else {
88
+ throw new Error("Invalid key type");
89
+ }
90
+ return new Uint8Array([...action, ...sig]);
91
+ }
92
+ /**
93
+ * Constructs wallet signing function, usable with `NordUser` type
94
+ *
95
+ * @param walletKey Either raw signing key as bytes array or hex string prefixed with `"0x"`
96
+ * @returns Async function which accepts arbitrary message, generates its digets,
97
+ * then signs it with provided user wallet key and returns signature
98
+ * as hex string prefixed with `"0x"`
99
+ */
100
+ function makeWalletSignFn(walletKey) {
101
+ const signingKey = new ethers_1.ethers.SigningKey(walletKey);
102
+ return async (message) => signingKey.sign(ethers_1.ethers.hashMessage(message)).serialized;
103
+ }
104
+ function makeToScaledBigUint(params) {
105
+ const Dec = decimal_js_1.Decimal.clone({
106
+ precision: params.precision,
107
+ toExpPos: params.exponent,
108
+ toExpNeg: -params.exponent,
109
+ });
110
+ const Ten = new Dec(10);
111
+ const Max = new Dec(((1n << BigInt(params.bits)) - 1n).toString());
112
+ return (x, decimals) => {
113
+ const dec = new Dec(x);
114
+ if (dec.isZero()) {
115
+ return 0n;
116
+ }
117
+ if (dec.isNeg()) {
118
+ throw new Error(`Number is negative`);
119
+ }
120
+ const scaled = Ten.pow(decimals).mul(dec).truncated();
121
+ if (scaled.isZero()) {
122
+ throw new Error(`Precision loss when converting ${dec} to scaled integer`);
123
+ }
124
+ if (scaled.greaterThan(Max)) {
125
+ throw new Error(`Integer is out of range: ${scaled} exceeds limit ${Max}`);
126
+ }
127
+ return BigInt(scaled.toString());
128
+ };
129
+ }
130
+ /**
131
+ * Converts decimal value into rescaled 64-bit unsigned integer
132
+ * by scaling it up by specified number of decimal digits.
133
+ *
134
+ * Ensures that number won't accidentally become zero
135
+ * or exceed U64's value range
136
+ *
137
+ * @param x Decimal value to rescale
138
+ * @param decimals Number of decimal digits
139
+ * @returns Rescaled unsigned integer
140
+ */
141
+ exports.toScaledU64 = makeToScaledBigUint({
142
+ bits: 64,
143
+ precision: 20,
144
+ exponent: 28,
145
+ });
146
+ /**
147
+ * Converts decimal value into rescaled 128-bit unsigned integer
148
+ * by scaling it up by specified number of decimal digits.
149
+ *
150
+ * Ensures that number won't accidentally become zero
151
+ * or exceed U128's value range
152
+ *
153
+ * @param x Decimal value to rescale
154
+ * @param decimals Number of decimal digits
155
+ * @returns Rescaled unsigned integer
156
+ */
157
+ exports.toScaledU128 = makeToScaledBigUint({
158
+ bits: 128,
159
+ precision: 40,
160
+ exponent: 56,
161
+ });
162
+ /**
163
+ * Encodes any protobuf message into a length-delimited format,
164
+ * i.e. prefixed with its length encoded as varint
165
+ * @param message message object
166
+ * @param coder associated coder object which implements `MessageFns` interface
167
+ * @returns Encoded message as Uint8Array, prefixed with its length
168
+ */
169
+ function encodeLengthDelimited(message, coder) {
170
+ const encoded = coder.encode(message).finish();
171
+ if (encoded.byteLength > MAX_PAYLOAD_SIZE) {
172
+ throw new Error(`Encoded message size (${encoded.byteLength} bytes) is greater than max payload size (${MAX_PAYLOAD_SIZE} bytes).`);
173
+ }
174
+ const encodedLength = new wire_1.BinaryWriter().uint32(encoded.byteLength).finish();
175
+ return new Uint8Array([...encodedLength, ...encoded]);
176
+ }
177
+ /**
178
+ * Decodes any protobuf message from a length-delimited format,
179
+ * i.e. prefixed with its length encoded as varint
180
+ *
181
+ * NB: Please note that due to limitations of Typescript type inference
182
+ * it requires to specify variable type explicitly:
183
+ *
184
+ * ```
185
+ * const foo: proto.Bar = decodeLengthDelimited(bytes, proto.Bar);
186
+ * ```
187
+ *
188
+ * @param bytes Byte array with encoded message
189
+ * @param coder associated coder object which implements `MessageFns` interface
190
+ * @returns Decoded Action as Uint8Array.
191
+ */
192
+ function decodeLengthDelimited(bytes, coder) {
193
+ const lengthReader = new wire_1.BinaryReader(bytes);
194
+ const msgLength = lengthReader.uint32();
195
+ const startsAt = lengthReader.pos;
196
+ if (msgLength > MAX_PAYLOAD_SIZE) {
197
+ throw new Error(`Encoded message size (${msgLength} bytes) is greater than max payload size (${MAX_PAYLOAD_SIZE} bytes).`);
198
+ }
199
+ if (startsAt + msgLength > bytes.byteLength) {
200
+ throw new Error(`Encoded message size (${msgLength} bytes) is greater than remaining buffer size (${bytes.byteLength - startsAt} bytes).`);
201
+ }
202
+ return coder.decode(bytes.slice(startsAt, startsAt + msgLength));
203
+ }
204
+ function checkPubKeyLength(keyType, len) {
205
+ if (keyType === types_1.KeyType.Bls12_381) {
206
+ throw new Error("Cannot create a user using Bls12_381, use Ed25119 or Secp256k1 instead.");
207
+ }
208
+ if (len !== 32 && keyType === types_1.KeyType.Ed25519) {
209
+ throw new Error("Ed25519 pubkeys must be 32 length.");
210
+ }
211
+ if (len !== 33 && keyType === types_1.KeyType.Secp256k1) {
212
+ throw new Error("Secp256k1 pubkeys must be 33 length.");
213
+ }
214
+ }
215
+ function findMarket(markets, marketId) {
216
+ if (marketId < 0 || markets.length - 1 < marketId) {
217
+ throw new Error(`The market with marketId=${marketId} not found`);
218
+ }
219
+ return markets[marketId];
220
+ }
221
+ function findToken(tokens, tokenId) {
222
+ if (tokenId < 0 || tokens.length - 1 < tokenId) {
223
+ throw new Error(`The token with tokenId=${tokenId} not found`);
224
+ }
225
+ return tokens[tokenId];
226
+ }
227
+ function keypairFromPrivateKey(privateKey) {
228
+ if (typeof privateKey === "string") {
229
+ if (!privateKey.startsWith("0x")) {
230
+ return web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(privateKey));
231
+ }
232
+ const hex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
233
+ const bytes = new Uint8Array(hex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
234
+ return web3_js_1.Keypair.fromSecretKey(bytes);
235
+ }
236
+ return web3_js_1.Keypair.fromSecretKey(privateKey);
237
+ }
@@ -0,0 +1,57 @@
1
+ import { EventEmitter } from "events";
2
+ import { NordWebSocketClientEvents } from "./events";
3
+ /**
4
+ * WebSocket client for Nord exchange
5
+ *
6
+ * This client connects to one of the specific Nord WebSocket endpoints:
7
+ *
8
+ * Each endpoint handles a specific type of data and subscriptions must match
9
+ * the endpoint type (e.g., only 'trades@BTCUSDC' subscriptions are valid on
10
+ * the /ws/trades endpoint).
11
+ */
12
+ export declare class NordWebSocketClient extends EventEmitter implements NordWebSocketClientEvents {
13
+ private ws;
14
+ private url;
15
+ private reconnectAttempts;
16
+ private maxReconnectAttempts;
17
+ private reconnectDelay;
18
+ private pingInterval;
19
+ private pingTimeout;
20
+ private isBrowser;
21
+ /**
22
+ * Create a new NordWebSocketClient
23
+ * @param url WebSocket server URL
24
+ */
25
+ constructor(url: string);
26
+ /**
27
+ * Validate stream format
28
+ * @param stream Stream identifier to validate
29
+ * @throws Error if stream format is invalid
30
+ */
31
+ private validateStream;
32
+ /**
33
+ * Setup WebSocket ping/pong heartbeat
34
+ */
35
+ private setupHeartbeat;
36
+ /**
37
+ * Get the appropriate WebSocket class based on environment
38
+ */
39
+ private getWebSocketClass;
40
+ /**
41
+ * Connect to the Nord WebSocket server
42
+ */
43
+ connect(): void;
44
+ /**
45
+ * Close the WebSocket connection
46
+ */
47
+ close(): void;
48
+ /**
49
+ * Handle incoming WebSocket messages
50
+ * @param message WebSocket message
51
+ */
52
+ private handleMessage;
53
+ /**
54
+ * Attempt to reconnect to the WebSocket server
55
+ */
56
+ private reconnect;
57
+ }
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NordWebSocketClient = void 0;
7
+ const events_1 = require("events");
8
+ const ws_1 = __importDefault(require("ws"));
9
+ const VALID_STREAM_TYPES = ["trades", "delta", "account"];
10
+ // Constants for WebSocket readyState
11
+ const WS_OPEN = 1;
12
+ /**
13
+ * WebSocket client for Nord exchange
14
+ *
15
+ * This client connects to one of the specific Nord WebSocket endpoints:
16
+ *
17
+ * Each endpoint handles a specific type of data and subscriptions must match
18
+ * the endpoint type (e.g., only 'trades@BTCUSDC' subscriptions are valid on
19
+ * the /ws/trades endpoint).
20
+ */
21
+ class NordWebSocketClient extends events_1.EventEmitter {
22
+ /**
23
+ * Create a new NordWebSocketClient
24
+ * @param url WebSocket server URL
25
+ */
26
+ constructor(url) {
27
+ super();
28
+ this.ws = null;
29
+ this.reconnectAttempts = 0;
30
+ this.maxReconnectAttempts = 5;
31
+ this.reconnectDelay = 1000;
32
+ this.pingInterval = null;
33
+ this.pingTimeout = null;
34
+ this.url = url;
35
+ // Check if we're in a browser environment
36
+ // The most reliable way is to check for Node.js process
37
+ this.isBrowser =
38
+ typeof process === "undefined" ||
39
+ !process.versions ||
40
+ !process.versions.node;
41
+ }
42
+ /**
43
+ * Validate stream format
44
+ * @param stream Stream identifier to validate
45
+ * @throws Error if stream format is invalid
46
+ */
47
+ validateStream(stream) {
48
+ const [type, params] = stream.split("@");
49
+ if (!type || !params) {
50
+ throw new Error(`Invalid stream format: ${stream}. Expected format: <type>@<params>`);
51
+ }
52
+ // Extract the endpoint from the URL
53
+ const urlPath = new URL(this.url).pathname;
54
+ const endpoint = urlPath.split("/").pop();
55
+ // Ensure the stream type matches the endpoint we're connected to
56
+ if (endpoint && type !== endpoint) {
57
+ throw new Error(`Stream type '${type}' doesn't match the connected endpoint '${endpoint}'`);
58
+ }
59
+ if (!VALID_STREAM_TYPES.includes(type)) {
60
+ throw new Error(`Invalid stream type: ${type}. Valid types are: ${VALID_STREAM_TYPES.join(", ")}`);
61
+ }
62
+ if (type === "account" && !/^\d+$/.test(params)) {
63
+ throw new Error(`Invalid account ID in stream: ${params}. Expected numeric ID`);
64
+ }
65
+ }
66
+ /**
67
+ * Setup WebSocket ping/pong heartbeat
68
+ */
69
+ setupHeartbeat() {
70
+ if (this.pingInterval) {
71
+ clearInterval(this.pingInterval);
72
+ }
73
+ if (this.pingTimeout) {
74
+ clearTimeout(this.pingTimeout);
75
+ }
76
+ // In browser, we rely on the browser's WebSocket implementation to handle ping/pong
77
+ if (this.isBrowser) {
78
+ return;
79
+ }
80
+ this.pingInterval = setInterval(() => {
81
+ if (this.ws && !this.isBrowser) {
82
+ // Only use ping() method in Node.js environment
83
+ this.ws.ping();
84
+ // Set timeout for pong response
85
+ this.pingTimeout = setTimeout(() => {
86
+ this.emit("error", new Error("WebSocket ping timeout"));
87
+ this.close();
88
+ this.reconnect();
89
+ }, 5000); // 5 second timeout
90
+ }
91
+ }, 30000); // Send ping every 30 seconds
92
+ }
93
+ /**
94
+ * Get the appropriate WebSocket class based on environment
95
+ */
96
+ getWebSocketClass() {
97
+ if (this.isBrowser) {
98
+ // In browser environments
99
+ if (typeof globalThis !== "undefined" && globalThis.WebSocket) {
100
+ return globalThis.WebSocket;
101
+ }
102
+ throw new Error("WebSocket is not available in this environment");
103
+ }
104
+ else {
105
+ // In Node.js
106
+ return ws_1.default;
107
+ }
108
+ }
109
+ /**
110
+ * Connect to the Nord WebSocket server
111
+ */
112
+ connect() {
113
+ if (this.ws) {
114
+ return;
115
+ }
116
+ try {
117
+ const WebSocketClass = this.getWebSocketClass();
118
+ if (this.isBrowser) {
119
+ // Browser WebSocket setup
120
+ this.ws = new WebSocketClass(this.url);
121
+ this.ws.onopen = () => {
122
+ this.emit("connected");
123
+ this.reconnectAttempts = 0;
124
+ this.reconnectDelay = 1000;
125
+ };
126
+ this.ws.onmessage = (event) => {
127
+ try {
128
+ const message = JSON.parse(event.data);
129
+ this.handleMessage(message);
130
+ }
131
+ catch (error) {
132
+ this.emit("error", new Error(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`));
133
+ }
134
+ };
135
+ this.ws.onclose = (event) => {
136
+ const reason = event && event.reason ? ` Reason: ${event.reason}` : "";
137
+ const code = event && event.code ? ` Code: ${event.code}` : "";
138
+ this.emit("disconnected");
139
+ this.reconnect();
140
+ };
141
+ this.ws.onerror = (event) => {
142
+ const errorMsg = `WebSocket error: ${event && event.type ? event.type : "unknown"}`;
143
+ this.emit("error", new Error(errorMsg));
144
+ };
145
+ }
146
+ else {
147
+ // Node.js WebSocket setup
148
+ const nodeWs = new WebSocketClass(this.url);
149
+ this.ws = nodeWs;
150
+ nodeWs.on("open", () => {
151
+ this.emit("connected");
152
+ this.reconnectAttempts = 0;
153
+ this.reconnectDelay = 1000;
154
+ this.setupHeartbeat();
155
+ });
156
+ nodeWs.on("message", (data) => {
157
+ try {
158
+ const message = JSON.parse(data.toString());
159
+ this.handleMessage(message);
160
+ }
161
+ catch (error) {
162
+ this.emit("error", new Error(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`));
163
+ }
164
+ });
165
+ nodeWs.on("close", (code, reason) => {
166
+ this.emit("disconnected");
167
+ if (this.pingInterval) {
168
+ clearInterval(this.pingInterval);
169
+ }
170
+ if (this.pingTimeout) {
171
+ clearTimeout(this.pingTimeout);
172
+ }
173
+ this.reconnect();
174
+ });
175
+ nodeWs.on("error", (error) => {
176
+ this.emit("error", error);
177
+ });
178
+ nodeWs.on("pong", () => {
179
+ if (this.pingTimeout) {
180
+ clearTimeout(this.pingTimeout);
181
+ }
182
+ });
183
+ }
184
+ }
185
+ catch (error) {
186
+ const errorMsg = `Failed to initialize WebSocket: ${error instanceof Error ? error.message : String(error)}`;
187
+ this.emit("error", new Error(errorMsg));
188
+ }
189
+ }
190
+ /**
191
+ * Close the WebSocket connection
192
+ */
193
+ close() {
194
+ if (this.ws) {
195
+ if (this.isBrowser) {
196
+ this.ws.close();
197
+ }
198
+ else {
199
+ this.ws.close();
200
+ }
201
+ this.ws = null;
202
+ }
203
+ if (this.pingInterval) {
204
+ clearInterval(this.pingInterval);
205
+ this.pingInterval = null;
206
+ }
207
+ if (this.pingTimeout) {
208
+ clearTimeout(this.pingTimeout);
209
+ this.pingTimeout = null;
210
+ }
211
+ }
212
+ /**
213
+ * Handle incoming WebSocket messages
214
+ * @param message WebSocket message
215
+ */
216
+ handleMessage(message) {
217
+ if (!message || typeof message !== "object") {
218
+ this.emit("error", new Error(`Unexpected message type: ${message}`));
219
+ return;
220
+ }
221
+ const hasOwn = (k) => Object.prototype.hasOwnProperty.call(message, k);
222
+ if (hasOwn("trades")) {
223
+ this.emit("trades", message);
224
+ return;
225
+ }
226
+ if (hasOwn("delta")) {
227
+ this.emit("delta", message);
228
+ return;
229
+ }
230
+ if (hasOwn("account")) {
231
+ this.emit("account", message);
232
+ return;
233
+ }
234
+ this.emit("error", new Error(`Unexpected message type: ${message}`));
235
+ }
236
+ /**
237
+ * Attempt to reconnect to the WebSocket server
238
+ */
239
+ reconnect() {
240
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
241
+ this.emit("error", new Error("Max reconnection attempts reached"));
242
+ return;
243
+ }
244
+ setTimeout(() => {
245
+ this.reconnectAttempts++;
246
+ this.reconnectDelay *= 2; // Exponential backoff
247
+ this.connect();
248
+ }, this.reconnectDelay);
249
+ }
250
+ }
251
+ exports.NordWebSocketClient = NordWebSocketClient;
@@ -0,0 +1,19 @@
1
+ import { WebSocketTradeUpdate, WebSocketDeltaUpdate, WebSocketAccountUpdate } from "../types";
2
+ /**
3
+ * Event type definitions for the NordWebSocketClient
4
+ */
5
+ export interface NordWebSocketEvents {
6
+ connected: () => void;
7
+ disconnected: () => void;
8
+ error: (error: Error) => void;
9
+ trade: (update: WebSocketTradeUpdate) => void;
10
+ delta: (update: WebSocketDeltaUpdate) => void;
11
+ account: (update: WebSocketAccountUpdate) => void;
12
+ }
13
+ /**
14
+ * Type declaration for NordWebSocketClient event methods
15
+ */
16
+ export declare interface NordWebSocketClientEvents {
17
+ on<E extends keyof NordWebSocketEvents>(event: E, listener: NordWebSocketEvents[E]): this;
18
+ emit<E extends keyof NordWebSocketEvents>(event: E, ...args: Parameters<NordWebSocketEvents[E]>): boolean;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export { NordWebSocketClient } from "./NordWebSocketClient";
2
+ export type { NordWebSocketEvents, NordWebSocketClientEvents } from "./events";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NordWebSocketClient = void 0;
4
+ var NordWebSocketClient_1 = require("./NordWebSocketClient");
5
+ Object.defineProperty(exports, "NordWebSocketClient", { enumerable: true, get: function () { return NordWebSocketClient_1.NordWebSocketClient; } });
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "@n1xyz/nord-ts",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "Typescript for Nord",
5
5
  "keywords": [],
6
6
  "author": "",
7
7
  "license": "ISC",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist/",
12
+ "src/",
13
+ "package.json",
14
+ "README.md"
15
+ ],
10
16
  "scripts": {
11
17
  "gen:proto": "nix run ..#nord-ts-proto ../engine/nord.proto src/gen/",
12
18
  "gen:api": "nix run ..#nord-openapi | bunx openapi-typescript > src/gen/openapi.ts",
@@ -36,7 +42,7 @@
36
42
  },
37
43
  "dependencies": {
38
44
  "@bufbuild/protobuf": "^2.0.0",
39
- "@n1xyz/proton": "0.0.0",
45
+ "@n1xyz/proton": "0.0.2",
40
46
  "@noble/curves": "^1.3.0",
41
47
  "@noble/ed25519": "^2.2.3",
42
48
  "@noble/hashes": "^1.3.2",
File without changes