@n1xyz/nord-ts 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/actions.js +184 -0
  2. package/dist/client/Nord.d.ts +9 -15
  3. package/dist/client/Nord.js +759 -0
  4. package/dist/client/NordAdmin.js +362 -0
  5. package/dist/client/NordUser.d.ts +3 -1
  6. package/dist/client/NordUser.js +752 -0
  7. package/dist/const.js +27 -0
  8. package/dist/error.js +51 -0
  9. package/dist/gen/nord_pb.d.ts +132 -114
  10. package/dist/gen/nord_pb.js +1068 -0
  11. package/dist/gen/openapi.d.ts +345 -72
  12. package/dist/gen/openapi.js +5 -0
  13. package/dist/index.browser.js +61342 -80207
  14. package/dist/index.common.js +59722 -87597
  15. package/dist/index.js +10 -0
  16. package/dist/nord/api/actions.d.ts +128 -0
  17. package/dist/nord/api/actions.js +396 -0
  18. package/dist/nord/api/core.d.ts +16 -0
  19. package/dist/nord/api/core.js +81 -0
  20. package/dist/nord/api/metrics.d.ts +67 -0
  21. package/dist/nord/api/metrics.js +229 -0
  22. package/dist/nord/api/triggers.d.ts +7 -0
  23. package/dist/nord/api/triggers.js +38 -0
  24. package/dist/nord/client/Nord.d.ts +387 -0
  25. package/dist/nord/client/Nord.js +747 -0
  26. package/dist/nord/client/NordAdmin.d.ts +226 -0
  27. package/dist/nord/client/NordAdmin.js +410 -0
  28. package/dist/nord/client/NordClient.d.ts +16 -0
  29. package/dist/nord/client/NordClient.js +28 -0
  30. package/dist/nord/client/NordUser.d.ts +379 -0
  31. package/dist/nord/client/NordUser.js +787 -0
  32. package/dist/nord/index.d.ts +8 -0
  33. package/dist/nord/index.js +34 -0
  34. package/dist/nord/models/Subscriber.d.ts +37 -0
  35. package/dist/nord/models/Subscriber.js +25 -0
  36. package/dist/nord/utils/NordError.d.ts +35 -0
  37. package/dist/nord/utils/NordError.js +49 -0
  38. package/dist/types.d.ts +15 -6
  39. package/dist/types.js +92 -0
  40. package/dist/utils.js +193 -0
  41. package/dist/websocket/NordWebSocketClient.d.ts +1 -0
  42. package/dist/websocket/NordWebSocketClient.js +242 -0
  43. package/dist/websocket/Subscriber.d.ts +7 -1
  44. package/dist/websocket/Subscriber.js +24 -0
  45. package/dist/websocket/events.d.ts +2 -1
  46. package/dist/websocket/events.js +1 -0
  47. package/dist/websocket/index.d.ts +1 -1
  48. package/dist/websocket/index.js +80 -0
  49. package/package.json +2 -2
