@n1xyz/nord-ts 0.1.0 → 0.1.2

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.
@@ -15,7 +15,13 @@ import * as ed from "@noble/ed25519";
15
15
  import { sha512 } from "@noble/hashes/sha512";
16
16
  ed.etc.sha512Sync = sha512;
17
17
  import { floatToScaledBigIntLossy } from "@n1xyz/proton";
18
- import { FillMode, Side, SPLTokenInfo, QuoteSize } from "../../types";
18
+ import {
19
+ FillMode,
20
+ Side,
21
+ SPLTokenInfo,
22
+ QuoteSize,
23
+ TriggerKind,
24
+ } from "../../types";
19
25
  import * as proto from "../../gen/nord_pb";
20
26
  import {
21
27
  BigIntValue,
@@ -34,7 +40,18 @@ import {
34
40
  withdraw,
35
41
  atomic as atomicAction,
36
42
  AtomicSubaction as ApiAtomicSubaction,
43
+ addTrigger as addTriggerAction,
44
+ removeTrigger as removeTriggerAction,
37
45
  } from "../api/actions";
46
+ import type {
47
+ AccountTriggerInfo,
48
+ TriggerHistoryPage,
49
+ HistoryTriggerQuery,
50
+ } from "../api/triggers";
51
+ import {
52
+ getAccountTriggers as fetchAccountTriggers,
53
+ getAccountTriggerHistory as fetchAccountTriggerHistory,
54
+ } from "../api/triggers";
38
55
  import { NordError } from "../utils/NordError";
39
56
  import { Nord } from "./Nord";
40
57
 
@@ -99,6 +116,22 @@ export interface PlaceOrderParams {
99
116
  accountId?: number;
100
117
  }
101
118
 
119
+ export interface AddTriggerParams {
120
+ marketId: number;
121
+ side: Side;
122
+ kind: TriggerKind;
123
+ triggerPrice: Decimal.Value;
124
+ limitPrice?: Decimal.Value;
125
+ accountId?: number;
126
+ }
127
+
128
+ export interface RemoveTriggerParams {
129
+ marketId: number;
130
+ side: Side;
131
+ kind: TriggerKind;
132
+ accountId?: number;
133
+ }
134
+
102
135
  /**
103
136
  * Parameters for transferring tokens between accounts
104
137
  */
@@ -834,6 +867,132 @@ export class NordUser {
834
867
  }
835
868
  }
836
869
 
