@n1xyz/nord-ts 0.0.20 → 0.0.22

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.
@@ -1,7 +1,7 @@
1
- import { Connection, PublicKey, Transaction } from "@solana/web3.js";
1
+ import { Connection, PublicKey, Transaction, SendOptions } from "@solana/web3.js";
2
2
  import Decimal from "decimal.js";
3
- import { FillMode, Side, SPLTokenInfo } from "../../types";
4
- import * as proto from "../../gen/nord";
3
+ import { FillMode, Side, SPLTokenInfo, QuoteSize } from "../../types";
4
+ import * as proto from "../../gen/nord_pb";
5
5
  import { BigIntValue } from "../../utils";
6
6
  import { Nord } from "./Nord";
7
7
  /**
@@ -43,8 +43,8 @@ export interface PlaceOrderParams {
43
43
  size?: Decimal.Value;
44
44
  /** Order price */
45
45
  price?: Decimal.Value;
46
- /** Quote size (for market orders) */
47
- quoteSize?: Decimal.Value;
46
+ /** Quote size object (requires non-zero price and size) */
47
+ quoteSize?: QuoteSize;
48
48
  /** Account ID to place the order from */
49
49
  accountId?: number;
50
50
  }
@@ -83,8 +83,8 @@ export interface UserAtomicSubaction {
83
83
  size?: Decimal.Value;
84
84
  /** Order price */
85
85
  price?: Decimal.Value;
86
- /** Quote size (for market orders) */
87
- quoteSize?: Decimal.Value;
86
+ /** Quote size object (for market-style placement) */
87
+ quoteSize?: QuoteSize;
88
88
  /** The client order ID of the order. */
89
89
  clientOrderId?: BigIntValue;
90
90
  }
