@n1xyz/nord-ts 0.1.5 → 0.1.7

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 (47) hide show
  1. package/dist/actions.d.ts +57 -0
  2. package/dist/actions.js +229 -0
  3. package/dist/client/Nord.d.ts +379 -0
  4. package/dist/client/Nord.js +718 -0
  5. package/dist/client/NordAdmin.d.ts +225 -0
  6. package/dist/client/NordAdmin.js +394 -0
  7. package/dist/client/NordUser.d.ts +350 -0
  8. package/dist/client/NordUser.js +743 -0
  9. package/dist/error.d.ts +35 -0
  10. package/dist/error.js +49 -0
  11. package/dist/gen/nord_pb.d.ts +233 -7
  12. package/dist/gen/nord_pb.js +34 -8
  13. package/dist/gen/openapi.d.ts +40 -0
  14. package/dist/index.d.ts +6 -1
  15. package/dist/index.js +29 -1
  16. package/dist/nord/client/Nord.d.ts +1 -1
  17. package/dist/nord/client/Nord.js +2 -2
  18. package/dist/nord/client/NordAdmin.d.ts +24 -1
  19. package/dist/nord/client/NordAdmin.js +63 -5
  20. package/dist/nord/index.d.ts +1 -1
  21. package/dist/nord/index.js +2 -1
  22. package/dist/types.d.ts +6 -50
  23. package/dist/types.js +1 -24
  24. package/dist/utils.d.ts +8 -11
  25. package/dist/utils.js +54 -41
  26. package/dist/websocket/Subscriber.d.ts +37 -0
  27. package/dist/websocket/Subscriber.js +25 -0
  28. package/dist/websocket/index.d.ts +19 -2
  29. package/dist/websocket/index.js +82 -2
  30. package/package.json +1 -1
  31. package/src/actions.ts +333 -0
  32. package/src/{nord/client → client}/Nord.ts +209 -211
  33. package/src/{nord/client → client}/NordAdmin.ts +196 -153
  34. package/src/{nord/client → client}/NordUser.ts +216 -305
  35. package/src/gen/nord_pb.ts +271 -9
  36. package/src/gen/openapi.ts +40 -0
  37. package/src/index.ts +7 -1
  38. package/src/types.ts +7 -54
  39. package/src/utils.ts +44 -47
  40. package/src/{nord/models → websocket}/Subscriber.ts +2 -2
  41. package/src/websocket/index.ts +105 -2
  42. package/src/nord/api/actions.ts +0 -648
  43. package/src/nord/api/core.ts +0 -96
  44. package/src/nord/api/metrics.ts +0 -269
  45. package/src/nord/client/NordClient.ts +0 -79
  46. package/src/nord/index.ts +0 -25
  47. /package/src/{nord/utils/NordError.ts → error.ts} +0 -0
package/dist/types.d.ts CHANGED
@@ -1,22 +1,7 @@
1
1
  import * as proto from "./gen/nord_pb";
2
2
  import type { components } from "./gen/openapi.ts";
3
3
  import Decimal from "decimal.js";
4
- /**
5
- * The peak TPS rate is queried over the specified period.
6
- * The period is specified in units of: {hour, day, week, month, year}.
7
- * Example inputs:
8
- * 1. AggregateMetrics.txPeakTpsPeriod = 3,
9
- * AggregateMetrics.txPeakTpsPeriodUnit = "d" => Peak TPS over last 3 days.
10
- * 1. AggregateMetrics.txPeakTpsPeriod = 1,
11
- * AggregateMetrics.txPeakTpsPeriodUnit = "w" => Peak TPS over last week.
12
- */
13
- export declare enum PeakTpsPeriodUnit {
14
- Hour = "h",
15
- Day = "d",
16
- Week = "w",
17
- Month = "m",
18
- Year = "y"
19
- }
4
+ import { Connection } from "@solana/web3.js";
20
5
  /**
21
6
  * Nord subscription type for trades or deltas
22
7
  */