870
+ /**
871
+ * Add a trigger for the current session
872
+ *
873
+ * @param params - Trigger parameters including market, side, and prices
874
+ * @returns Object containing the actionId of the submitted trigger
875
+ * @throws {NordError} If the operation fails
876
+ */
877
+ async addTrigger(params: AddTriggerParams): Promise<{ actionId: bigint }> {
878
+ try {
879
+ this.checkSessionValidity();
880
+ const market = findMarket(this.nord.markets, params.marketId);
881
+ if (!market) {
882
+ throw new NordError(`Market with ID ${params.marketId} not found`);
883
+ }
884
+ const result = await addTriggerAction(
885
+ this.nord.webServerUrl,
886
+ this.sessionSignFn,
887
+ await this.nord.getTimestamp(),
888
+ this.getNonce(),
889
+ {
890
+ sessionId: optExpect(this.sessionId, "No session"),
891
+ marketId: params.marketId,
892
+ side: params.side,
893
+ kind: params.kind,
894
+ priceDecimals: market.priceDecimals,
895
+ triggerPrice: params.triggerPrice,
896
+ limitPrice: params.limitPrice,
897
+ accountId: params.accountId,
898
+ },
899
+ );
900
+ return result;
901
+ } catch (error) {
902
+ throw new NordError("Failed to add trigger", { cause: error });
903
+ }
904
+ }
905
+
906
+ /**
907
+ * Remove a trigger for the current session
908
+ *
909
+ * @param params - Trigger parameters identifying the trigger to remove
910
+ * @returns Object containing the actionId of the removal action
911
+ * @throws {NordError} If the operation fails
912
+ */
913
+ async removeTrigger(
914
+ params: RemoveTriggerParams,
915
+ ): Promise<{ actionId: bigint }> {
916
+ try {
917
+ this.checkSessionValidity();
918
+ const market = findMarket(this.nord.markets, params.marketId);
919
+ if (!market) {
920
+ throw new NordError(`Market with ID ${params.marketId} not found`);
921
+ }
922
+ const result = await removeTriggerAction(
923
+ this.nord.webServerUrl,
924
+ this.sessionSignFn,
925
+ await this.nord.getTimestamp(),
926
+ this.getNonce(),
927
+ {
928
+ sessionId: optExpect(this.sessionId, "No session"),
929
+ marketId: params.marketId,
930
+ side: params.side,
931
+ kind: params.kind,
932
+ accountId: params.accountId,
933
+ },
934
+ );
935
+ return result;
936
+ } catch (error) {
937
+ throw new NordError("Failed to remove trigger", { cause: error });
938
+ }
939
+ }
940
+
941
+ /**
942
+ * Fetch active triggers for an account.
943
+ *
944
+ * @param params Optional parameters containing an explicit account id.
945
+ * @throws {NordError} If no account can be resolved or the request fails.
946
+ */
947
+ async getAccountTriggers(params?: {
948
+ accountId?: number;
949
+ }): Promise<AccountTriggerInfo[]> {
950
+ const accountId = params?.accountId ?? this.accountIds?.[0];
951
+
952
+ if (accountId == null) {
953
+ throw new NordError(
954
+ "Account ID is undefined. Make sure to call updateAccountId() before requesting triggers.",
955
+ );
956
+ }
957
+
958
+ try {
959
+ return await fetchAccountTriggers(this.nord.webServerUrl, accountId);
960
+ } catch (error) {
961
+ throw new NordError("Failed to fetch account triggers", { cause: error });
962
+ }
963
+ }
964
+
965
+ /**
966
+ * Fetch trigger history for an account.
967
+ *
968
+ * @param params Optional parameters with account id and history query filters.
969
+ * @throws {NordError} If no account can be resolved or the request fails.
970
+ */
971
+ async getAccountTriggerHistory(
972
+ params: HistoryTriggerQuery & { accountId?: number },
973
+ ): Promise<TriggerHistoryPage> {
974
+ const { accountId: providedAccountId, ...query } = params;
975
+ const accountId = providedAccountId ?? this.accountIds?.[0];
976
+
977
+ if (accountId == null) {
978
+ throw new NordError(
979
+ "Account ID is undefined. Make sure to call updateAccountId() before requesting trigger history.",
980
+ );
981
+ }
982
+
983
+ try {
984
+ return await fetchAccountTriggerHistory(
985
+ this.nord.webServerUrl,
986
+ accountId,
987
+ query,
988
+ );
989
+ } catch (error) {
990
+ throw new NordError("Failed to fetch account trigger history", {
991
+ cause: error,
992
+ });
993
+ }
994
+ }
995
+
837
996
  /**
838
997
  * Transfer tokens to another account
839
998
  *
package/src/types.ts CHANGED
@@ -88,6 +88,10 @@ export type SideFromApi = components["schemas"]["Side"];
88
88
  export type FillModeFromApi = components["schemas"]["FillMode"];
89
89
  export type PlacementOrigin = components["schemas"]["PlacementOrigin"];
90
90
  export type FinalizationReason = components["schemas"]["FinalizationReason"];
91
+ export type AccountPnlQuery = components["schemas"]["AccountPnlQuery"];
92
+ export type AccountPnl = components["schemas"]["AccountPnl"];
93
+ export type AccountPnlPage =
94
+ components["schemas"]["PageResult_for_uint64_and_AccountPnl"];
91
95
 
92
96
  /**
93
97
  * Configuration options for the Nord client
@@ -114,8 +118,8 @@ export enum KeyType {
114
118
  }
115
119
 
116
120
  export enum Side {
117
- Ask,
118
- Bid,
121
+ Ask = "ask",
122
+ Bid = "bid",
119
123
  }
120
124
 
121
125
  export enum FillMode {
@@ -125,6 +129,18 @@ export enum FillMode {
125
129
  FillOrKill,
126
130
  }
127
131
 
132
+ export enum TriggerKind {
133
+ StopLoss = 0,
134
+ TakeProfit = 1,
135
+ }
136
+
137
+ export enum TriggerStatus {
138
+ Active = 0,
139
+ Success = 1,
140
+ Cancel = 2,
141
+ Remove = 4,
142
+ }
143
+
128
144
  export interface SubscriberConfig {
129
145
  streamURL: string;
130
146
  maxBufferLen?: number;
@@ -304,9 +320,22 @@ export interface SPLTokenInfo {
304
320
  }
305
321
 
306
322
  // Positive decimal price and size.
323
+ // Example:
324
+ // ```
325
+ // const limit = new QuoteSize(new Decimal(114000), new Decimal(0.00035)),
326
+ //```
327
+ // Gives 40$ USD limit.
328
+ //
329
+ // Given price is same(or very close) to the market price,
330
+ // limit gives size tick as close as possible to settlemnt size tick.
331
+
332
+ // If you want to get smaller tick on client (on server it will not change),
333
+ // do `new QuoteSize(new Decimal(114000/2), new Decimal(0.00070))`.
334
+ // It will be 40$ limit, but may help if BTC suddently moves fast.
307
335
  export class QuoteSize {
308
336
  price: Decimal;
309
337
  size: Decimal;
338
+ /// Input can be only positive values.
310
339
  constructor(quotePrice: Decimal.Value, quoteSize: Decimal.Value) {
311
340
  const p = new Decimal(quotePrice);
312
341
  const s = new Decimal(quoteSize);
@@ -317,11 +346,13 @@ export class QuoteSize {
317
346
  this.size = s;
318
347
  }
319
348
 
349
+ // USD value of limit, use for debug
320
350
  value(): Decimal {
321
351
  return this.price.mul(this.size);
322
352
  }
323
353
 
324
- toScaledU64(
354
+ // Converts to wire format to be send to server, scaling price and size according to market decimals.
355
+ toWire(
325
356
  marketPriceDecimals: number,
326
357
  marketSizeDecimals: number,
327
358
  ): { price: bigint; size: bigint } {
package/src/utils.ts CHANGED
@@ -17,6 +17,7 @@ export const SESSION_TTL: bigint = 60n * 60n * 24n * 30n;
17
17
  export const ZERO_DECIMAL = new Decimal(0);
18
18
  export const MAX_BUFFER_LEN = 10_000;
19
19
 
20
+ // Max size of data returned from Nord endpoints
20
21
  const MAX_PAYLOAD_SIZE = 100 * 1024; // 100 kB
21
22
 
22
23
  /** Any type convertible to bigint */