@@ -203,13 +203,15 @@ export declare class NordUser {
203
203
  * @param amount - Amount to deposit
204
204
  * @param tokenId - Token ID
205
205
  * @param recipient - Recipient address; defaults to the user's address
206
+ * @param sendOptions - Send options for .sendTransaction
206
207
  * @returns Transaction signature
207
208
  * @throws {NordError} If required parameters are missing or operation fails
208
209
  */
209
- deposit({ amount, tokenId, recipient, }: Readonly<{
210
+ deposit({ amount, tokenId, recipient, sendOptions, }: Readonly<{
210
211
  amount: number;
211
212
  tokenId: number;
212
213
  recipient?: PublicKey;
214
+ sendOptions?: SendOptions;
213
215
  }>): Promise<string>;
214
216
  /**
215
217
  * Get a new nonce for actions
@@ -265,19 +267,27 @@ export declare class NordUser {
265
267
  * Place an order on the exchange
266
268
  *
267
269
  * @param params - Order parameters
268
- * @returns Order ID if successful
270
+ * @returns Object containing actionId, orderId (if posted), fills, and clientOrderId
269
271
  * @throws {NordError} If the operation fails
270
272
  */
271
- placeOrder(params: PlaceOrderParams): Promise<bigint | undefined>;
273
+ placeOrder(params: PlaceOrderParams): Promise<{
274
+ actionId: bigint;
275
+ orderId?: bigint;
276
+ fills: proto.Receipt_Trade[];
277
+ }>;
272
278
  /**
273
279
  * Cancel an order
274
280
  *
275
281
  * @param orderId - Order ID to cancel
276
282
  * @param providedAccountId - Account ID that placed the order
277
- * @returns Action ID if successful
283
+ * @returns Object containing actionId, cancelled orderId, and accountId
278
284
  * @throws {NordError} If the operation fails
279
285
  */
280
- cancelOrder(orderId: BigIntValue, providedAccountId?: number): Promise<bigint>;
286
+ cancelOrder(orderId: BigIntValue, providedAccountId?: number): Promise<{
287
+ actionId: bigint;
288
+ orderId: bigint;
289
+ accountId: number;
290
+ }>;
281
291
  /**
282
292
  * Transfer tokens to another account
283
293
  *
@@ -297,7 +307,10 @@ export declare class NordUser {
297
307
  * @param userActions array of user-friendly subactions
298
308
  * @param providedAccountId optional account performing the action (defaults to first account)
299
309
  */
300
- atomic(userActions: UserAtomicSubaction[], providedAccountId?: number): Promise<proto.Receipt_AtomicResult>;
310
+ atomic(userActions: UserAtomicSubaction[], providedAccountId?: number): Promise<{
311
+ actionId: bigint;
312
+ results: proto.Receipt_AtomicSubactionResultKind[];
313
+ }>;
301
314
  /**
302
315
  * Helper function to retry a promise with exponential backoff
303
316
  *
@@ -242,10 +242,11 @@ class NordUser {
242
242
  * @param amount - Amount to deposit
243
243
  * @param tokenId - Token ID
244
244
  * @param recipient - Recipient address; defaults to the user's address
245
+ * @param sendOptions - Send options for .sendTransaction
245
246
  * @returns Transaction signature
246
247
  * @throws {NordError} If required parameters are missing or operation fails
247
248
  */
248
- async deposit({ amount, tokenId, recipient, }) {
249
+ async deposit({ amount, tokenId, recipient, sendOptions, }) {
249
250
  try {
250
251
  // Find the token info
251
252
  const tokenInfo = this.splTokenInfos.find((t) => t.tokenId === tokenId);
@@ -262,14 +263,14 @@ class NordUser {
262
263
  mint,
263
264
  sourceTokenAccount: fromAccount,
264
265
  });
265
- const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
266
+ const { blockhash } = await this.connection.getLatestBlockhash();
266
267
  const tx = new web3_js_1.Transaction();
267
268
  tx.add(ix);
268
269
  tx.recentBlockhash = blockhash;
269
270
  tx.feePayer = payer;
270
271
  const signedTx = await this.transactionSignFn(tx);
271
272
  signedTx.partialSign(extraSigner);
272
- const signature = await this.connection.sendRawTransaction(signedTx.serialize());
273
+ const signature = await this.connection.sendRawTransaction(signedTx.serialize(), sendOptions);
273
274
  return signature;
274
275
  }
275
276
  catch (error) {
@@ -345,10 +346,11 @@ class NordUser {
345
346
  * @throws {NordError} If the operation fails
346
347
  */
347
348
  async refreshSession() {
348
- this.sessionId = await (0, actions_1.createSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
349
+ const result = await (0, actions_1.createSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
349
350
  userPubkey: (0, utils_1.optExpect)(this.publicKey.toBytes(), "No user's public key"),
350
351
  sessionPubkey: this.sessionPubKey,
351
352
  });
353
+ this.sessionId = result.sessionId;
352
354
  }
353
355
  /**
354
356
  * Revoke a session
@@ -404,7 +406,7 @@ class NordUser {
404
406
  * Place an order on the exchange
405
407
  *
406
408
  * @param params - Order parameters
407
- * @returns Order ID if successful
409
+ * @returns Object containing actionId, orderId (if posted), fills, and clientOrderId
408
410
  * @throws {NordError} If the operation fails
409
411
  */
410
412
  async placeOrder(params) {
@@ -414,7 +416,7 @@ class NordUser {
414
416
  if (!market) {
415
417
  throw new NordError_1.NordError(`Market with ID ${params.marketId} not found`);
416
418
  }
417
- return (0, actions_1.placeOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
419
+ const result = await (0, actions_1.placeOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
418
420
  sessionId: (0, utils_1.optExpect)(this.sessionId, "No session"),
419
421
  senderId: params.accountId,
420
422
  sizeDecimals: market.sizeDecimals,
@@ -427,6 +429,7 @@ class NordUser {
427
429
  price: params.price,
428
430
  quoteSize: params.quoteSize,
429
431
  });
432
+ return result;
430
433
  }
431
434
  catch (error) {
432
435
  throw new NordError_1.NordError("Failed to place order", { cause: error });
@@ -437,18 +440,19 @@ class NordUser {
437
440
  *
438
441
  * @param orderId - Order ID to cancel
439
442
  * @param providedAccountId - Account ID that placed the order
440
- * @returns Action ID if successful
443
+ * @returns Object containing actionId, cancelled orderId, and accountId
441
444
  * @throws {NordError} If the operation fails
442
445
  */
443
446
  async cancelOrder(orderId, providedAccountId) {
444
447
  const accountId = providedAccountId != null ? providedAccountId : this.accountIds?.[0];
445
448
  try {
446
449
  this.checkSessionValidity();
447
- return (0, actions_1.cancelOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
450
+ const result = await (0, actions_1.cancelOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
448
451
  sessionId: (0, utils_1.optExpect)(this.sessionId, "No session"),
449
452
  senderId: accountId,
450
453
  orderId,
451
454
  });
455
+ return result;
452
456
  }
453
457
  catch (error) {
454
458
  throw new NordError_1.NordError(`Failed to cancel order ${orderId}`, {
@@ -514,8 +518,7 @@ class NordUser {
514
518
  priceDecimals: market.priceDecimals,
515
519
  size: act.size,
516
520
  price: act.price,
517
- quoteSizeSize: act.quoteSize, // treated as quote size; we pass only size component
518
- quoteSizePrice: undefined,
521
+ quoteSize: act.quoteSize,
519
522
  clientOrderId: act.clientOrderId,
520
523
  };
521
524
  }
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import * as proto from "./gen/nord";
1
+ import * as proto from "./gen/nord_pb";
2
2
  import type { components } from "./gen/openapi.ts";
3
+ import Decimal from "decimal.js";
3
4
  /**
4
5
  * The peak TPS rate is queried over the specified period.
5
6
  * The period is specified in units of: {hour, day, week, month, year}.
@@ -208,19 +209,10 @@ export interface ActionNonceResponse {
208
209
  * WebSocket message types
209
210
  */
210
211
  export declare enum WebSocketMessageType {
211
- Subscribe = "subscribe",
212
- Unsubscribe = "unsubscribe",
213
212
  TradeUpdate = "trades",
214
213
  DeltaUpdate = "delta",
215
214
  AccountUpdate = "account"
216
215
  }
217
- /**
218
- * WebSocket subscription request
219
- */
220
- export interface WebSocketSubscription {
221
- e: WebSocketMessageType;
222
- streams: string[];
223
- }
224
216
  /**
225
217
  * WebSocket trade update message
226
218
  */
@@ -251,10 +243,20 @@ export interface WebSocketAccountUpdate {
251
243
  account: Account;
252
244
  timestamp: number;
253
245
  }
254
- export type WebSocketMessage = WebSocketSubscription | WebSocketTradeUpdate | WebSocketDeltaUpdate | WebSocketAccountUpdate;
246
+ export type WebSocketMessage = WebSocketTradeUpdate | WebSocketDeltaUpdate | WebSocketAccountUpdate;
255
247
  export interface SPLTokenInfo {
256
248
  mint: string;
257
249
  precision: number;
258
250
  tokenId: number;
259
251
  name: string;
260
252
  }
253
+ export declare class QuoteSize {
254
+ price: Decimal;
255
+ size: Decimal;
256
+ constructor(quotePrice: Decimal.Value, quoteSize: Decimal.Value);
257
+ value(): Decimal;
258
+ toScaledU64(marketPriceDecimals: number, marketSizeDecimals: number): {
259
+ price: bigint;
260
+ size: bigint;
261
+ };
262
+ }
package/dist/types.js CHANGED
@@ -32,10 +32,15 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.WebSocketMessageType = exports.FillMode = exports.Side = exports.KeyType = exports.PeakTpsPeriodUnit = void 0;
39
+ exports.QuoteSize = exports.WebSocketMessageType = exports.FillMode = exports.Side = exports.KeyType = exports.PeakTpsPeriodUnit = void 0;
37
40
  exports.fillModeToProtoFillMode = fillModeToProtoFillMode;
38
- const proto = __importStar(require("./gen/nord"));
41
+ const proto = __importStar(require("./gen/nord_pb"));
42
+ const decimal_js_1 = __importDefault(require("decimal.js"));
43
+ const utils_1 = require("./utils");
39
44
  /**
40
45
  * The peak TPS rate is queried over the specified period.
41
46
  * The period is specified in units of: {hour, day, week, month, year}.
@@ -95,9 +100,29 @@ function fillModeToProtoFillMode(x) {
95
100
  */
96
101
  var WebSocketMessageType;
97
102
  (function (WebSocketMessageType) {
98
- WebSocketMessageType["Subscribe"] = "subscribe";
99
- WebSocketMessageType["Unsubscribe"] = "unsubscribe";
100
103
  WebSocketMessageType["TradeUpdate"] = "trades";
101
104
  WebSocketMessageType["DeltaUpdate"] = "delta";
102
105
  WebSocketMessageType["AccountUpdate"] = "account";
103
106
  })(WebSocketMessageType || (exports.WebSocketMessageType = WebSocketMessageType = {}));
107
+ // Positive decimal price and size.
108
+ class QuoteSize {
109
+ constructor(quotePrice, quoteSize) {
110
+ const p = new decimal_js_1.default(quotePrice);
111
+ const s = new decimal_js_1.default(quoteSize);
112
+ if (p.isZero() || s.isZero()) {
113
+ throw new Error("quotePrice and quoteSize must be non-zero");
114
+ }
115
+ this.price = p;
116
+ this.size = s;
117
+ }
118
+ value() {
119
+ return this.price.mul(this.size);
120
+ }
121
+ toScaledU64(marketPriceDecimals, marketSizeDecimals) {
122
+ return {
123
+ price: (0, utils_1.toScaledU64)(this.price, marketPriceDecimals),
124
+ size: (0, utils_1.toScaledU64)(this.size, marketSizeDecimals),
125
+ };
126
+ }
127
+ }
128
+ exports.QuoteSize = QuoteSize;
package/dist/utils.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Decimal } from "decimal.js";
2
2
  import { KeyType, type Market, type Token } from "./types";
3
- import * as proto from "./gen/nord";
3
+ import { type Message } from "@bufbuild/protobuf";
4
+ import type { GenMessage } from "@bufbuild/protobuf/codegenv2";
4
5
  import { ethers } from "ethers";
5
6
  import { RequestInfo, RequestInit, Response } from "node-fetch";
6
7
  import { Keypair } from "@solana/web3.js";
@@ -68,30 +69,15 @@ export declare const toScaledU64: (x: Decimal.Value, decimals: number) => bigint
68
69
  * @returns Rescaled unsigned integer
69
70
  */
70
71
  export declare const toScaledU128: (x: Decimal.Value, decimals: number) => bigint;
71
- /**
72
- * Encodes any protobuf message into a length-delimited format,
73
- * i.e. prefixed with its length encoded as varint
74
- * @param message message object
75
- * @param coder associated coder object which implements `MessageFns` interface
76
- * @returns Encoded message as Uint8Array, prefixed with its length
77
- */
78
- export declare function encodeLengthDelimited<T, M extends proto.MessageFns<T>>(message: T, coder: M): Uint8Array;
79
72
  /**
80
73
  * Decodes any protobuf message from a length-delimited format,
81
74
  * i.e. prefixed with its length encoded as varint
82
75
  *
83
- * NB: Please note that due to limitations of Typescript type inference
84
- * it requires to specify variable type explicitly:
85
- *
86
- * ```
87
- * const foo: proto.Bar = decodeLengthDelimited(bytes, proto.Bar);
88
- * ```
89
- *
90
- * @param bytes Byte array with encoded message
91
- * @param coder associated coder object which implements `MessageFns` interface
92
- * @returns Decoded Action as Uint8Array.
76
+ * @param bytes Byte array with encoded message
77
+ * @param schema Message schema for decoding
78
+ * @returns Decoded message
93
79
  */
94
- export declare function decodeLengthDelimited<T, M extends proto.MessageFns<T>>(bytes: Uint8Array, coder: M): T;
80
+ export declare function decodeLengthDelimited<T extends Message>(bytes: Uint8Array, schema: GenMessage<T>): T;
95
81
  export declare function checkPubKeyLength(keyType: KeyType, len: number): void;
96
82
  export declare function findMarket(markets: Market[], marketId: number): Market;
97
83
  export declare function findToken(tokens: Token[], tokenId: number): Token;
package/dist/utils.js CHANGED
@@ -11,7 +11,6 @@ exports.optExpect = optExpect;
11
11
  exports.checkedFetch = checkedFetch;
12
12
  exports.signAction = signAction;
13
13
  exports.makeWalletSignFn = makeWalletSignFn;
14
- exports.encodeLengthDelimited = encodeLengthDelimited;
15
14
  exports.decodeLengthDelimited = decodeLengthDelimited;
16
15
  exports.checkPubKeyLength = checkPubKeyLength;
17
16
  exports.findMarket = findMarket;
@@ -24,6 +23,7 @@ const secp256k1_1 = require("@noble/curves/secp256k1");
24
23
  const sha256_1 = require("@noble/hashes/sha256");
25
24
  const types_1 = require("./types");
26
25
  const wire_1 = require("@bufbuild/protobuf/wire");
26
+ const protobuf_1 = require("@bufbuild/protobuf");
27
27
  const ethers_1 = require("ethers");
28
28
  const node_fetch_1 = __importDefault(require("node-fetch"));
29
29
  const web3_js_1 = require("@solana/web3.js");
@@ -101,6 +101,7 @@ function makeWalletSignFn(walletKey) {
101
101
  const signingKey = new ethers_1.ethers.SigningKey(walletKey);
102
102
  return async (message) => signingKey.sign(ethers_1.ethers.hashMessage(message)).serialized;
103
103
  }
104
+ // Returned numbers do fit into specified bits range, or error is thrown.
104
105
  function makeToScaledBigUint(params) {
105
106
  const Dec = decimal_js_1.Decimal.clone({
106
107
  precision: params.precision,
@@ -159,47 +160,28 @@ exports.toScaledU128 = makeToScaledBigUint({
159
160
  precision: 40,
160
161
  exponent: 56,
161
162
  });
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
163
  /**
178
164
  * Decodes any protobuf message from a length-delimited format,
179
165
  * i.e. prefixed with its length encoded as varint
180
166
  *
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.
167
+ * @param bytes Byte array with encoded message
168
+ * @param schema Message schema for decoding
169
+ * @returns Decoded message
191
170
  */
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).`);
171
+ function decodeLengthDelimited(bytes, schema) {
172
+ // use sizeDelimitedPeek to extract the message length and offset
173
+ const peekResult = (0, wire_1.sizeDelimitedPeek)(bytes);
174
+ if (peekResult.size === null || peekResult.offset === null) {
175
+ throw new Error("Failed to parse size-delimited message");
176
+ }
177
+ if (peekResult.size > MAX_PAYLOAD_SIZE) {
178
+ throw new Error(`Encoded message size (${peekResult.size} bytes) is greater than max payload size (${MAX_PAYLOAD_SIZE} bytes).`);
198
179
  }
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).`);
180
+ if (peekResult.offset + peekResult.size > bytes.length) {
181
+ throw new Error(`Encoded message size (${peekResult.size} bytes) is greater than remaining buffer size (${bytes.length - peekResult.offset} bytes).`);
201
182
  }
202
- return coder.decode(bytes.slice(startsAt, startsAt + msgLength));
183
+ // decode the message using the offset and size from peek
184
+ return (0, protobuf_1.fromBinary)(schema, bytes.slice(peekResult.offset, peekResult.offset + peekResult.size));
203
185
  }
204
186
  function checkPubKeyLength(keyType, len) {
205
187
  if (keyType === types_1.KeyType.Bls12_381) {
@@ -12,7 +12,6 @@ import { NordWebSocketClientEvents } from "./events";
12
12
  export declare class NordWebSocketClient extends EventEmitter implements NordWebSocketClientEvents {
13
13
  private ws;
14
14
  private url;
15
- private subscriptions;
16
15
  private reconnectAttempts;
17
16
  private maxReconnectAttempts;
18
17
  private reconnectDelay;
@@ -42,16 +41,6 @@ export declare class NordWebSocketClient extends EventEmitter implements NordWeb
42
41
  * Connect to the Nord WebSocket server
43
42
  */
44
43
  connect(): void;
45
- /**
46
- * Subscribe to one or more streams
47
- * @param streams Array of streams to subscribe to (e.g. ["trades@BTCUSDC", "deltas@BTCUSDC"])
48
- */
49
- subscribe(streams: string[]): void;
50
- /**
51
- * Unsubscribe from one or more streams
52
- * @param streams Array of streams to unsubscribe from
53
- */
54
- unsubscribe(streams: string[]): void;
55
44
  /**
56
45
  * Close the WebSocket connection
57
46
  */
@@ -6,10 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.NordWebSocketClient = void 0;
7
7
  const events_1 = require("events");
8
8
  const ws_1 = __importDefault(require("ws"));
9
- const types_1 = require("../types");
10
9
  const VALID_STREAM_TYPES = ["trades", "delta", "account"];
11
- // Constants for WebSocket readyState
12
- const WS_OPEN = 1;
13
10
  /**
14
11
  * WebSocket client for Nord exchange
15
12
  *
@@ -27,7 +24,6 @@ class NordWebSocketClient extends events_1.EventEmitter {
27
24
  constructor(url) {
28
25
  super();
29
26
  this.ws = null;
30
- this.subscriptions = new Set();
31
27
  this.reconnectAttempts = 0;
32
28
  this.maxReconnectAttempts = 5;
33
29
  this.reconnectDelay = 1000;
@@ -124,10 +120,6 @@ class NordWebSocketClient extends events_1.EventEmitter {
124
120
  this.emit("connected");
125
121
  this.reconnectAttempts = 0;
126
122
  this.reconnectDelay = 1000;
127
- // Resubscribe to previous subscriptions
128
- if (this.subscriptions.size > 0) {
129
- this.subscribe([...this.subscriptions]);
130
- }
131
123
  };
132
124
  this.ws.onmessage = (event) => {
133
125
  try {
@@ -138,16 +130,12 @@ class NordWebSocketClient extends events_1.EventEmitter {
138
130
  this.emit("error", new Error(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`));
139
131
  }
140
132
  };
141
- this.ws.onclose = (event) => {
142
- const reason = event && event.reason ? ` Reason: ${event.reason}` : "";
143
- const code = event && event.code ? ` Code: ${event.code}` : "";
133
+ this.ws.onclose = (_event) => {
144
134
  this.emit("disconnected");
145
- console.log(`WebSocket closed.${code}${reason}`);
146
135
  this.reconnect();
147
136
  };
148
137
  this.ws.onerror = (event) => {
149
138
  const errorMsg = `WebSocket error: ${event && event.type ? event.type : "unknown"}`;
150
- console.error(errorMsg, event);
151
139
  this.emit("error", new Error(errorMsg));
152
140
  };
153
141
  }
@@ -160,10 +148,6 @@ class NordWebSocketClient extends events_1.EventEmitter {
160
148
  this.reconnectAttempts = 0;
161
149
  this.reconnectDelay = 1000;
162
150
  this.setupHeartbeat();
163
- // Resubscribe to previous subscriptions
164
- if (this.subscriptions.size > 0) {
165
- this.subscribe([...this.subscriptions]);
166
- }
167
151
  });
168
152
  nodeWs.on("message", (data) => {
169
153
  try {
@@ -174,9 +158,8 @@ class NordWebSocketClient extends events_1.EventEmitter {
174
158
  this.emit("error", new Error(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`));
175
159
  }
176
160
  });
177
- nodeWs.on("close", (code, reason) => {
161
+ nodeWs.on("close", (_code, _reason) => {
178
162
  this.emit("disconnected");
179
- console.log(`WebSocket closed. Code: ${code} Reason: ${reason}`);
180
163
  if (this.pingInterval) {
181
164
  clearInterval(this.pingInterval);
182
165
  }
@@ -186,7 +169,6 @@ class NordWebSocketClient extends events_1.EventEmitter {
186
169
  this.reconnect();
187
170
  });
188
171
  nodeWs.on("error", (error) => {
189
- console.error("WebSocket error:", error);
190
172
  this.emit("error", error);
191
173
  });
192
174
  nodeWs.on("pong", () => {
@@ -198,86 +180,9 @@ class NordWebSocketClient extends events_1.EventEmitter {
198
180
  }
199
181
  catch (error) {
200
182
  const errorMsg = `Failed to initialize WebSocket: ${error instanceof Error ? error.message : String(error)}`;
201
- console.error(errorMsg);
202
183
  this.emit("error", new Error(errorMsg));
203
184
  }
204
185
  }
205
- /**
206
- * Subscribe to one or more streams
207
- * @param streams Array of streams to subscribe to (e.g. ["trades@BTCUSDC", "deltas@BTCUSDC"])
208
- */
209
- subscribe(streams) {
210
- // Validate all streams first
211
- try {
212
- streams.forEach((stream) => this.validateStream(stream));
213
- }
214
- catch (error) {
215
- this.emit("error", error instanceof Error ? error : new Error(String(error)));
216
- return;
217
- }
218
- if (!this.ws ||
219
- (this.isBrowser
220
- ? this.ws.readyState !== WS_OPEN
221
- : this.ws.readyState !== ws_1.default.OPEN)) {
222
- streams.forEach((stream) => this.subscriptions.add(stream));
223
- return;
224
- }
225
- const message = {
226
- e: types_1.WebSocketMessageType.Subscribe,
227
- streams,
228
- };
229
- try {
230
- const messageStr = JSON.stringify(message);
231
- if (this.isBrowser) {
232
- this.ws.send(messageStr);
233
- }
234
- else {
235
- this.ws.send(messageStr);
236
- }
237
- streams.forEach((stream) => this.subscriptions.add(stream));
238
- }
239
- catch (error) {
240
- this.emit("error", error instanceof Error ? error : new Error(String(error)));
241
- }
242
- }
243
- /**
244
- * Unsubscribe from one or more streams
245
- * @param streams Array of streams to unsubscribe from
246
- */
247
- unsubscribe(streams) {
248
- // Validate all streams first
249
- try {
250
- streams.forEach((stream) => this.validateStream(stream));
251
- }
252
- catch (error) {
253
- this.emit("error", error instanceof Error ? error : new Error(String(error)));
254
- return;
255
- }
256
- if (!this.ws ||
257
- (this.isBrowser
258
- ? this.ws.readyState !== WS_OPEN
259
- : this.ws.readyState !== ws_1.default.OPEN)) {
260
- streams.forEach((stream) => this.subscriptions.delete(stream));
261
- return;
262
- }
263
- const message = {
264
- e: types_1.WebSocketMessageType.Unsubscribe,
265
- streams,
266
- };
267
- try {
268
- const messageStr = JSON.stringify(message);
269
- if (this.isBrowser) {
270
- this.ws.send(messageStr);
271
- }
272
- else {
273
- this.ws.send(messageStr);
274
- }
275
- streams.forEach((stream) => this.subscriptions.delete(stream));
276
- }
277
- catch (error) {
278
- this.emit("error", error instanceof Error ? error : new Error(String(error)));
279
- }
280
- }
281
186
  /**
282
187
  * Close the WebSocket connection
283
188
  */
@@ -299,7 +204,6 @@ class NordWebSocketClient extends events_1.EventEmitter {
299
204
  clearTimeout(this.pingTimeout);
300
205
  this.pingTimeout = null;
301
206
  }
302
- this.subscriptions.clear();
303
207
  }
304
208
  /**
305
209
  * Handle incoming WebSocket messages