@n1xyz/nord-ts 0.1.7 → 0.1.9

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