@n1xyz/nord-ts 0.1.4 → 0.1.6

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.
@@ -362,6 +362,14 @@ export interface paths {
362
362
  "application/json": number;
363
363
  };
364
364
  };
365
+ 404: {
366
+ headers: {
367
+ [name: string]: unknown;
368
+ };
369
+ content: {
370
+ "application/json": components["schemas"]["UserNotFound"];
371
+ };
372
+ };
365
373
  };
366
374
  };
367
375
  put?: never;
@@ -1103,6 +1111,127 @@ export interface paths {
1103
1111
  patch?: never;
1104
1112
  trace?: never;
1105
1113
  };
1114
+ "/fee/brackets/info": {
1115
+ parameters: {
1116
+ query?: never;
1117
+ header?: never;
1118
+ path?: never;
1119
+ cookie?: never;
1120
+ };
1121
+ get: {
1122
+ parameters: {
1123
+ query?: never;
1124
+ header?: never;
1125
+ path?: never;
1126
+ cookie?: never;
1127
+ };
1128
+ requestBody?: never;
1129
+ responses: {
1130
+ 200: {
1131
+ headers: {
1132
+ [name: string]: unknown;
1133
+ };
1134
+ content: {
1135
+ "application/json": [
1136
+ components["schemas"]["FeeTierId"],
1137
+ components["schemas"]["FeeTierConfig"]
1138
+ ][];
1139
+ };
1140
+ };
1141
+ };
1142
+ };
1143
+ put?: never;
1144
+ post?: never;
1145
+ delete?: never;
1146
+ options?: never;
1147
+ head?: never;
1148
+ patch?: never;
1149
+ trace?: never;
1150
+ };
1151
+ "/account/{account_id}/fee/tier": {
1152
+ parameters: {
1153
+ query?: never;
1154
+ header?: never;
1155
+ path?: never;
1156
+ cookie?: never;
1157
+ };
1158
+ get: {
1159
+ parameters: {
1160
+ query?: never;
1161
+ header?: never;
1162
+ path: {
1163
+ account_id: number;
1164
+ };
1165
+ cookie?: never;
1166
+ };
1167
+ requestBody?: never;
1168
+ responses: {
1169
+ 200: {
1170
+ headers: {
1171
+ [name: string]: unknown;
1172
+ };
1173
+ content: {
1174
+ "application/json": components["schemas"]["FeeTierId"];
1175
+ };
1176
+ };
1177
+ 404: {
1178
+ headers: {
1179
+ [name: string]: unknown;
1180
+ };
1181
+ content: {
1182
+ "application/json": components["schemas"]["UserNotFound"];
1183
+ };
1184
+ };
1185
+ };
1186
+ };
1187
+ put?: never;
1188
+ post?: never;
1189
+ delete?: never;
1190
+ options?: never;
1191
+ head?: never;
1192
+ patch?: never;
1193
+ trace?: never;
1194
+ };
1195
+ "/accounts/fee-tiers": {
1196
+ parameters: {
1197
+ query?: never;
1198
+ header?: never;
1199
+ path?: never;
1200
+ cookie?: never;
1201
+ };
1202
+ /** @description List fee tiers assigned to accounts. */
1203
+ get: {
1204
+ parameters: {
1205
+ query?: {
1206
+ /** @description fetch results starting with this page; query starts with first entry if page isn't specified */
1207
+ startInclusive?: number | null;
1208
+ /** @description Query returns up to 50 trades in one go. */
1209
+ pageSize?: number | null;
1210
+ };
1211
+ header?: never;
1212
+ path?: never;
1213
+ cookie?: never;
1214
+ };
1215
+ requestBody?: never;
1216
+ responses: {
1217
+ 200: {
1218
+ headers: {
1219
+ [name: string]: unknown;
1220
+ };
1221
+ content: {
1222
+ "application/json": components["schemas"]["PageResult_for_uint32_and_AccountFeeTier"];
1223
+ };
1224
+ };
1225
+ };
1226
+ };
1227
+ put?: never;
1228
+ post?: never;
1229
+ delete?: never;
1230
+ options?: never;
1231
+ head?: never;
1232
+ patch?: never;
1233
+ trace?: never;
1234
+ };
1106
1235
  "/tv": {
1107
1236
  parameters: {
1108
1237
  query?: never;
@@ -2076,6 +2205,7 @@ export interface components {
2076
2205
  ActionNotFound: null;
2077
2206
  /** @description Returns fee parts per market per balance change per action per account. Fee is taken from user without return. Please note that some operations need some deposit which will be returned - these are not part of fees. */
2078
2207
  FillRole: "maker" | "taker";
2208
+ UserNotFound: null;
2079
2209
  OrderbookInfo: {
2080
2210
  /** Format: uint64 */
2081
2211
  updateId: number;
@@ -2153,7 +2283,6 @@ export interface components {
2153
2283
  pubkey: string;
2154
2284
  expiry: string;
2155
2285
  };
2156
- UserNotFound: null;
2157
2286
  PageQueryPart_for_String: {
2158
2287
  /** @description fetch results starting with this page; query starts with first entry if page isn't specified */
2159
2288
  startInclusive?: string | null;
@@ -2525,6 +2654,41 @@ export interface components {
2525
2654
  timestamp: number;
2526
2655
  paused: boolean;
2527
2656
  };
2657
+ /** Format: uint32 */
2658
+ FeeTierId: number;
2659
+ FeeTierConfig: {
2660
+ /** Format: uint16 */
2661
+ maker_fee_bps: number;
2662
+ /** Format: uint16 */
2663
+ taker_fee_bps: number;
2664
+ };
2665
+ PageQueryPart_for_uint32: {
2666
+ /**
2667
+ * Format: uint32
2668
+ * @description fetch results starting with this page; query starts with first entry if page isn't specified
2669
+ */
2670
+ startInclusive?: number | null;
2671
+ /**
2672
+ * Format: uint8
2673
+ * @description Query returns up to 50 trades in one go.
2674
+ * @default null
2675
+ */
2676
+ pageSize: number | null;
2677
+ };
2678
+ PageResult_for_uint32_and_AccountFeeTier: {
2679
+ /** @description Set of items for requested by query. */
2680
+ items: components["schemas"]["AccountFeeTier"][];
2681
+ /**
2682
+ * Format: uint32
2683
+ * @description If request contains more data, this is the id is set with which next request should be performed to get next page. If no more data, then it is undefined.
2684
+ */
2685
+ nextStartInclusive?: number | null;
2686
+ };
2687
+ AccountFeeTier: {
2688
+ /** Format: uint32 */
2689
+ accountId: number;
2690
+ feeTier: components["schemas"]["FeeTierId"];
2691
+ };
2528
2692
  /** @description TV config query response https://www.tradingview.com/charting-library-docs/latest/connecting_data/UDF/#data-feed-configuration-data */
2529
2693
  TvConfigResponse: {
2530
2694
  supported_resolutions: components["schemas"]["Resolution"][];
@@ -2,7 +2,6 @@ import Decimal from "decimal.js";
2
2
  import * as proto from "../../gen/nord_pb";
3
3
  import { paths } from "../../gen/openapi";
4
4
  import createClient from "openapi-fetch";
5
-
6
5
  import { create } from "@bufbuild/protobuf";
7
6
  import {
8
7
  FillMode,
@@ -21,6 +20,32 @@ import {
21
20
  toScaledU64,
22
21
  } from "../../utils";
23
22
  import { sizeDelimitedEncode } from "@bufbuild/protobuf/wire";
23
+ import { NordError } from "../utils/NordError";
24
+
25
+ type ReceiptKind = NonNullable<proto.Receipt["kind"]>;
26
+ type ExtractReceiptKind<K extends ReceiptKind["case"]> = Extract<
27
+ ReceiptKind,
28
+ { case: K }
29
+ >;
30
+
31
+ export function formatReceiptError(receipt: proto.Receipt): string {
32
+ if (receipt.kind?.case === "err") {
33
+ const err = receipt.kind.value;
34
+ return proto.Error[err] ?? err.toString();
35
+ }
36
+ return receipt.kind?.case ?? "unknown";
37
+ }
38
+
39
+ export function expectReceiptKind<K extends ReceiptKind["case"]>(
40
+ receipt: proto.Receipt,
41
+ expected: K,
42
+ action: string,
43
+ ): asserts receipt is proto.Receipt & { kind: ExtractReceiptKind<K> } {
44
+ if (receipt.kind?.case !== expected) {
45
+ const label = formatReceiptError(receipt);
46
+ throw new NordError(`Failed to ${action}: ${label}`);
47
+ }
48
+ }
24
49
 
25
50
  async function sessionSign(
26
51
  signFn: (message: Uint8Array) => Promise<Uint8Array>,
@@ -16,6 +16,7 @@ import {
16
16
  NordConfig,
17
17
  OrderbookQuery,
18
18
  OrderbookResponse,
19
+ FeeTierConfig,
19
20
  PeakTpsPeriodUnit,
20
21
  SubscriptionPattern,
21
22
  Token,
@@ -24,6 +25,13 @@ import {
24
25
  AccountTriggerInfo,
25
26
  HistoryTriggerQuery,
26
27
  TriggerHistoryPage,
28
+ FeeTierId,
29
+ AccountFeeTierPage,
30
+ PageResultStringOrderInfo,
31
+ PageResultStringTrade,
32
+ OrderInfoFromApi,
33
+ TokenStats,
34
+ FillRole,
27
35
  } from "../../types";
28
36
  import * as utils from "../../utils";
29
37
  import { NordWebSocketClient } from "../../websocket/index";
@@ -231,13 +239,14 @@ export class Nord {
231
239
  app,
232
240
  solanaUrl,
233
241
  webServerUrl,
242
+ protonUrl,
234
243
  }: Readonly<NordConfig>): Promise<Nord> {
235
244
  // TODO: we should parametrize the connectionn not have it done here.
236
245
  // this is a dogshit api, only here to be compatible with the shitty
237
246
  // vibecoded code and not break zero one team's workflow.
238
247
  const connection = new Connection(solanaUrl, { commitment: "confirmed" });
239
248
  const protonClient = await ProtonClient.init({
240
- protonUrl: webServerUrl,
249
+ protonUrl: protonUrl ?? webServerUrl,
241
250
  app: new PublicKey(app),
242
251
  solConn: connection,
243
252
  });
@@ -617,6 +626,31 @@ export class Nord {
617
626
  return await this.GET("/info", {});
618
627
  }
619
628
 
629
+ /**
630
+ * Fetch the current fee tier brackets configured on Nord.
631
+ *
632
+ * @returns Array of fee tier identifiers paired with their configuration
633
+ * @throws {NordError} If the request fails
634
+ */
635
+ public async getFeeBrackets(): Promise<Array<[FeeTierId, FeeTierConfig]>> {
636
+ return await this.GET("/fee/brackets/info", {});
637
+ }
638
+
639
+ /**
640
+ * Retrieve the fee tier assigned to a specific account.
641
+ *
642
+ * @param accountId - Account identifier to query
643
+ * @returns Fee tier details for the requested account
644
+ * @throws {NordError} If the request fails
645
+ */
646
+ public async getAccountFeeTier(accountId: number): Promise<FeeTierId> {
647
+ return await this.GET("/account/{account_id}/fee/tier", {
648
+ params: {
649
+ path: { account_id: accountId },
650
+ },
651
+ });
652
+ }
653
+
620
654
  /**
621
655
  * Get account information
622
656
  *
@@ -632,6 +666,76 @@ export class Nord {
632
666
  });
633
667
  }
634
668
 
669
+ /**
670
+ * Get the public key associated with an account id.
671
+ *
672
+ * @param accountId - Account id to query
673
+ * @returns Base58-encoded account public key
674
+ * @throws {NordError} If the request fails
675
+ */
676
+ public async getAccountPubkey(accountId: number): Promise<string> {
677
+ return await this.GET("/account/{account_id}/pubkey", {
678
+ params: {
679
+ path: { account_id: accountId },
680
+ },
681
+ });
682
+ }
683
+
684
+ /**
685
+ * Get the withdrawal fee charged for an account.
686
+ *
687
+ * @param accountId - Account id to query
688
+ * @returns Withdrawal fee quoted in quote token units
689
+ * @throws {NordError} If the request fails
690
+ */
691
+ public async getAccountWithdrawalFee(accountId: number): Promise<number> {
692
+ return await this.GET("/account/{account_id}/fees/withdrawal", {
693
+ params: {
694
+ path: { account_id: accountId },
695
+ },
696
+ });
697
+ }
698
+
699
+ /**
700
+ * Get open orders for an account.
701
+ *
702
+ * @param accountId - Account id to query
703
+ * @param query - Optional pagination parameters
704
+ * @returns Page of orders keyed by client order id
705
+ * @throws {NordError} If the request fails
706
+ */
707
+ public async getAccountOrders(
708
+ accountId: number,
709
+ query?: { startInclusive?: string | null; pageSize?: number | null },
710
+ ): Promise<PageResultStringOrderInfo> {
711
+ return await this.GET("/account/{account_id}/orders", {
712
+ params: {
713
+ path: { account_id: accountId },
714
+ query: {
715
+ startInclusive: query?.startInclusive,
716
+ pageSize: query?.pageSize,
717
+ },
718
+ },
719
+ });
720
+ }
721
+
722
+ /**
723
+ * List account fee tiers with pagination support.
724
+ */
725
+ public async getAccountsFeeTiers(query?: {
726
+ startInclusive?: number | null;
727
+ pageSize?: number | null;
728
+ }): Promise<AccountFeeTierPage> {
729
+ return await this.GET("/accounts/fee-tiers", {
730
+ params: {
731
+ query: {
732
+ startInclusive: query?.startInclusive ?? undefined,
733
+ pageSize: query?.pageSize ?? undefined,
734
+ },
735
+ },
736
+ });
737
+ }
738
+
635
739
  /**
636
740
  * Get profit and loss history for an account
637
741
  *
@@ -674,6 +778,86 @@ export class Nord {
674
778
  });
675
779
  }
676
780
 
781
+ /**
782
+ * Fetch the per-market fee quote for an account.
783
+ *
784
+ * @param params - Market id, fee kind, and account id to quote
785
+ * @returns Fee in quote token units (negative means fee is charged)
786
+ * @throws {NordError} If the request fails
787
+ */
788
+ public async getMarketFee({
789
+ marketId,
790
+ feeKind,
791
+ accountId,
792
+ }: {
793
+ marketId: number;
794
+ feeKind: FillRole;
795
+ accountId: number;
796
+ }): Promise<number> {
797
+ return await this.GET("/market/{market_id}/fees/{fee_kind}/{account_id}", {
798
+ params: {
799
+ path: {
800
+ market_id: marketId,
801
+ fee_kind: feeKind,
802
+ account_id: accountId,
803
+ },
804
+ },
805
+ });
806
+ }
807
+
808
+ /**
809
+ * Fetch token statistics such as index price and oracle metadata.
810
+ *
811
+ * @param tokenId - Token identifier
812
+ * @returns Token stats
813
+ * @throws {NordError} If the request fails
814
+ */
815
+ public async getTokenStats(tokenId: number): Promise<TokenStats> {
816
+ return await this.GET("/tokens/{token_id}/stats", {
817
+ params: {
818
+ path: { token_id: tokenId },
819
+ },
820
+ });
821
+ }
822
+
823
+ /**
824
+ * Get order summary by order id.
825
+ *
826
+ * @param orderId - Order identifier
827
+ * @returns Order information
828
+ * @throws {NordError} If the request fails
829
+ */
830
+ public async getOrder(orderId: string): Promise<OrderInfoFromApi> {
831
+ return await this.GET("/order/{order_id}", {
832
+ params: {
833
+ path: { order_id: orderId },
834
+ },
835
+ });
836
+ }
837
+
838
+ /**
839
+ * Get trade history for a specific order.
840
+ *
841
+ * @param orderId - Order identifier
842
+ * @param query - Optional pagination parameters
843
+ * @returns Page of trades associated with the order
844
+ * @throws {NordError} If the request fails
845
+ */
846
+ public async getOrderTrades(
847
+ orderId: string,
848
+ query?: { startInclusive?: string | null; pageSize?: number | null },
849
+ ): Promise<PageResultStringTrade> {
850
+ return await this.GET("/order/{order_id}/trades", {
851
+ params: {
852
+ path: { order_id: orderId },
853
+ query: {
854
+ startInclusive: query?.startInclusive,
855
+ pageSize: query?.pageSize,
856
+ },
857
+ },
858
+ });
859
+ }
860
+
677
861
  /**
678
862
  * Check if an account exists for the given address
679
863
  *