@n1xyz/nord-ts 0.0.17 → 0.0.18

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 (48) hide show
  1. package/.local/qa.ts +77 -0
  2. package/.local/test-atomic.ts +112 -0
  3. package/check.sh +4 -0
  4. package/default.nix +47 -0
  5. package/dist/api/client.d.ts +14 -0
  6. package/dist/api/client.js +45 -0
  7. package/dist/gen/nord.d.ts +52 -23
  8. package/dist/gen/nord.js +322 -170
  9. package/dist/gen/openapi.d.ts +2244 -0
  10. package/dist/gen/openapi.js +6 -0
  11. package/dist/index.d.ts +0 -1
  12. package/dist/index.js +0 -9
  13. package/dist/nord/api/actions.d.ts +30 -1
  14. package/dist/nord/api/actions.js +60 -3
  15. package/dist/nord/api/core.d.ts +1 -34
  16. package/dist/nord/api/core.js +0 -71
  17. package/dist/nord/client/Nord.d.ts +31 -33
  18. package/dist/nord/client/Nord.js +100 -60
  19. package/dist/nord/client/NordUser.d.ts +64 -11
  20. package/dist/nord/client/NordUser.js +91 -33
  21. package/dist/nord/index.d.ts +0 -2
  22. package/dist/nord/index.js +0 -2
  23. package/dist/nord/models/Subscriber.d.ts +2 -2
  24. package/dist/types.d.ts +43 -190
  25. package/dist/utils.d.ts +1 -28
  26. package/dist/utils.js +5 -58
  27. package/dist/websocket/NordWebSocketClient.js +18 -13
  28. package/dist/websocket/index.d.ts +1 -1
  29. package/package.json +23 -31
  30. package/src/index.ts +0 -16
  31. package/src/nord/api/actions.ts +131 -9
  32. package/src/nord/api/core.ts +0 -71
  33. package/src/nord/client/Nord.ts +142 -76
  34. package/src/nord/client/NordUser.ts +171 -51
  35. package/src/nord/index.ts +0 -2
  36. package/src/nord/models/Subscriber.ts +2 -2
  37. package/src/types.ts +55 -216
  38. package/src/utils.ts +6 -63
  39. package/src/websocket/NordWebSocketClient.ts +23 -15
  40. package/src/websocket/index.ts +1 -1
  41. package/tests/utils.spec.ts +1 -34
  42. package/dist/idl/bridge.json +0 -1506
  43. package/jest.config.ts +0 -9
  44. package/nodemon.json +0 -4
  45. package/protoc-generate.sh +0 -23
  46. package/src/idl/bridge.json +0 -1506
  47. package/src/nord/api/market.ts +0 -122
  48. package/src/nord/api/queries.ts +0 -135
@@ -3,15 +3,12 @@ import * as proto from "../../gen/nord";
3
3
  import { FillMode, fillModeToProtoFillMode, KeyType, Side } from "../../types";
4
4
  import {
5
5
  assert,
6
- bigIntToProtoU128,
7
6
  BigIntValue,
8
7
  checkedFetch,
9
8
  checkPubKeyLength,
10
9
  decodeLengthDelimited,
11
10
  encodeLengthDelimited,
12
- optMap,
13
11
  SESSION_TTL,
14
- toScaledU128,
15
12
  toScaledU64,
16
13
  } from "../../utils";
17
14
 