@@ -35,8 +20,10 @@ export interface NordConfig {
35
20
  webServerUrl: string;
36
21
  /** App address */
37
22
  app: string;
38
- /** Solana cluster URL */
39
- solanaUrl: string;
23
+ /** Solana connection */
24
+ solanaConnection: Connection;
25
+ /** Proton URL, defaults to webServerUrl */
26
+ protonUrl?: string;
40
27
  /**
41
28
  * Whether to initialize WebSockets on creation, defaults to true
42
29
  * @deprecated this is a funky api we're gonna be removing it
@@ -99,11 +86,6 @@ export interface Order {
99
86
  price: number;
100
87
  marketId: number;
101
88
  }
102
- export declare enum KeyType {
103
- Ed25519 = 0,
104
- Secp256k1 = 1,
105
- Bls12_381 = 2
106
- }
107
89
  export declare enum Side {
108
90
  Ask = "ask",
109
91
  Bid = "bid"
@@ -163,32 +145,6 @@ export interface ActionResponse {
163
145
  action: proto.Action;
164
146
  physicalExecTime: Date;
165
147
  }
166
- /**
167
- * Block summary.
168
- * block_number Block number.
169
- * from_action_id First action_id in the block.
170
- * to_action_id Last action_id in the block.
171
- */
172
- export interface BlockSummary {
173
- block_number: number;
174
- from_action_id: number;
175
- to_action_id: number;
176
- }
177
- /**
178
- * Aggregate metrics
179
- * blocks_total: Total number of L2 blocks.
180
- * tx_total: Total number of transactions.
181
- * tx_tps: Transaction throughput.
182
- * tx_tps_peak: Peak transaction throughput.
183
- * request_latency_average: Average request latency.
184
- */
185
- export interface AggregateMetrics {
186
- blocks_total: number;
187
- tx_total: number;
188
- tx_tps: number;
189
- tx_tps_peak: number;
190
- request_latency_average: number;
191
- }
192
148
  /**
193
149
  * Converts a `FillMode` enum to its corresponding protobuf representation.
194
150
  *
@@ -212,7 +168,7 @@ export interface OrderbookEntry {
212
168
  */
213
169
  export interface OrderbookQuery {
214
170
  symbol?: string;
215
- market_id?: number;
171
+ marketId?: number;
216
172
  }
217
173
  /**
218
174
  * Response for timestamp query
package/dist/types.js CHANGED
@@ -36,34 +36,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.QuoteSize = exports.WebSocketMessageType = exports.TriggerStatus = exports.TriggerKind = exports.FillMode = exports.Side = exports.KeyType = exports.PeakTpsPeriodUnit = void 0;
39
+ exports.QuoteSize = exports.WebSocketMessageType = exports.TriggerStatus = exports.TriggerKind = exports.FillMode = exports.Side = void 0;
40
40
  exports.fillModeToProtoFillMode = fillModeToProtoFillMode;
41
41
  const proto = __importStar(require("./gen/nord_pb"));
42
42
  const decimal_js_1 = __importDefault(require("decimal.js"));
43
43
  const utils_1 = require("./utils");
44
- /**
45
- * The peak TPS rate is queried over the specified period.
46
- * The period is specified in units of: {hour, day, week, month, year}.
47
- * Example inputs:
48
- * 1. AggregateMetrics.txPeakTpsPeriod = 3,
49
- * AggregateMetrics.txPeakTpsPeriodUnit = "d" => Peak TPS over last 3 days.
50
- * 1. AggregateMetrics.txPeakTpsPeriod = 1,
51
- * AggregateMetrics.txPeakTpsPeriodUnit = "w" => Peak TPS over last week.
52
- */
53
- var PeakTpsPeriodUnit;
54
- (function (PeakTpsPeriodUnit) {
55
- PeakTpsPeriodUnit["Hour"] = "h";
56
- PeakTpsPeriodUnit["Day"] = "d";
57
- PeakTpsPeriodUnit["Week"] = "w";
58
- PeakTpsPeriodUnit["Month"] = "m";
59
- PeakTpsPeriodUnit["Year"] = "y";
60
- })(PeakTpsPeriodUnit || (exports.PeakTpsPeriodUnit = PeakTpsPeriodUnit = {}));
61
- var KeyType;
62
- (function (KeyType) {
63
- KeyType[KeyType["Ed25519"] = 0] = "Ed25519";
64
- KeyType[KeyType["Secp256k1"] = 1] = "Secp256k1";
65
- KeyType[KeyType["Bls12_381"] = 2] = "Bls12_381";
66
- })(KeyType || (exports.KeyType = KeyType = {}));
67
44
  var Side;
68
45
  (function (Side) {
69
46
  Side["Ask"] = "ask";
package/dist/utils.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { Decimal } from "decimal.js";
2
- import { KeyType, type Market, type Token } from "./types";
2
+ import { type Market, type Token } from "./types";
3
3
  import { type Message } from "@bufbuild/protobuf";
4
4
  import type { GenMessage } from "@bufbuild/protobuf/codegenv2";
5
5
  import { ethers } from "ethers";
6
6
  import { RequestInfo, RequestInit, Response } from "node-fetch";
7
7
  import { Keypair } from "@solana/web3.js";
8
+ import * as solana from "@solana/web3.js";
8
9
  export declare const SESSION_TTL: bigint;
9
10
  export declare const ZERO_DECIMAL: Decimal;
10
11
  export declare const MAX_BUFFER_LEN = 10000;
@@ -12,7 +13,7 @@ export declare const MAX_BUFFER_LEN = 10000;
12
13
  export type BigIntValue = bigint | number | string;
13
14
  export declare function panic(message: string): never;
14
15
  export declare function isRfc3339(s: string): boolean;
15
- export declare function assert(predicate: boolean, message?: string): void;
16
+ export declare function assert(predicate: boolean, message?: string): asserts predicate;
16
17
  /**
17
18
  * Extracts value out of optional if it's defined, or throws error if it's not
18
19
  * @param value Optional value to unwrap
@@ -28,14 +29,6 @@ export declare function optExpect<T>(value: T | undefined, message: string): T;
28
29
  * @throws If response wasn't Ok
29
30
  */
30
31
  export declare function checkedFetch(url: RequestInfo, init?: RequestInit): Promise<Response>;
31
- /**
32
- * Signs an action using the specified secret key and key type.
33
- * @param action - The action data to be signed.
34
- * @param sk - Secret key used for signing the action.
35
- * @param keyType - Type of the key used for signing.
36
- * @returns A new Uint8Array containing the action followed by its signature.
37
- */
38
- export declare function signAction(action: Uint8Array, sk: Uint8Array, keyType: KeyType): Uint8Array;
39
32
  /**
40
33
  * Constructs wallet signing function, usable with `NordUser` type
41
34
  *
@@ -78,8 +71,12 @@ export declare const toScaledU128: (x: Decimal.Value, decimals: number) => bigin
78
71
  * @returns Decoded message
79
72
  */
80
73
  export declare function decodeLengthDelimited<T extends Message>(bytes: Uint8Array, schema: GenMessage<T>): T;
81
- export declare function checkPubKeyLength(keyType: KeyType, len: number): void;
82
74
  export declare function decodeHex(value: string): Uint8Array;
83
75
  export declare function findMarket(markets: Market[], marketId: number): Market;
84
76
  export declare function findToken(tokens: Token[], tokenId: number): Token;
85
77
  export declare function keypairFromPrivateKey(privateKey: string | Uint8Array): Keypair;
78
+ export declare function signUserPayload({ payload, user, signTransaction, }: Readonly<{
79
+ payload: Uint8Array;
80
+ user: solana.PublicKey;
81
+ signTransaction: (tx: solana.Transaction) => Promise<solana.Transaction>;
82
+ }>): Promise<Uint8Array>;
package/dist/utils.js CHANGED
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -9,26 +42,21 @@ exports.isRfc3339 = isRfc3339;
9
42
  exports.assert = assert;
10
43
  exports.optExpect = optExpect;
11
44
  exports.checkedFetch = checkedFetch;
12
- exports.signAction = signAction;
13
45
  exports.makeWalletSignFn = makeWalletSignFn;
14
46
  exports.decodeLengthDelimited = decodeLengthDelimited;
15
- exports.checkPubKeyLength = checkPubKeyLength;
16
47
  exports.decodeHex = decodeHex;
17
48
  exports.findMarket = findMarket;
18
49
  exports.findToken = findToken;
19
50
  exports.keypairFromPrivateKey = keypairFromPrivateKey;
51
+ exports.signUserPayload = signUserPayload;
20
52
  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
53
  const wire_1 = require("@bufbuild/protobuf/wire");
27
54
  const protobuf_1 = require("@bufbuild/protobuf");
28
55
  const ethers_1 = require("ethers");
29
56
  const node_fetch_1 = __importDefault(require("node-fetch"));
30
57
  const web3_js_1 = require("@solana/web3.js");
31
58
  const bs58_1 = __importDefault(require("bs58"));
59
+ const solana = __importStar(require("@solana/web3.js"));
32
60
  exports.SESSION_TTL = 60n * 60n * 24n * 30n;
33
61
  exports.ZERO_DECIMAL = new decimal_js_1.Decimal(0);
34
62
  exports.MAX_BUFFER_LEN = 10000;
@@ -68,29 +96,6 @@ async function checkedFetch(url, init) {
68
96
  assert(resp.ok, `Request failed with ${resp.status}: ${resp.statusText}`);
69
97
  return resp;
70
98
  }
71
- /**
72
- * Signs an action using the specified secret key and key type.
73
- * @param action - The action data to be signed.
74
- * @param sk - Secret key used for signing the action.
75
- * @param keyType - Type of the key used for signing.
76
- * @returns A new Uint8Array containing the action followed by its signature.
77
- */
78
- function signAction(action, sk, keyType) {
79
- let sig;
80
- if (keyType === types_1.KeyType.Ed25519) {
81
- sig = ed25519_1.ed25519.sign(action, sk);
82
- }
83
- else if (keyType === types_1.KeyType.Bls12_381) {
84
- sig = bls12_381_1.bls12_381.sign(action, sk);
85
- }
86
- else if (keyType === types_1.KeyType.Secp256k1) {
87
- sig = secp256k1_1.secp256k1.sign((0, sha256_1.sha256)(action), sk).toCompactRawBytes();
88
- }
89
- else {
90
- throw new Error("Invalid key type");
91
- }
92
- return new Uint8Array([...action, ...sig]);
93
- }
94
99
  /**
95
100
  * Constructs wallet signing function, usable with `NordUser` type
96
101
  *
@@ -185,17 +190,6 @@ function decodeLengthDelimited(bytes, schema) {
185
190
  // decode the message using the offset and size from peek
186
191
  return (0, protobuf_1.fromBinary)(schema, bytes.slice(peekResult.offset, peekResult.offset + peekResult.size));
187
192
  }
188
- function checkPubKeyLength(keyType, len) {
189
- if (keyType === types_1.KeyType.Bls12_381) {
190
- throw new Error("Cannot create a user using Bls12_381, use Ed25119 or Secp256k1 instead.");
191
- }
192
- if (len !== 32 && keyType === types_1.KeyType.Ed25519) {
193
- throw new Error("Ed25519 pubkeys must be 32 length.");
194
- }
195
- if (len !== 33 && keyType === types_1.KeyType.Secp256k1) {
196
- throw new Error("Secp256k1 pubkeys must be 33 length.");
197
- }
198
- }
199
193
  function decodeHex(value) {
200
194
  const hex = value.startsWith("0x") ? value.slice(2) : value;
201
195
  return Uint8Array.from(Buffer.from(hex, "hex"));
@@ -223,3 +217,22 @@ function keypairFromPrivateKey(privateKey) {
223
217
  }
224
218
  return web3_js_1.Keypair.fromSecretKey(privateKey);
225
219
  }
220
+ async function signUserPayload({ payload, user, signTransaction, }) {
221
+ const tx = new solana.Transaction({
222
+ blockhash: bs58_1.default.encode(new Uint8Array(32)),
223
+ lastValidBlockHeight: 0,
224
+ feePayer: user,
225
+ });
226
+ tx.add(new solana.TransactionInstruction({
227
+ keys: [],
228
+ programId: user,
229
+ data: Buffer.from(payload),
230
+ }));
231
+ const signedTx = await signTransaction(tx);
232
+ const sig = signedTx.signatures[0];
233
+ assert(sig.signature !== null, "signature must be non-null; check your signTransaction function");
234
+ assert(sig.signature.length === 64, //.
235
+ "signature must be 64 bytes");
236
+ assert(sig.publicKey.equals(user), `signature is for ${sig.publicKey}, expected ${user}`);
237
+ return sig.signature;
238
+ }
@@ -0,0 +1,37 @@
1
+ import { EventEmitter } from "events";
2
+ import { Account, DeltaEvent, OrderbookResponse, SubscriberConfig, StreamTrade, Trades } from "../types";
3
+ /**
4
+ * Subscriber class for handling WebSocket subscriptions
5
+ */
6
+ export declare class Subscriber {
7
+ streamURL: string;
8
+ buffer: (DeltaEvent | Trades | Account)[];
9
+ maxBufferLen: number;
10
+ /**
11
+ * Create a new Subscriber instance
12
+ * @param config Subscriber configuration
13
+ */
14
+ constructor(config: SubscriberConfig);
15
+ /**
16
+ * Subscribe to WebSocket events
17
+ */
18
+ subscribe(): void;
19
+ }
20
+ /**
21
+ * Interface for orderbook subscription
22
+ */
23
+ export interface OrderbookSubscription extends EventEmitter {
24
+ on(event: "message", listener: (data: OrderbookResponse) => void): this;
25
+ on(event: "error", listener: (error: Error) => void): this;
26
+ close(): void;
27
+ removeAllListeners(event?: string): this;
28
+ }
29
+ /**
30
+ * Interface for trade subscription
31
+ */
32
+ export interface TradeSubscription extends EventEmitter {
33
+ on(event: "message", listener: (data: StreamTrade[]) => void): this;
34
+ on(event: "error", listener: (error: Error) => void): this;
35
+ close(): void;
36
+ removeAllListeners(event?: string): this;
37
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Subscriber = void 0;
4
+ const utils_1 = require("../utils");
5
+ /**
6
+ * Subscriber class for handling WebSocket subscriptions
7
+ */
8
+ class Subscriber {
9
+ /**
10
+ * Create a new Subscriber instance
11
+ * @param config Subscriber configuration
12
+ */
13
+ constructor(config) {
14
+ this.streamURL = config.streamURL;
15
+ this.buffer = [];
16
+ this.maxBufferLen = config.maxBufferLen ?? utils_1.MAX_BUFFER_LEN;
17
+ }
18
+ /**
19
+ * Subscribe to WebSocket events
20
+ */
21
+ subscribe() {
22
+ // TODO: Implement subscription logic
23
+ }
24
+ }
25
+ exports.Subscriber = Subscriber;
@@ -1,2 +1,19 @@
1
- export { NordWebSocketClient } from "./NordWebSocketClient";
2
- export type { NordWebSocketEvents, NordWebSocketClientEvents } from "./events";
1
+ import { NordWebSocketClient } from "./NordWebSocketClient";
2
+ import type { SubscriptionPattern } from "../types";
3
+ import type { NordWebSocketEvents, NordWebSocketClientEvents } from "./events";
4
+ import { Subscriber } from "./Subscriber";
5
+ export { NordWebSocketClient, NordWebSocketEvents, NordWebSocketClientEvents, Subscriber, };
6
+ /**
7
+ * Initialize a WebSocket client for Nord
8
+ *
9
+ * Connects to the Nord WebSocket endpoint with support for multiple subscription types:
10
+ * - trades@SYMBOL - For trade updates
11
+ * - deltas@SYMBOL - For orderbook delta updates
12
+ * - account@ACCOUNT_ID - For user-specific updates
13
+ *
14
+ * @param webServerUrl - Base URL for the Nord web server
15
+ * @param subscriptions - Array of subscriptions (e.g., ["trades@BTCUSDC", "deltas@BTCUSDC", "account@42"])
16
+ * @returns WebSocket client
17
+ * @throws {NordError} If initialization fails or invalid subscription is provided
18
+ */
19
+ export declare function initWebSocketClient(webServerUrl: string, subscriptions?: SubscriptionPattern[] | "trades" | "delta" | "account"): NordWebSocketClient;
@@ -1,5 +1,85 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NordWebSocketClient = void 0;
4
- var NordWebSocketClient_1 = require("./NordWebSocketClient");
3
+ exports.Subscriber = exports.NordWebSocketClient = void 0;
4
+ exports.initWebSocketClient = initWebSocketClient;
5
+ const NordWebSocketClient_1 = require("./NordWebSocketClient");
5
6
  Object.defineProperty(exports, "NordWebSocketClient", { enumerable: true, get: function () { return NordWebSocketClient_1.NordWebSocketClient; } });
7
+ const error_1 = require("../error");
8
+ const Subscriber_1 = require("./Subscriber");
9
+ Object.defineProperty(exports, "Subscriber", { enumerable: true, get: function () { return Subscriber_1.Subscriber; } });
10
+ /**
11
+ * Initialize a WebSocket client for Nord
12
+ *
13
+ * Connects to the Nord WebSocket endpoint with support for multiple subscription types:
14
+ * - trades@SYMBOL - For trade updates
15
+ * - deltas@SYMBOL - For orderbook delta updates
16
+ * - account@ACCOUNT_ID - For user-specific updates
17
+ *
18
+ * @param webServerUrl - Base URL for the Nord web server
19
+ * @param subscriptions - Array of subscriptions (e.g., ["trades@BTCUSDC", "deltas@BTCUSDC", "account@42"])
20
+ * @returns WebSocket client
21
+ * @throws {NordError} If initialization fails or invalid subscription is provided
22
+ */
23
+ function initWebSocketClient(webServerUrl, subscriptions) {
24
+ try {
25
+ // Determine URL and subscriptions based on parameters
26
+ let wsUrl = webServerUrl.replace(/^http/, "ws") + `/ws`;
27
+ // Validate subscriptions parameter
28
+ if (typeof subscriptions === "string") {
29
+ // Legacy mode - handle endpoint string
30
+ if (subscriptions === "trades" ||
31
+ subscriptions === "delta" ||
32
+ subscriptions === "account") {
33
+ wsUrl += `/${subscriptions}`;
34
+ }
35
+ else {
36
+ throw new error_1.NordError(`Invalid endpoint: ${subscriptions}. Must be "trades", "deltas", or "account".`);
37
+ }
38
+ }
39
+ else if (Array.isArray(subscriptions) && subscriptions.length > 0) {
40
+ // New mode - validate and combine subscriptions in URL
41
+ subscriptions.forEach(validateSubscription);
42
+ wsUrl += `/${subscriptions.join("&")}`;
43
+ }
44
+ else {
45
+ // Default to trades endpoint if no subscriptions specified
46
+ wsUrl += `/trades`;
47
+ }
48
+ console.log(`Initializing WebSocket client with URL: ${wsUrl}`);
49
+ // Create and connect the WebSocket client
50
+ const ws = new NordWebSocketClient_1.NordWebSocketClient(wsUrl);
51
+ // Add error handler
52
+ ws.on("error", (error) => {
53
+ console.error("Nord WebSocket error:", error);
54
+ });
55
+ // Add connected handler for debugging
56
+ ws.on("connected", () => {
57
+ console.log("Nord WebSocket connected successfully");
58
+ });
59
+ // Connect the WebSocket
60
+ ws.connect();
61
+ return ws;
62
+ }
63
+ catch (error) {
64
+ console.error("Failed to initialize WebSocket client:", error);
65
+ throw new error_1.NordError("Failed to initialize WebSocket client", {
66
+ cause: error,
67
+ });
68
+ }
69
+ }
70
+ /**
71
+ * Validates a subscription string follows the correct format
72
+ *
73
+ * @param subscription - The subscription to validate
74
+ * @throws {NordError} If the subscription format is invalid
75
+ */
76
+ function validateSubscription(subscription) {
77
+ const [type, param] = subscription.split("@");
78
+ if (!type || !param || !["trades", "deltas", "account"].includes(type)) {
79
+ throw new error_1.NordError(`Invalid subscription format: ${subscription}. Expected format: "trades@SYMBOL", "deltas@SYMBOL", or "account@ID"`);
80
+ }
81
+ // Additional validation for account subscriptions
82
+ if (type === "account" && isNaN(Number(param))) {
83
+ throw new error_1.NordError(`Invalid account ID in subscription: ${subscription}. Account ID must be a number.`);
84
+ }
85
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n1xyz/nord-ts",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Typescript for Nord",
5
5
  "keywords": [],
6
6
  "author": "",