@@ -0,0 +1,759 @@
1
+ import { ProtonClient } from "@n1xyz/proton";
2
+ import { PublicKey } from "@solana/web3.js";
3
+ import { EventEmitter } from "events";
4
+ import createClient from "openapi-fetch";
5
+ import * as proto from "../gen/nord_pb";
6
+ import * as utils from "../utils";
7
+ import { initWebSocketClient } from "../websocket";
8
+ import { NordError } from "../error";
9
+ /**
10
+ * Main Nord client class for interacting with the Nord API
11
+ */
12
+ export class Nord {
13
+ /** Base URL for the Nord web server */
14
+ webServerUrl;
15
+ /** Solana RPC URL */
16
+ solanaConnection;
17
+ /** Available markets */
18
+ markets = [];
19
+ /** Available tokens */
20
+ tokens = [];
21
+ /** Map of symbol to market_id */
22
+ symbolToMarketId = new Map();
23
+ /** Proton client for proton related operations */
24
+ protonClient;
25
+ /** HTTP client for Nord operations */
26
+ httpClient;
27
+ /**
28
+ * Create a new Nord client
29
+ *
30
+ * @param config - Configuration options for the Nord client
31
+ * @param config.webServerUrl - Base URL for the Nord web server
32
+ * @param config.solanaUrl - Solana cluster URL
33
+ * @throws {Error} If required configuration is missing
34
+ */
35
+ constructor({ solanaConnection, webServerUrl, protonClient, }) {
36
+ this.webServerUrl = webServerUrl;
37
+ this.solanaConnection = solanaConnection;
38
+ this.protonClient = protonClient;
39
+ this.httpClient = createClient({ baseUrl: webServerUrl });
40
+ }
41
+ /**
42
+ * Create a WebSocket client with specific subscriptions
43
+ *
44
+ * @param trades - Market symbols to subscribe to for trade updates
45
+ * @param deltas - Market symbols to subscribe to for orderbook delta updates
46
+ * @param accounts - Account IDs to subscribe to for account updates
47
+ * @returns A new WebSocket client with the requested subscriptions
48
+ * @throws {NordError} If invalid subscription options are provided
49
+ *
50
+ * @example
51
+ * // Create a client for trades and deltas from one market and an account
52
+ * const wsClient = nord.createWebSocketClient({
53
+ * trades: ["BTCUSDC"],
54
+ * deltas: ["BTCUSDC"],
55
+ * accounts: [123]
56
+ * });
57
+ *
58
+ * @example
59
+ * // Create a client for trades from multiple markets
60
+ * const tradesClient = nord.createWebSocketClient({
61
+ * trades: ["BTCUSDC", "ETHUSDC"]
62
+ * });
63
+ */
64
+ createWebSocketClient({ trades, deltas, accounts, }) {
65
+ const subscriptions = [];
66
+ // Add trade subscriptions
67
+ if (trades && trades.length > 0) {
68
+ trades.forEach((symbol) => {
69
+ subscriptions.push(`trades@${symbol}`);
70
+ });
71
+ }
72
+ // Add delta subscriptions
73
+ if (deltas && deltas.length > 0) {
74
+ deltas.forEach((symbol) => {
75
+ subscriptions.push(`deltas@${symbol}`);
76
+ });
77
+ }
78
+ // Add account subscriptions
79
+ if (accounts && accounts.length > 0) {
80
+ accounts.forEach((accountId) => {
81
+ if (isNaN(accountId) || accountId <= 0) {
82
+ throw new NordError(`Invalid account ID: ${accountId}. Must be a positive number.`);
83
+ }
84
+ subscriptions.push(`account@${accountId}`);
85
+ });
86
+ }
87
+ // Validate that at least one subscription was provided
88
+ if (subscriptions.length === 0) {
89
+ throw new NordError("At least one subscription must be provided");
90
+ }
91
+ // Create and return a new WebSocket client
92
+ return initWebSocketClient(this.webServerUrl, subscriptions);
93
+ }
94
+ async GET(path, options) {
95
+ const r = await this.httpClient.GET(path, options);
96
+ if (r.error) {
97
+ throw new NordError(`failed to GET ${path}`, { cause: r.error });
98
+ }
99
+ if (r.data === undefined) {
100
+ // this should never happen, but the type checker seems unhappy.
101
+ // if we catch this we'll need to debug accordingly.
102
+ throw new NordError("internal assertion violation", { cause: r });
103
+ }
104
+ return r.data;
105
+ }
106
+ /**
107
+ * Get the current timestamp from the Nord server
108
+ *
109
+ * @returns Current timestamp as a bigint
110
+ * @throws {NordError} If the request fails
111
+ */
112
+ async getTimestamp() {
113
+ return BigInt(await this.GET("/timestamp", {}));
114
+ }
115
+ /**
116
+ * Get the last event nonce from the Nord server
117
+ *
118
+ * @returns Next action nonce
119
+ * @throws {NordError} If the request fails
120
+ */
121
+ async getActionNonce() {
122
+ return await this.GET("/event/last-acked-nonce", {});
123
+ }
124
+ /**
125
+ * Get the admin list from the Nord server
126
+ *
127
+ * @returns List of admin registration keys paired with their ACL role mask
128
+ * @throws {NordError} If the request fails
129
+ */
130
+ async getAdminList() {
131
+ return await this.GET("/admin", {});
132
+ }
133
+ /**
134
+ * Get account volume across all markets, optionally for a specific market.
135
+ *
136
+ * @param accountId - Account identifier
137
+ * @param since - RFC3339 timestamp marking the inclusive start of the window
138
+ * @param until - RFC3339 timestamp marking the exclusive end of the window
139
+ * @param marketId - Optional market identifier to scope the volume
140
+ * @returns Array of market volumes (single entry when `marketId` is provided)
141
+ * @throws {NordError} If the request fails
142
+ */
143
+ async getAccountVolume({ accountId, since, until, marketId, }) {
144
+ return await this.GET("/account/volume", {
145
+ params: {
146
+ query: {
147
+ accountId,
148
+ since,
149
+ until,
150
+ marketId,
151
+ },
152
+ },
153
+ });
154
+ }
155
+ /**
156
+ * Fetch information about Nord markets and tokens
157
+ *
158
+ * @throws {NordError} If the request fails
159
+ */
160
+ async fetchNordInfo() {
161
+ try {
162
+ const info = await this.GET("/info", {});
163
+ this.markets = info.markets;
164
+ this.tokens = info.tokens;
165
+ // Populate the symbolToMarketId map
166
+ this.symbolToMarketId.clear();
167
+ info.markets.forEach((market) => {
168
+ this.symbolToMarketId.set(market.symbol, market.marketId);
169
+ });
170
+ }
171
+ catch (error) {
172
+ throw new NordError("Failed to fetch Nord info", { cause: error });
173
+ }
174
+ }
175
+ /** @deprecated use Nord.new */
176
+ static async initNord(x) {
177
+ return await Nord.new(x);
178
+ }
179
+ /**
180
+ * Initialize a new Nord client
181
+ *
182
+ * @param nordConfig - Configuration options for the Nord client
183
+ * @param nordConfig.webServerUrl - Base URL for the Nord web server
184
+ * @param nordConfig.app - App address
185
+ * @param nordConfig.solanaUrl - Solana cluster URL
186
+ * @returns Initialized Nord client
187
+ * @throws {NordError} If initialization fails
188
+ */
189
+ static async new({ app, solanaConnection, webServerUrl, protonUrl, }) {
190
+ const protonClient = await ProtonClient.init({
191
+ protonUrl: protonUrl ?? webServerUrl,
192
+ app: new PublicKey(app),
193
+ solConn: solanaConnection,
194
+ });
195
+ const nord = new Nord({
196
+ protonClient,
197
+ solanaConnection,
198
+ webServerUrl,
199
+ });
200
+ await nord.init();
201
+ return nord;
202
+ }
203
+ /**
204
+ * Initialize the Nord client
205
+ * @private
206
+ */
207
+ async init() {
208
+ await this.fetchNordInfo();
209
+ }
210
+ /**
211
+ * Query a specific action
212
+ *
213
+ * @param actionId - Action identifier to fetch
214
+ * @returns Action response
215
+ * @throws {NordError} If the request fails
216
+ */
217
+ async queryAction({ actionId, }) {
218
+ return ((await this.queryRecentActions({
219
+ from: actionId,
220
+ to: actionId,
221
+ }))[0] ?? null);
222
+ }
223
+ /**
224
+ * Query recent actions
225
+ *
226
+ * @param from - Starting action index (inclusive)
227
+ * @param to - Ending action index (inclusive)
228
+ * @returns Actions response
229
+ * @throws {NordError} If the request fails
230
+ */
231
+ async queryRecentActions({ from, to, }) {
232
+ const xs = await this.GET("/action", {
233
+ params: {
234
+ query: { from, to },
235
+ },
236
+ });
237
+ return xs.map((x) => ({
238
+ actionId: x.actionId,
239
+ action: utils.decodeLengthDelimited(Buffer.from(x.payload, "base64"), proto.ActionSchema),
240
+ physicalExecTime: new Date(x.physicalTime),
241
+ }));
242
+ }
243
+ /**
244
+ * Get the last action ID
245
+ *
246
+ * @returns Last action ID
247
+ * @throws {NordError} If the request fails
248
+ */
249
+ async getLastActionId() {
250
+ return await this.GET("/action/last-executed-id", {});
251
+ }
252
+ /**
253
+ * Subscribe to orderbook updates for a market
254
+ *
255
+ * @param symbol - Market symbol
256
+ * @returns Orderbook subscription
257
+ * @throws {NordError} If symbol is invalid
258
+ */
259
+ subscribeOrderbook(symbol) {
260
+ if (!symbol || typeof symbol !== "string") {
261
+ throw new NordError("Invalid market symbol");
262
+ }
263
+ const subscription = new EventEmitter();
264
+ const wsClient = this.createWebSocketClient({
265
+ deltas: [symbol],
266
+ });
267
+ const handleDelta = (update) => {
268
+ if (update.market_symbol !== symbol) {
269
+ return;
270
+ }
271
+ subscription.emit("message", update);
272
+ };
273
+ wsClient.on("delta", handleDelta);
274
+ subscription.close = () => {
275
+ wsClient.removeListener("delta", handleDelta);
276
+ subscription.removeAllListeners();
277
+ };
278
+ return subscription;
279
+ }
280
+ /**
281
+ * Subscribe to trade updates for a market
282
+ *
283
+ * @param symbol - Market symbol
284
+ * @returns Trade subscription
285
+ * @throws {NordError} If symbol is invalid
286
+ */
287
+ subscribeTrades(symbol) {
288
+ if (!symbol || typeof symbol !== "string") {
289
+ throw new NordError("Invalid market symbol");
290
+ }
291
+ const subscription = new EventEmitter();
292
+ const wsClient = this.createWebSocketClient({
293
+ trades: [symbol],
294
+ });
295
+ const handleTrade = (update) => {
296
+ if (update.market_symbol !== symbol) {
297
+ return;
298
+ }
299
+ subscription.emit("message", update);
300
+ };
301
+ wsClient.on("trades", handleTrade);
302
+ subscription.close = () => {
303
+ wsClient.removeListener("trades", handleTrade);
304
+ subscription.removeAllListeners();
305
+ };
306
+ return subscription;
307
+ }
308
+ /**
309
+ * Subscribe to account updates
310
+ *
311
+ * @param accountId - Account ID to subscribe to
312
+ * @returns User subscription
313
+ * @throws {NordError} If accountId is invalid
314
+ */
315
+ subscribeAccount(accountId) {
316
+ if (isNaN(accountId) || accountId <= 0) {
317
+ throw new NordError("Invalid account ID");
318
+ }
319
+ const subscription = new EventEmitter();
320
+ const wsClient = this.createWebSocketClient({
321
+ accounts: [accountId],
322
+ });
323
+ const handleAccountUpdate = (update) => {
324
+ if (update.account_id !== accountId) {
325
+ return;
326
+ }
327
+ subscription.emit("message", update);
328
+ };
329
+ wsClient.on("account", handleAccountUpdate);
330
+ subscription.close = () => {
331
+ wsClient.removeListener("account", handleAccountUpdate);
332
+ subscription.removeAllListeners();
333
+ };
334
+ return subscription;
335
+ }
336
+ /**
337
+ * Get trades for a market
338
+ *
339
+ * @param marketId - Market identifier to filter by
340
+ * @param takerId - Taker account identifier
341
+ * @param makerId - Maker account identifier
342
+ * @param takerSide - Side executed by the taker
343
+ * @param pageSize - Maximum number of trades to return
344
+ * @param since - RFC3339 timestamp to start from (inclusive)
345
+ * @param until - RFC3339 timestamp to end at (exclusive)
346
+ * @param pageId - Pagination cursor returned from a prior call
347
+ * @returns Trades response
348
+ * @throws {NordError} If the request fails
349
+ */
350
+ async getTrades({ marketId, takerId, makerId, takerSide, pageSize, since, until, startInclusive, }) {
351
+ if (since && !utils.isRfc3339(since)) {
352
+ throw new NordError(`Invalid RFC3339 timestamp: ${since}`);
353
+ }
354
+ if (until && !utils.isRfc3339(until)) {
355
+ throw new NordError(`Invalid RFC3339 timestamp: ${until}`);
356
+ }
357
+ return await this.GET("/trades", {
358
+ params: {
359
+ query: {
360
+ takerId,
361
+ makerId,
362
+ marketId,
363
+ pageSize,
364
+ takerSide,
365
+ since,
366
+ until,
367
+ startInclusive,
368
+ },
369
+ },
370
+ });
371
+ }
372
+ /**
373
+ * Get user account IDs
374
+ *
375
+ * @param pubkey - User public key to query
376
+ * @returns User account IDs response
377
+ * @throws {NordError} If the request fails
378
+ */
379
+ async getUser({ pubkey, }) {
380
+ const r = await this.httpClient.GET("/user/{pubkey}", {
381
+ params: {
382
+ path: { pubkey: pubkey.toString() },
383
+ },
384
+ });
385
+ if (r.response.status === 404) {
386
+ return null;
387
+ }
388
+ return r.data;
389
+ }
390
+ /**
391
+ * Get orderbook for a market
392
+ *
393
+ * @param symbol - Market symbol to resolve into an id
394
+ * @param marketId - Market identifier
395
+ * @returns Orderbook response
396
+ * @throws {NordError} If the request fails or if the market symbol is unknown
397
+ * @remarks It's recommended to initialize the Nord client using the static `initNord` method
398
+ * to ensure market information is properly loaded before calling this method.
399
+ */
400
+ async getOrderbook({ symbol, marketId, }) {
401
+ // If only symbol is provided, convert it to market_id
402
+ let _marketId;
403
+ if (symbol && marketId === undefined) {
404
+ // If the map is empty, try to fetch market information first
405
+ if (this.symbolToMarketId.size === 0) {
406
+ await this.fetchNordInfo();
407
+ }
408
+ const id = this.symbolToMarketId.get(symbol);
409
+ if (id === undefined) {
410
+ throw new NordError(`Unknown market symbol: ${symbol}`);
411
+ }
412
+ _marketId = id;
413
+ }
414
+ else if (marketId !== undefined) {
415
+ _marketId = marketId;
416
+ }
417
+ else {
418
+ throw new NordError("Either symbol or market_id must be provided for orderbook query");
419
+ }
420
+ return await this.GET("/market/{market_id}/orderbook", {
421
+ params: {
422
+ path: { market_id: _marketId },
423
+ },
424
+ });
425
+ }
426
+ /**
427
+ * Get information about the Nord server
428
+ *
429
+ * @returns Information about markets and tokens
430
+ * @throws {NordError} If the request fails
431
+ */
432
+ async getInfo() {
433
+ return await this.GET("/info", {});
434
+ }
435
+ /**
436
+ * Fetch the current fee tier brackets configured on Nord.
437
+ *
438
+ * @returns Array of fee tier identifiers paired with their configuration
439
+ * @throws {NordError} If the request fails
440
+ */
441
+ async getFeeBrackets() {
442
+ return await this.GET("/fee/brackets/info", {});
443
+ }
444
+ /**
445
+ * Retrieve the fee tier assigned to a specific account.
446
+ *
447
+ * @param accountId - Account identifier to query
448
+ * @returns Fee tier details for the requested account
449
+ * @throws {NordError} If the request fails
450
+ */
451
+ async getAccountFeeTier(accountId) {
452
+ return await this.GET("/account/{account_id}/fee/tier", {
453
+ params: {
454
+ path: { account_id: accountId },
455
+ },
456
+ });
457
+ }
458
+ /**
459
+ * Get account information
460
+ *
461
+ * @param accountId - Account ID to get information for
462
+ * @returns Account information
463
+ * @throws {NordError} If the request fails
464
+ */
465
+ async getAccount(accountId) {
466
+ return await this.GET("/account/{account_id}", {
467
+ params: {
468
+ path: { account_id: accountId },
469
+ },
470
+ });
471
+ }
472
+ /**
473
+ * Get the public key associated with an account id.
474
+ *
475
+ * @param accountId - Account id to query
476
+ * @returns Base58-encoded account public key
477
+ * @throws {NordError} If the request fails
478
+ */
479
+ async getAccountPubkey(accountId) {
480
+ return await this.GET("/account/{account_id}/pubkey", {
481
+ params: {
482
+ path: { account_id: accountId },
483
+ },
484
+ });
485
+ }
486
+ /**
487
+ * Get the withdrawal fee charged for an account.
488
+ *
489
+ * @param accountId - Account id to query
490
+ * @returns Withdrawal fee quoted in quote token units
491
+ * @throws {NordError} If the request fails
492
+ */
493
+ async getAccountWithdrawalFee(accountId) {
494
+ return await this.GET("/account/{account_id}/fees/withdrawal", {
495
+ params: {
496
+ path: { account_id: accountId },
497
+ },
498
+ });
499
+ }
500
+ /**
501
+ * Get open orders for an account.
502
+ *
503
+ * @param accountId - Account id to query
504
+ * @param startInclusive - Pagination cursor (client order id) to resume from
505
+ * @param pageSize - Maximum number of orders to return
506
+ * @returns Page of orders keyed by client order id
507
+ * @throws {NordError} If the request fails
508
+ */
509
+ async getAccountOrders(accountId, { startInclusive, pageSize, } = {}) {
510
+ return await this.GET("/account/{account_id}/orders", {
511
+ params: {
512
+ path: { account_id: accountId },
513
+ query: {
514
+ startInclusive,
515
+ pageSize,
516
+ },
517
+ },
518
+ });
519
+ }
520
+ /**
521
+ * List account fee tiers with pagination support.
522
+ *
523
+ * @param startInclusive - Account id cursor to resume from
524
+ * @param pageSize - Maximum number of entries to return
525
+ */
526
+ async getAccountsFeeTiers({ startInclusive, pageSize, } = {}) {
527
+ return await this.GET("/accounts/fee-tiers", {
528
+ params: {
529
+ query: {
530
+ startInclusive: startInclusive ?? undefined,
531
+ pageSize: pageSize ?? undefined,
532
+ },
533
+ },
534
+ });
535
+ }
536
+ /**
537
+ * Get profit and loss history for an account
538
+ *
539
+ * @param accountId - Account ID to query
540
+ * @param since - RFC3339 timestamp to start from (inclusive)
541
+ * @param until - RFC3339 timestamp to end at (exclusive)
542
+ * @param startInclusive - Pagination cursor to resume from
543
+ * @param pageSize - Maximum number of entries to return
544
+ * @returns Page of PnL entries ordered from latest to oldest
545
+ * @throws {NordError} If the request fails
546
+ */
547
+ async getAccountPnl(accountId, { since, until, startInclusive, pageSize, } = {}) {
548
+ return await this.GET("/account/{account_id}/pnl", {
549
+ params: {
550
+ path: { account_id: accountId },
551
+ query: {
552
+ since,
553
+ until,
554
+ startInclusive,
555
+ pageSize,
556
+ },
557
+ },
558
+ });
559
+ }
560
+ /**
561
+ * Get market statistics (alias for marketsStats for backward compatibility)
562
+ *
563
+ *
564
+ * @param marketId - Market identifier
565
+ *
566
+ * @returns Market statistics response
567
+ */
568
+ async getMarketStats({ marketId, }) {
569
+ return await this.GET("/market/{market_id}/stats", {
570
+ params: {
571
+ path: { market_id: marketId },
572
+ },
573
+ });
574
+ }
575
+ /**
576
+ * Fetch the per-market fee quote for an account.
577
+ *
578
+ * @param marketId - Market identifier
579
+ * @param feeKind - Fill role (maker/taker) to quote
580
+ * @param accountId - Account identifier to quote
581
+ * @returns Fee in quote token units (negative means fee is charged)
582
+ * @throws {NordError} If the request fails
583
+ */
584
+ async getMarketFee({ marketId, feeKind, accountId, }) {
585
+ return await this.GET("/market/{market_id}/fees/{fee_kind}/{account_id}", {
586
+ params: {
587
+ path: {
588
+ market_id: marketId,
589
+ fee_kind: feeKind,
590
+ account_id: accountId,
591
+ },
592
+ },
593
+ });
594
+ }
595
+ /**
596
+ * Fetch the latest available market price at or before the given timestamp.
597
+ *
598
+ * @param marketId - Market identifier
599
+ * @param atOrBefore - RFC3339 timestamp to look back from (returns the latest price at or before this time)
600
+ * @returns Previous market price record; price is `null` if no trades exist at or before `at`
601
+ * @throws {NordError} If the request fails
602
+ */
603
+ async getPrevMarketPrice({ marketId, atOrBefore, }) {
604
+ return await this.GET("/market/{market_id}/price/prev", {
605
+ params: {
606
+ path: { market_id: marketId },
607
+ query: {
608
+ atOrBefore,
609
+ },
610
+ },
611
+ });
612
+ }
613
+ /**
614
+ * Fetch token statistics such as index price and oracle metadata.
615
+ *
616
+ * @param tokenId - Token identifier
617
+ * @returns Token stats
618
+ * @throws {NordError} If the request fails
619
+ */
620
+ async getTokenStats(tokenId) {
621
+ return await this.GET("/tokens/{token_id}/stats", {
622
+ params: {
623
+ path: { token_id: tokenId },
624
+ },
625
+ });
626
+ }
627
+ /**
628
+ * Get order summary by order id.
629
+ *
630
+ * @param orderId - Order identifier
631
+ * @returns Order information
632
+ * @throws {NordError} If the request fails
633
+ */
634
+ async getOrder(orderId) {
635
+ return await this.GET("/order/{order_id}", {
636
+ params: {
637
+ path: { order_id: orderId },
638
+ },
639
+ });
640
+ }
641
+ /**
642
+ * Get trade history for a specific order.
643
+ *
644
+ * @param orderId - Order identifier
645
+ * @param startInclusive - Trade pagination cursor
646
+ * @param pageSize - Maximum number of trades to return
647
+ * @returns Page of trades associated with the order
648
+ * @throws {NordError} If the request fails
649
+ */
650
+ async getOrderTrades(orderId, { startInclusive, pageSize, } = {}) {
651
+ return await this.GET("/order/{order_id}/trades", {
652
+ params: {
653
+ path: { order_id: orderId },
654
+ query: {
655
+ startInclusive,
656
+ pageSize,
657
+ },
658
+ },
659
+ });
660
+ }
661
+ /**
662
+ * Check if an account exists for the given address
663
+ *
664
+ * @param address - The public key address to check
665
+ * @returns True if the account exists, false otherwise
666
+ * @deprecated use getUser instead
667
+ */
668
+ async accountExists(pubkey) {
669
+ return !!(await this.getUser({ pubkey }));
670
+ }
671
+ /**
672
+ * Fetch active triggers for an account.
673
+ *
674
+ * @param accountId - Account identifier owning the triggers
675
+ * @throws {NordError} If no account can be resolved or the request fails.
676
+ */
677
+ async getAccountTriggers({ accountId, } = {}) {
678
+ if (accountId == null) {
679
+ throw new NordError("Account ID is undefined. Make sure to call updateAccountId() before requesting triggers.");
680
+ }
681
+ try {
682
+ const triggers = await this.GET("/account/{account_id}/triggers", {
683
+ params: {
684
+ path: { account_id: accountId },
685
+ },
686
+ });
687
+ return triggers ?? [];
688
+ }
689
+ catch (error) {
690
+ throw new NordError("Failed to fetch account triggers", { cause: error });
691
+ }
692
+ }
693
+ /**
694
+ * Fetch trigger history for an account.
695
+ *
696
+ * @param accountId - Account identifier owning the triggers
697
+ * @param since - RFC3339 timestamp to start from (inclusive)
698
+ * @param until - RFC3339 timestamp to end at (exclusive)
699
+ * @param pageSize - Maximum number of entries to return
700
+ * @param startInclusive - Pagination cursor to resume from
701
+ * @throws {NordError} If no account can be resolved or the request fails.
702
+ */
703
+ async getAccountTriggerHistory({ accountId, since, until, pageSize, startInclusive, }) {
704
+ if (accountId == null) {
705
+ throw new NordError("Account ID is undefined. Make sure to call updateAccountId() before requesting trigger history.");
706
+ }
707
+ try {
708
+ return await this.GET("/account/{account_id}/triggers/history", {
709
+ params: {
710
+ path: { account_id: accountId },
711
+ query: {
712
+ since,
713
+ until,
714
+ pageSize,
715
+ startInclusive,
716
+ },
717
+ },
718
+ });
719
+ }
720
+ catch (error) {
721
+ throw new NordError("Failed to fetch account trigger history", {
722
+ cause: error,
723
+ });
724
+ }
725
+ }
726
+ /**
727
+ * Fetch withdrawal history for an account.
728
+ *
729
+ * @param accountId - Account identifier owning the withdrawals
730
+ * @param since - RFC3339 timestamp to start from (inclusive)
731
+ * @param until - RFC3339 timestamp to end at (exclusive)
732
+ * @param pageSize - Maximum number of entries to return
733
+ * @param startInclusive - Pagination cursor to resume from
734
+ * @throws {NordError} If no account can be resolved or the request fails.
735
+ */
736
+ async getAccountWithdrawalHistory({ accountId, since, until, pageSize, startInclusive, }) {
737
+ if (accountId == null) {
738
+ throw new NordError("Account ID is undefined. Make sure to call updateAccountId() before requesting withdrawal history.");
739
+ }
740
+ try {
741
+ return await this.GET("/account/{account_id}/history/withdrawal", {
742
+ params: {
743
+ path: { account_id: accountId },
744
+ query: {
745
+ since,
746
+ until,
747
+ pageSize,
748
+ startInclusive,
749
+ },
750
+ },
751
+ });
752
+ }
753
+ catch (error) {
754
+ throw new NordError("Failed to fetch account withdrawal history", {
755
+ cause: error,
756
+ });
757
+ }
758
+ }
759
+ }