@@ -35,6 +32,7 @@ function makeSendHttp(
35
32
  serverUrl: string,
36
33
  ): (encoded: Uint8Array) => Promise<Uint8Array> {
37
34
  return async (body) => {
35
+ // TODO: this should be changed to use openapi
38
36
  const response = await checkedFetch(`${serverUrl}/action`, {
39
37
  method: "POST",
40
38
  headers: {
@@ -271,15 +269,17 @@ async function placeOrderImpl(
271
269
  // NOTE: if `size` equals 1.0, it will sell whole unit, for example 1.0 BTC
272
270
  size?: Decimal.Value;
273
271
  price?: Decimal.Value;
274
- quoteSize?: Decimal.Value;
272
+ quoteSizeSize?: Decimal.Value;
273
+ quoteSizePrice?: Decimal.Value;
275
274
  clientOrderId?: BigIntValue;
276
275
  },
277
276
  ): Promise<bigint | undefined> {
278
277
  const price = toScaledU64(params.price ?? 0, params.priceDecimals);
279
278
  const size = toScaledU64(params.size ?? 0, params.sizeDecimals);
280
- const quoteSize = toScaledU128(
281
- params.quoteSize ?? 0,
282
- params.priceDecimals + params.sizeDecimals,
279
+ const quoteSize = toScaledU64(params.quoteSizeSize ?? 0, params.sizeDecimals);
280
+ const quotePrice = toScaledU64(
281
+ params.quoteSizePrice ?? 0,
282
+ params.priceDecimals,
283
283
  );
284
284
 
285
285
  // Compose action object
@@ -297,8 +297,11 @@ async function placeOrderImpl(
297
297
  isReduceOnly: params.isReduceOnly,
298
298
  price,
299
299
  size,
300
- quoteSize: bigIntToProtoU128(quoteSize),
301
- clientOrderId: optMap(params.clientOrderId, (x) => BigInt(x)),
300
+ quoteSize: { size: quoteSize, price: quotePrice },
301
+ clientOrderId:
302
+ params.clientOrderId === undefined
303
+ ? undefined
304
+ : BigInt(params.clientOrderId),
302
305
  delegatorAccountId: params.liquidateeId,
303
306
  },
304
307
  },
@@ -478,6 +481,124 @@ export async function transfer(
478
481
  params,
479
482
  );
480
483
  }
484
+
485
+ export type AtomicSubaction =
486
+ | {
487
+ kind: "place";
488
+ // Market and order parameters – identical semantics to placeOrder()
489
+ marketId: number;
490
+ side: Side;
491
+ fillMode: FillMode;
492
+ isReduceOnly: boolean;
493
+ // decimals for scaling
494
+ sizeDecimals: number;
495
+ priceDecimals: number;
496
+ // at least one of the three has to be specified; 0 treated as "not set"
497
+ size?: Decimal.Value;
498
+ price?: Decimal.Value;
499
+ quoteSizeSize?: Decimal.Value;
500
+ quoteSizePrice?: Decimal.Value;
501
+ clientOrderId?: BigIntValue;
502
+ }
503
+ | {
504
+ kind: "cancel";
505
+ orderId: BigIntValue;
506
+ };
507
+
508
+ async function atomicImpl(
509
+ sendFn: (encoded: Uint8Array) => Promise<Uint8Array>,
510
+ signFn: (message: Uint8Array) => Promise<Uint8Array>,
511
+ currentTimestamp: bigint,
512
+ nonce: number,
513
+ params: {
514
+ sessionId: BigIntValue;
515
+ accountId?: number;
516
+ actions: AtomicSubaction[];
517
+ },
518
+ ): Promise<proto.Receipt_AtomicResult> {
519
+ assert(
520
+ params.actions.length > 0 && params.actions.length <= 4,
521
+ "Atomic action must contain between 1 and 4 sub-actions",
522
+ );
523
+
524
+ const subactions: proto.AtomicSubactionKind[] = params.actions.map((a) => {
525
+ if (a.kind === "place") {
526
+ const price = toScaledU64(a.price ?? 0, a.priceDecimals);
527
+ const size = toScaledU64(a.size ?? 0, a.sizeDecimals);
528
+ const quoteSizeSize = toScaledU64(a.quoteSizeSize ?? 0, a.sizeDecimals);
529
+ const quoteSizePrice = toScaledU64(
530
+ a.quoteSizePrice ?? 0,
531
+ a.priceDecimals,
532
+ );
533
+ const tradeOrPlace: proto.TradeOrPlace = {
534
+ marketId: a.marketId,
535
+ orderType: {
536
+ side: a.side === Side.Bid ? proto.Side.BID : proto.Side.ASK,
537
+ fillMode: fillModeToProtoFillMode(a.fillMode),
538
+ isReduceOnly: a.isReduceOnly,
539
+ },
540
+ limit: {
541
+ price,
542
+ size,
543
+ quoteSize: { size: quoteSizeSize, price: quoteSizePrice },
544
+ },
545
+ clientOrderId:
546
+ a.clientOrderId === undefined ? undefined : BigInt(a.clientOrderId),
547
+ };
548
+ return {
549
+ inner: { $case: "tradeOrPlace", value: tradeOrPlace },
550
+ } as proto.AtomicSubactionKind;
551
+ }
552
+ return {
553
+ inner: { $case: "cancelOrder", value: { orderId: BigInt(a.orderId) } },
554
+ } as proto.AtomicSubactionKind;
555
+ });
556
+
557
+ const action: proto.Action = {
558
+ currentTimestamp,
559
+ nonce,
560
+ kind: {
561
+ $case: "atomic",
562
+ value: {
563
+ sessionId: BigInt(params.sessionId),
564
+ accountId: params.accountId, // optional
565
+ actions: subactions,
566
+ },
567
+ },
568
+ };
569
+
570
+ const resp = await sendAction(
571
+ sendFn,
572
+ (m) => sessionSign(signFn, m),
573
+ action,
574
+ "execute atomic action",
575
+ );
576
+ if (resp.kind?.$case === "atomic") {
577
+ return resp.kind.value;
578
+ }
579
+ throw new Error(`Unexpected receipt kind ${resp.kind?.$case}`);
580
+ }
581
+
582
+ export async function atomic(
583
+ serverUrl: string,
584
+ signFn: (message: Uint8Array) => Promise<Uint8Array>,
585
+ currentTimestamp: bigint,
586
+ nonce: number,
587
+ params: {
588
+ sessionId: BigIntValue;
589
+ accountId?: number;
590
+ actions: AtomicSubaction[];
591
+ },
592
+ ): Promise<proto.Receipt_AtomicResult> {
593
+ return atomicImpl(
594
+ makeSendHttp(serverUrl),
595
+ signFn,
596
+ currentTimestamp,
597
+ nonce,
598
+ params,
599
+ );
600
+ }
601
+
481
602
  /**
482
603
  * For testing purposes
483
604
  */
@@ -488,4 +609,5 @@ export const _private = {
488
609
  placeOrderImpl,
489
610
  cancelOrderImpl,
490
611
  transferImpl,
612
+ atomicImpl,
491
613
  };
@@ -3,77 +3,6 @@ import { checkedFetch } from "../../utils";
3
3
  import { NordWebSocketClient } from "../../websocket/index";
4
4
  import { NordError } from "../utils/NordError";
5
5
 
6
- /**
7
- * Get the current timestamp from the Nord server
8
- *
9
- * @param webServerUrl - Base URL for the Nord web server
10
- * @returns Current timestamp as a bigint
11
- * @throws {NordError} If the request fails
12
- */
13
- export async function getTimestamp(webServerUrl: string): Promise<bigint> {
14
- try {
15
- const response = await checkedFetch(`${webServerUrl}/timestamp`);
16
- return BigInt(await response.json());
17
- } catch (error) {
18
- throw new NordError("Failed to get timestamp", { cause: error });
19
- }
20
- }
21
-
22
- /**
23
- * Get the next action nonce from the Nord server
24
- *
25
- * @param webServerUrl - Base URL for the Nord web server
26
- * @returns Next action nonce
27
- * @throws {NordError} If the request fails
28
- */
29
- export async function getLastEventNonce(webServerUrl: string): Promise<number> {
30
- try {
31
- const response = await checkedFetch(
32
- `${webServerUrl}/event/last-acked-nonce`,
33
- );
34
- const data = await response.json();
35
- return data.nonce;
36
- } catch (error) {
37
- throw new NordError("Failed to get action nonce", { cause: error });
38
- }
39
- }
40
-
41
- /**
42
- * Get information about the Nord server
43
- *
44
- * @param webServerUrl - Base URL for the Nord web server
45
- * @returns Information about markets and tokens
46
- * @throws {NordError} If the request fails
47
- */
48
- export async function getInfo(webServerUrl: string): Promise<Info> {
49
- try {
50
- const response = await checkedFetch(`${webServerUrl}/info`);
51
- return await response.json();
52
- } catch (error) {
53
- throw new NordError("Failed to get info", { cause: error });
54
- }
55
- }
56
-
57
- /**
58
- * Get account information
59
- *
60
- * @param webServerUrl - Base URL for the Nord web server
61
- * @param accountId - Account ID to get information for
62
- * @returns Account information
63
- * @throws {NordError} If the request fails
64
- */
65
- export async function getAccount(
66
- webServerUrl: string,
67
- accountId: number,
68
- ): Promise<Account> {
69
- try {
70
- const response = await checkedFetch(`${webServerUrl}/account/${accountId}`);
71
- return await response.json();
72
- } catch (error) {
73
- throw new NordError(`Failed to get account ${accountId}`, { cause: error });
74
- }
75
- }
76
-
77
6
  /**
78
7
  * Initialize a WebSocket client for Nord
79
8
  *
@@ -1,35 +1,32 @@
1
1
  import { EventEmitter } from "events";
2
+ import { PublicKey, Connection } from "@solana/web3.js";
3
+ import createClient, { Client, FetchOptions } from "openapi-fetch";
2
4
  import {
5
+ Info,
3
6
  Account,
4
- ActionQuery,
5
7
  ActionResponse,
6
- ActionsResponse,
7
8
  AggregateMetrics,
8
- Info,
9
9
  Market,
10
- MarketsStatsResponse,
11
10
  NordConfig,
12
11
  OrderbookQuery,
13
12
  OrderbookResponse,
14
13
  PeakTpsPeriodUnit,
15
- RollmanActionResponse,
16
- RollmanActionsResponse,
17
14
  SubscriptionPattern,
18
15
  Token,
19
- TradesQuery,
20
16
  TradesResponse,
21
- UserAccountIdsQuery,
22
- UserAccountIdsResponse,
17
+ User,
18
+ MarketStats,
23
19
  } from "../../types";
24
20
  import { ProtonClient } from "@n1xyz/proton";
21
+ import * as proto from "../../gen/nord";
22
+ // import { base64 } from "@scure/base";
25
23
  import { NordWebSocketClient } from "../../websocket/index";
26
24
  import * as core from "../api/core";
27
- import * as market from "../api/market";
28
25
  import * as metrics from "../api/metrics";
29
- import * as queries from "../api/queries";
26
+ import * as utils from "../../utils";
30
27
  import { OrderbookSubscription, TradeSubscription } from "../models/Subscriber";
31
28
  import { NordError } from "../utils/NordError";
32
- import { PublicKey, Connection } from "@solana/web3.js";
29
+ import type { paths } from "../../gen/openapi.ts";
33
30
 
34
31
  /**
35
32
  * User subscription interface
@@ -72,9 +69,12 @@ export class Nord {
72
69
  /** Map of symbol to market_id */
73
70
  private symbolToMarketId: Map<string, number> = new Map();
74
71
 
75
- /** Proton client for bridge and indexd operations */
72
+ /** Proton client for bridge and hansel operations */
76
73
  public protonClient: ProtonClient;
77
74
 
75
+ /** HTTP client for Nord operations */
76
+ private httpClient: Client<paths>;
77
+
78
78
  /**
79
79
  * Create a new Nord client
80
80
  *
@@ -99,6 +99,7 @@ export class Nord {
99
99
  this.bridgeVk = bridgeVk;
100
100
  this.solanaUrl = solanaUrl;
101
101
  this.protonClient = protonClient;
102
+ this.httpClient = createClient<paths>({ baseUrl: webServerUrl });
102
103
  }
103
104
 
104
105
  /**
@@ -162,6 +163,22 @@ export class Nord {
162
163
  return core.initWebSocketClient(this.webServerUrl, subscriptions);
163
164
  }
164
165
 
166
+ private async GET<P extends keyof paths & string>(
167
+ path: P,
168
+ options: FetchOptions<paths[P]["get"]>,
169
+ ) {
170
+ const r = await this.httpClient.GET(path, options);
171
+ if (r.error) {
172
+ throw new NordError(`failed to GET ${path}`, { cause: r.error });
173
+ }
174
+ if (r.data === undefined) {
175
+ // this should never happen, but the type checker seems unhappy.
176
+ // if we catch this we'll need to debug accordingly.
177
+ throw new NordError("internal assertion violation", { cause: r });
178
+ }
179
+ return r.data;
180
+ }
181
+
165
182
  /**
166
183
  * Get the current timestamp from the Nord server
167
184
  *
@@ -169,7 +186,7 @@ export class Nord {
169
186
  * @throws {NordError} If the request fails
170
187
  */
171
188
  async getTimestamp(): Promise<bigint> {
172
- return core.getTimestamp(this.webServerUrl);
189
+ return BigInt(await this.GET("/timestamp", {}));
173
190
  }
174
191
 
175
192
  /**
@@ -179,7 +196,7 @@ export class Nord {
179
196
  * @throws {NordError} If the request fails
180
197
  */
181
198
  async getActionNonce(): Promise<number> {
182
- return core.getLastEventNonce(this.webServerUrl);
199
+ return await this.GET("/event/last-acked-nonce", {});
183
200
  }
184
201
 
185
202
  /**
@@ -189,7 +206,7 @@ export class Nord {
189
206
  */
190
207
  async fetchNordInfo(): Promise<void> {
191
208
  try {
192
- const info = await core.getInfo(this.webServerUrl);
209
+ const info = await this.GET("/info", {});
193
210
  this.markets = info.markets;
194
211
  this.tokens = info.tokens;
195
212
 
@@ -246,16 +263,6 @@ export class Nord {
246
263
  await this.fetchNordInfo();
247
264
  }
248
265
 
249
- /**
250
- * Get market statistics
251
- *
252
- * @returns Market statistics response
253
- * @throws {NordError} If the request fails
254
- */
255
- public async marketsStats(): Promise<MarketsStatsResponse> {
256
- return market.marketsStats(this.webServerUrl);
257
- }
258
-
259
266
  /**
260
267
  * Query a specific action
261
268
  *
@@ -263,8 +270,19 @@ export class Nord {
263
270
  * @returns Action response
264
271
  * @throws {NordError} If the request fails
265
272
  */
266
- async queryAction(query: ActionQuery): Promise<ActionResponse> {
267
- return queries.queryAction(this.webServerUrl, query);
273
+ async queryAction({
274
+ action_id,
275
+ }: {
276
+ action_id: number;
277
+ }): Promise<ActionResponse | null> {
278
+ return (
279
+ (
280
+ await this.queryRecentActions({
281
+ from: action_id,
282
+ to: action_id,
283
+ })
284
+ )[0] ?? null
285
+ );
268
286
  }
269
287
 
270
288
  /**
@@ -275,8 +293,23 @@ export class Nord {
275
293
  * @returns Actions response
276
294
  * @throws {NordError} If the request fails
277
295
  */
278
- async queryRecentActions(from: number, to: number): Promise<ActionsResponse> {
279
- return queries.queryRecentActions(this.webServerUrl, from, to);
296
+ async queryRecentActions(query: {
297
+ from: number;
298
+ to: number;
299
+ }): Promise<ActionResponse[]> {
300
+ const xs = await this.GET("/action", {
301
+ params: {
302
+ query,
303
+ },
304
+ });
305
+ return xs.map((x) => ({
306
+ actionId: x.actionId,
307
+ action: utils.decodeLengthDelimited(
308
+ Buffer.from(x.payload, "base64"),
309
+ proto.Action,
310
+ ),
311
+ physicalExecTime: new Date(x.physicalTime * 1000),
312
+ }));
280
313
  }
281
314
 
282
315
  /**
@@ -286,7 +319,7 @@ export class Nord {
286
319
  * @throws {NordError} If the request fails
287
320
  */
288
321
  async getLastActionId(): Promise<number> {
289
- return queries.getLastActionId(this.webServerUrl);
322
+ return await this.GET("/action/last-executed-id", {});
290
323
  }
291
324
 
292
325
  /**
@@ -351,28 +384,6 @@ export class Nord {
351
384
  return metrics.getTotalTransactions(this.webServerUrl);
352
385
  }
353
386
 
354
- /**
355
- * Query an action from Rollman
356
- *
357
- * @param query - Action query parameters
358
- * @returns Rollman action response
359
- * @throws {NordError} If the request fails
360
- */
361
- async actionQueryRollman(query: ActionQuery): Promise<RollmanActionResponse> {
362
- return queries.actionQueryRollman(this.webServerUrl, query);
363
- }
364
-
365
- /**
366
- * Query actions from Rollman
367
- *
368
- * @param last_n - Number of recent actions to query
369
- * @returns Rollman actions response
370
- * @throws {NordError} If the request fails
371
- */
372
- async actionsQueryRollman(last_n: number): Promise<RollmanActionsResponse> {
373
- return queries.actionsQueryRollman(this.webServerUrl, last_n);
374
- }
375
-
376
387
  /**
377
388
  * Query Prometheus metrics
378
389
  *
@@ -511,8 +522,38 @@ export class Nord {
511
522
  * @returns Trades response
512
523
  * @throws {NordError} If the request fails
513
524
  */
514
- public async getTrades(query: TradesQuery): Promise<TradesResponse> {
515
- return market.getTrades(this.webServerUrl, query);
525
+ public async getTrades(
526
+ query: Readonly<{
527
+ marketId?: number;
528
+ takerId?: number;
529
+ makerId?: number;
530
+ takerSide?: "bid" | "ask";
531
+ pageSize?: number;
532
+ sinceRcf3339?: string;
533
+ untilRfc3339?: string;
534
+ pageId?: string;
535
+ }>,
536
+ ): Promise<TradesResponse> {
537
+ if (query.sinceRcf3339 && !utils.isRfc3339(query.sinceRcf3339)) {
538
+ throw new NordError(`Invalid RFC3339 timestamp: ${query.sinceRcf3339}`);
539
+ }
540
+ if (query.untilRfc3339 && !utils.isRfc3339(query.untilRfc3339)) {
541
+ throw new NordError(`Invalid RFC3339 timestamp: ${query.untilRfc3339}`);
542
+ }
543
+ return await this.GET("/trades", {
544
+ params: {
545
+ query: {
546
+ takerId: query.takerId,
547
+ makerId: query.makerId,
548
+ marketId: query.marketId,
549
+ pageSize: query.pageSize,
550
+ takerSide: query.takerSide,
551
+ since: query.sinceRcf3339,
552
+ until: query.untilRfc3339,
553
+ startInclusive: query.pageId,
554
+ },
555
+ },
556
+ });
516
557
  }
517
558
 
518
559
  /**
@@ -522,10 +563,18 @@ export class Nord {
522
563
  * @returns User account IDs response
523
564
  * @throws {NordError} If the request fails
524
565
  */
525
- public async getUserAccountIds(
526
- query: UserAccountIdsQuery,
527
- ): Promise<UserAccountIdsResponse> {
528
- return market.getUserAccountIds(this.webServerUrl, query);
566
+ public async getUser(query: {
567
+ pubkey: string | PublicKey;
568
+ }): Promise<User | null> {
569
+ const r = await this.httpClient.GET("/user/{pubkey}", {
570
+ params: {
571
+ path: { pubkey: query.pubkey.toString() },
572
+ },
573
+ });
574
+ if (r.response.status === 404) {
575
+ return null;
576
+ }
577
+ return r.data!;
529
578
  }
530
579
 
531
580
  /**
@@ -539,21 +588,31 @@ export class Nord {
539
588
  */
540
589
  public async getOrderbook(query: OrderbookQuery): Promise<OrderbookResponse> {
541
590
  // If only symbol is provided, convert it to market_id
591
+ let marketId: number;
542
592
  if (query.symbol && query.market_id === undefined) {
543
593
  // If the map is empty, try to fetch market information first
544
594
  if (this.symbolToMarketId.size === 0) {
545
595
  await this.fetchNordInfo();
546
596
  }
547
597
 
548
- const marketId = this.symbolToMarketId.get(query.symbol);
549
- if (marketId === undefined) {
598
+ const id = this.symbolToMarketId.get(query.symbol);
599
+ if (id === undefined) {
550
600
  throw new NordError(`Unknown market symbol: ${query.symbol}`);
551
601
  }
552
-
553
- query = { market_id: marketId };
602
+ marketId = id;
603
+ } else if (query.market_id !== undefined) {
604
+ marketId = query.market_id;
605
+ } else {
606
+ throw new NordError(
607
+ "Either symbol or market_id must be provided for orderbook query",
608
+ );
554
609
  }
555
610
 
556
- return market.getOrderbook(this.webServerUrl, query);
611
+ return await this.GET("/market/{market_id}/orderbook", {
612
+ params: {
613
+ path: { market_id: marketId },
614
+ },
615
+ });
557
616
  }
558
617
 
559
618
  /**
@@ -563,7 +622,7 @@ export class Nord {
563
622
  * @throws {NordError} If the request fails
564
623
  */
565
624
  public async getInfo(): Promise<Info> {
566
- return core.getInfo(this.webServerUrl);
625
+ return await this.GET("/info", {});
567
626
  }
568
627
 
569
628
  /**
@@ -574,17 +633,28 @@ export class Nord {
574
633
  * @throws {NordError} If the request fails
575
634
  */
576
635
  public async getAccount(accountId: number): Promise<Account> {
577
- return core.getAccount(this.webServerUrl, accountId);
636
+ return await this.GET("/account/{account_id}", {
637
+ params: {
638
+ path: { account_id: accountId },
639
+ },
640
+ });
578
641
  }
579
642
 
580
643
  /**
581
644
  * Get market statistics (alias for marketsStats for backward compatibility)
582
645
  *
583
- * @deprecated Use marketsStats instead
584
646
  * @returns Market statistics response
585
647
  */
586
- public async getMarketStats(): Promise<MarketsStatsResponse> {
587
- return this.marketsStats();
648
+ public async getMarketStats({
649
+ marketId,
650
+ }: {
651
+ marketId: number;
652
+ }): Promise<MarketStats> {
653
+ return await this.GET("/market/{market_id}/stats", {
654
+ params: {
655
+ path: { market_id: marketId },
656
+ },
657
+ });
588
658
  }
589
659
 
590
660
  /**
@@ -592,13 +662,9 @@ export class Nord {
592
662
  *
593
663
  * @param address - The public key address to check
594
664
  * @returns True if the account exists, false otherwise
665
+ * @deprecated use getUser instead
595
666
  */
596
- public async accountExists(address: string): Promise<boolean> {
597
- try {
598
- await market.getUserAccountIds(this.webServerUrl, { pubkey: address });
599
- return true;
600
- } catch {
601
- return false;
602
- }
667
+ public async accountExists(pubkey: string | PublicKey): Promise<boolean> {
668
+ return !!(await this.getUser({ pubkey }));
603
669
  }
604
670
  }