@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.
@@ -83,8 +83,12 @@ export interface paths {
83
83
  get: {
84
84
  parameters: {
85
85
  query: {
86
+ /** @description Start action ID (exclusive) */
86
87
  from: number;
88
+ /** @description End action ID (inclusive) */
87
89
  to: number;
90
+ /** @description Optionally provided binary version of client, so nord server can ensure all actions provided are executable by client. */
91
+ clientVersion?: components["schemas"]["ExecutableVersion"] | null;
88
92
  };
89
93
  header?: never;
90
94
  path?: never;
@@ -108,6 +112,14 @@ export interface paths {
108
112
  "application/json": components["schemas"]["RangeTooLarge"];
109
113
  };
110
114
  };
115
+ 501: {
116
+ headers: {
117
+ [name: string]: unknown;
118
+ };
119
+ content: {
120
+ "application/json": components["schemas"]["NotImplemented"];
121
+ };
122
+ };
111
123
  };
112
124
  };
113
125
  put?: never;
@@ -136,6 +148,14 @@ export interface paths {
136
148
  "application/octet-stream": unknown;
137
149
  };
138
150
  };
151
+ 413: {
152
+ headers: {
153
+ [name: string]: unknown;
154
+ };
155
+ content: {
156
+ "application/json": components["schemas"]["PayloadTooLarge"];
157
+ };
158
+ };
139
159
  415: {
140
160
  headers: {
141
161
  /**
@@ -778,7 +798,7 @@ export interface paths {
778
798
  [name: string]: unknown;
779
799
  };
780
800
  content: {
781
- "application/json": components["schemas"]["TriggerInfo"][] | null;
801
+ "application/json": components["schemas"]["AccountTriggerInfo"][] | null;
782
802
  };
783
803
  };
784
804
  };
@@ -975,6 +995,79 @@ export interface paths {
975
995
  patch?: never;
976
996
  trace?: never;
977
997
  };
998
+ "/state/download": {
999
+ parameters: {
1000
+ query?: never;
1001
+ header?: never;
1002
+ path?: never;
1003
+ cookie?: never;
1004
+ };
1005
+ /** @description Returns state download link and metadata, as defined by nearest(up to equality) snapshot `time` or `action_id`` or `timestamp`. If not specified, returns latest snapshot. Example: /state/download?actionId=1 /state/download?time&2025-09-22T12:34:56Z /state/download?timestamp&1695380000 - Does not implemented yet. To get the latest snap use: /state/download - w/o any params.
1006
+ *
1007
+ * The link from responce can be inserted to search bar in browser to download. */
1008
+ get: {
1009
+ parameters: {
1010
+ query?: never;
1011
+ header?: never;
1012
+ path?: never;
1013
+ cookie?: never;
1014
+ };
1015
+ requestBody?: never;
1016
+ responses: {
1017
+ 200: {
1018
+ headers: {
1019
+ [name: string]: unknown;
1020
+ };
1021
+ content: {
1022
+ "application/json": components["schemas"]["StateDownloadMeta"];
1023
+ };
1024
+ };
1025
+ 501: {
1026
+ headers: {
1027
+ [name: string]: unknown;
1028
+ };
1029
+ content: {
1030
+ "application/json": components["schemas"]["NotImplemented"];
1031
+ };
1032
+ };
1033
+ };
1034
+ };
1035
+ put?: never;
1036
+ post?: never;
1037
+ delete?: never;
1038
+ options?: never;
1039
+ head?: never;
1040
+ patch?: never;
1041
+ trace?: never;
1042
+ };
1043
+ "/state/download/{snapshot_id}": {
1044
+ parameters: {
1045
+ query?: never;
1046
+ header?: never;
1047
+ path?: never;
1048
+ cookie?: never;
1049
+ };
1050
+ /** @description Typical HTTP file download endpoint. Actually same as provided by S3 storages. Means supports Range header, Content-Length, Content-Type, ETag and so on, and relevant headers. */
1051
+ get: {
1052
+ parameters: {
1053
+ query?: never;
1054
+ header?: never;
1055
+ path: {
1056
+ snapshot_id: string;
1057
+ };
1058
+ cookie?: never;
1059
+ };
1060
+ requestBody?: never;
1061
+ responses: never;
1062
+ };
1063
+ put?: never;
1064
+ post?: never;
1065
+ delete?: never;
1066
+ options?: never;
1067
+ head?: never;
1068
+ patch?: never;
1069
+ trace?: never;
1070
+ };
978
1071
  "/tv": {
979
1072
  parameters: {
980
1073
  query?: never;
@@ -1910,12 +2003,25 @@ export interface components {
1910
2003
  AcceptedMediaType: {
1911
2004
  expected: string;
1912
2005
  };
2006
+ PayloadTooLarge: {
2007
+ /** Format: uint */
2008
+ limit: number;
2009
+ };
1913
2010
  ActionsQuery: {
1914
- /** Format: uint64 */
2011
+ /**
2012
+ * Format: uint64
2013
+ * @description Start action ID (exclusive)
2014
+ */
1915
2015
  from: number;
1916
- /** Format: uint64 */
2016
+ /**
2017
+ * Format: uint64
2018
+ * @description End action ID (inclusive)
2019
+ */
1917
2020
  to: number;
2021
+ /** @description Optionally provided binary version of client, so nord server can ensure all actions provided are executable by client. */
2022
+ clientVersion?: components["schemas"]["ExecutableVersion"] | null;
1918
2023
  };
2024
+ ExecutableVersion: string;
1919
2025
  ActionsItem: {
1920
2026
  /** Format: uint64 */
1921
2027
  actionId: number;
@@ -1928,6 +2034,10 @@ export interface components {
1928
2034
  /** Format: uint16 */
1929
2035
  maximal: number;
1930
2036
  };
2037
+ NotImplemented: {
2038
+ /** @description Human readable message describing what to expect next. */
2039
+ message: string;
2040
+ };
1931
2041
  ActionNotFound: null;
1932
2042
  /** @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. */
1933
2043
  FillRole: "maker" | "taker";
@@ -2258,14 +2368,23 @@ export interface components {
2258
2368
  /** @enum {string} */
2259
2369
  TriggerKind: "stopLoss" | "takeProfit";
2260
2370
  /** @enum {string} */
2261
- TriggerStatus: "active" | "success" | "cancel" | "fail" | "remove";
2262
- TriggerInfo: {
2371
+ TriggerStatus: "Active" | "Success" | "Removed" | "Canceled";
2372
+ /** @description Trigger into per account. */
2373
+ AccountTriggerInfo: {
2263
2374
  /** Format: uint32 */
2264
2375
  marketId: number;
2376
+ key: components["schemas"]["TriggerKey"];
2377
+ triggerPrices: components["schemas"]["TriggerPrice"];
2378
+ /** Format: uint64 */
2379
+ actionId: number;
2380
+ };
2381
+ TriggerKey: {
2265
2382
  side: components["schemas"]["Side"];
2266
2383
  kind: components["schemas"]["TriggerKind"];
2267
- triggerPrice: components["schemas"]["PositivePriceMantissa"];
2268
- limitPrice?: components["schemas"]["PositivePriceMantissa"] | null;
2384
+ };
2385
+ TriggerPrice: {
2386
+ trigger: components["schemas"]["PositivePriceMantissa"];
2387
+ settlement?: components["schemas"]["PositivePriceMantissa"] | null;
2269
2388
  };
2270
2389
  /**
2271
2390
  * Format: uint64
@@ -2333,6 +2452,29 @@ export interface components {
2333
2452
  */
2334
2453
  pageSize: number | null;
2335
2454
  };
2455
+ DownloadFilter: components["schemas"]["Op_for_DataDateTime"] | components["schemas"]["Op_for_uint64"] | components["schemas"]["Op_for_uint64"] | null;
2456
+ /** @description Parses tag (anycase), and value in round braces using `from_str`. */
2457
+ Op_for_DataDateTime: {
2458
+ le: components["schemas"]["DataDateTime"];
2459
+ };
2460
+ DataDateTime: string;
2461
+ /** @description Parses tag (anycase), and value in round braces using `from_str`. */
2462
+ Op_for_uint64: {
2463
+ /** Format: uint64 */
2464
+ le: number;
2465
+ };
2466
+ StateDownloadMeta: {
2467
+ /** @description Hash of the state file. Used as ETag. */
2468
+ hash: number[];
2469
+ /**
2470
+ * Format: uri
2471
+ * @description Link to download the state file.
2472
+ */
2473
+ link: string;
2474
+ /** @description Version of binary which produced this state snapshot. So can decide whether it is compatible with client. todo(repl): After upgrade release make it non-optional. */
2475
+ version?: components["schemas"]["BinaryId"] | null;
2476
+ };
2477
+ BinaryId: string;
2336
2478
  /** @description TV config query response https://www.tradingview.com/charting-library-docs/latest/connecting_data/UDF/#data-feed-configuration-data */
2337
2479
  TvConfigResponse: {
2338
2480
  supported_resolutions: components["schemas"]["Resolution"][];
@@ -1,6 +1,6 @@
1
1
  import Decimal from "decimal.js";
2
2
  import * as proto from "../../gen/nord_pb";
3
- import { FillMode, Side, QuoteSize } from "../../types";
3
+ import { FillMode, Side, QuoteSize, TriggerKind } from "../../types";
4
4
  import { BigIntValue } from "../../utils";
5
5
  export declare function prepareAction(action: proto.Action, makeSignedMessage: (message: Uint8Array) => Promise<Uint8Array>): Promise<Uint8Array<ArrayBufferLike>>;
6
6
  export declare function createSession(serverUrl: string, walletSignFn: (message: string | Uint8Array) => Promise<Uint8Array>, currentTimestamp: bigint, nonce: number, params: {
@@ -68,6 +68,27 @@ export declare function transfer(serverUrl: string, signFn: (message: Uint8Array
68
68
  amount: bigint;
69
69
  accountCreated: boolean;
70
70
  }>;
71
+ export declare function addTrigger(serverUrl: string, signFn: (message: Uint8Array) => Promise<Uint8Array>, currentTimestamp: bigint, nonce: number, params: {
72
+ sessionId: BigIntValue;
73
+ marketId: number;
74
+ side: Side;
75
+ kind: TriggerKind;
76
+ priceDecimals: number;
77
+ triggerPrice: Decimal.Value;
78
+ limitPrice?: Decimal.Value;
79
+ accountId?: number;
80
+ }): Promise<{
81
+ actionId: bigint;
82
+ }>;
83
+ export declare function removeTrigger(serverUrl: string, signFn: (message: Uint8Array) => Promise<Uint8Array>, currentTimestamp: bigint, nonce: number, params: {
84
+ sessionId: BigIntValue;
85
+ marketId: number;
86
+ side: Side;
87
+ kind: TriggerKind;
88
+ accountId?: number;
89
+ }): Promise<{
90
+ actionId: bigint;
91
+ }>;
71
92
  export type AtomicSubaction = {
72
93
  kind: "place";
73
94
  marketId: number;
@@ -43,6 +43,8 @@ exports.withdraw = withdraw;
43
43
  exports.placeOrder = placeOrder;
44
44
  exports.cancelOrder = cancelOrder;
45
45
  exports.transfer = transfer;
46
+ exports.addTrigger = addTrigger;
47
+ exports.removeTrigger = removeTrigger;
46
48
  exports.atomic = atomic;
47
49
  const proto = __importStar(require("../../gen/nord_pb"));
48
50
  const openapi_fetch_1 = __importDefault(require("openapi-fetch"));
@@ -66,7 +68,7 @@ function createAction(currentTimestamp, nonce, kind) {
66
68
  kind,
67
69
  });
68
70
  }
69
- async function sendAction(serverUrl, makeSignedMessage, action, actionErrorDesc) {
71
+ async function sendAction(serverUrl, makeSignedMessage, action) {
70
72
  const body = await prepareAction(action, makeSignedMessage);
71
73
  // NOTE: restructure and reuse client as it is in Nord.ts
72
74
  const client = (0, openapi_fetch_1.default)({ baseUrl: serverUrl });
@@ -77,14 +79,18 @@ async function sendAction(serverUrl, makeSignedMessage, action, actionErrorDesc)
77
79
  },
78
80
  },
79
81
  body: body,
82
+ // NOTE: openapi-fetch ignores headers and types/const headers in schema, and always assume all things are JSON
83
+ // to handle multi type bodies, need these overrides and later adhoc parsing
84
+ bodySerializer: (body) => body,
85
+ parseAs: "stream",
80
86
  });
81
87
  if (response.error) {
82
- throw new Error(`Failed to ${actionErrorDesc}, HTTP status ${response}`);
88
+ throw new Error(`Failed to ${action.kind.case}, HTTP status ${JSON.stringify(response.error)}`);
83
89
  }
84
- const rawResp = new Uint8Array(await response.response.arrayBuffer());
90
+ const rawResp = new Uint8Array(await response.response.bytes());
85
91
  const resp = (0, utils_1.decodeLengthDelimited)(rawResp, proto.ReceiptSchema);
86
92
  if (resp.kind?.case === "err") {
87
- throw new Error(`Could not ${actionErrorDesc}, reason: ${proto.Error[resp.kind.value]}`);
93
+ throw new Error(`Could not execute ${action.kind.case}, reason: ${proto.Error[resp.kind.value]}`);
88
94
  }
89
95
  return resp;
90
96
  }
@@ -92,12 +98,17 @@ async function sendAction(serverUrl, makeSignedMessage, action, actionErrorDesc)
92
98
  // `makeSignedMessage` must include the original message and signature.
93
99
  async function prepareAction(action, makeSignedMessage) {
94
100
  const encoded = (0, wire_1.sizeDelimitedEncode)(proto.ActionSchema, action);
95
- // NOTE(agent): keep in sync with MAX_HTTP_REQUEST_BODY_SIZE in rust code
96
- const MAX_HTTP_REQUEST_BODY_SIZE = 1024;
97
- if (encoded.byteLength > MAX_HTTP_REQUEST_BODY_SIZE) {
98
- throw new Error(`Encoded message size (${encoded.byteLength} bytes) is greater than max payload size (${MAX_HTTP_REQUEST_BODY_SIZE} bytes).`);
101
+ // NOTE(agent): keep in sync with MAX_ENCODED_ACTION_SIZE in Rust code
102
+ const MAX_ENCODED_ACTION_SIZE = 1024;
103
+ if (encoded.byteLength > MAX_ENCODED_ACTION_SIZE) {
104
+ console.warn("Encoded message:", encoded);
105
+ throw new Error(`Encoded message size (${encoded.byteLength} bytes) is greater than max payload size (${MAX_ENCODED_ACTION_SIZE} bytes).`);
99
106
  }
100
107
  const body = await makeSignedMessage(encoded);
108
+ if (body.byteLength > MAX_ENCODED_ACTION_SIZE) {
109
+ console.warn("Encoded length:", encoded.byteLength);
110
+ throw new Error(`Signed message size (${body.byteLength} bytes) is greater than max payload size (${MAX_ENCODED_ACTION_SIZE} bytes).`);
111
+ }
101
112
  return body;
102
113
  }
103
114
  async function createSession(serverUrl, walletSignFn, currentTimestamp, nonce, params) {
@@ -119,7 +130,7 @@ async function createSession(serverUrl, walletSignFn, currentTimestamp, nonce, p
119
130
  expiryTimestamp: expiry,
120
131
  }),
121
132
  });
122
- const resp = await sendAction(serverUrl, (m) => walletSign(walletSignFn, m), action, "create a new session");
133
+ const resp = await sendAction(serverUrl, (m) => walletSign(walletSignFn, m), action);
123
134
  if (resp.kind?.case === "createSessionResult") {
124
135
  return {
125
136
  actionId: resp.actionId,
@@ -137,7 +148,7 @@ async function revokeSession(serverUrl, walletSignFn, currentTimestamp, nonce, p
137
148
  sessionId: BigInt(params.sessionId),
138
149
  }),
139
150
  });
140
- const resp = await sendAction(serverUrl, (m) => walletSign(walletSignFn, m), action, "revoke session");
151
+ const resp = await sendAction(serverUrl, (m) => walletSign(walletSignFn, m), action);
141
152
  return { actionId: resp.actionId };
142
153
  }
143
154
  async function withdraw(serverUrl, signFn, currentTimestamp, nonce, params) {
@@ -153,7 +164,7 @@ async function withdraw(serverUrl, signFn, currentTimestamp, nonce, params) {
153
164
  amount,
154
165
  }),
155
166
  });
156
- const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action, "withdraw");
167
+ const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action);
157
168
  if (resp.kind?.case === "withdrawResult") {
158
169
  return { actionId: resp.actionId, ...resp.kind.value };
159
170
  }
@@ -165,7 +176,7 @@ async function placeOrder(serverUrl, signFn, currentTimestamp, nonce, params) {
165
176
  const price = (0, utils_1.toScaledU64)(params.price ?? 0, params.priceDecimals);
166
177
  const size = (0, utils_1.toScaledU64)(params.size ?? 0, params.sizeDecimals);
167
178
  const scaledQuote = params.quoteSize
168
- ? params.quoteSize.toScaledU64(params.priceDecimals, params.sizeDecimals)
179
+ ? params.quoteSize.toWire(params.priceDecimals, params.sizeDecimals)
169
180
  : undefined;
170
181
  (0, utils_1.assert)(price > 0n || size > 0n || scaledQuote !== undefined, "OrderLimit must include at least one of: size, price, or quoteSize");
171
182
  const action = createAction(currentTimestamp, nonce, {
@@ -191,7 +202,7 @@ async function placeOrder(serverUrl, signFn, currentTimestamp, nonce, params) {
191
202
  delegatorAccountId: params.liquidateeId,
192
203
  }),
193
204
  });
194
- const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action, "place order");
205
+ const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action);
195
206
  if (resp.kind?.case === "placeOrderResult") {
196
207
  return {
197
208
  actionId: resp.actionId,
@@ -213,7 +224,7 @@ async function cancelOrder(serverUrl, signFn, currentTimestamp, nonce, params) {
213
224
  delegatorAccountId: params.liquidateeId,
214
225
  }),
215
226
  });
216
- const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action, "cancel order");
227
+ const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action);
217
228
  if (resp.kind?.case === "cancelOrderResult") {
218
229
  return {
219
230
  actionId: resp.actionId,
@@ -236,7 +247,7 @@ async function transfer(serverUrl, signFn, currentTimestamp, nonce, params) {
236
247
  amount: (0, utils_1.toScaledU64)(params.amount ?? 0, params.tokenDecimals),
237
248
  }),
238
249
  });
239
- const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action, "transfer");
250
+ const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action);
240
251
  if (resp.kind?.case === "transferred") {
241
252
  return {
242
253
  actionId: resp.actionId,
@@ -251,6 +262,63 @@ async function transfer(serverUrl, signFn, currentTimestamp, nonce, params) {
251
262
  throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
252
263
  }
253
264
  }
265
+ async function addTrigger(serverUrl, signFn, currentTimestamp, nonce, params) {
266
+ const triggerPrice = (0, utils_1.toScaledU64)(params.triggerPrice, params.priceDecimals);
267
+ (0, utils_1.assert)(triggerPrice > 0n, "Trigger price must be positive");
268
+ const limitPrice = params.limitPrice === undefined
269
+ ? undefined
270
+ : (0, utils_1.toScaledU64)(params.limitPrice, params.priceDecimals);
271
+ if (limitPrice !== undefined) {
272
+ (0, utils_1.assert)(limitPrice > 0n, "Limit price must be positive");
273
+ }
274
+ const key = (0, protobuf_1.create)(proto.TriggerKeySchema, {
275
+ kind: params.kind === types_1.TriggerKind.StopLoss
276
+ ? proto.TriggerKind.STOP_LOSS
277
+ : proto.TriggerKind.TAKE_PROFIT,
278
+ side: params.side === types_1.Side.Bid ? proto.Side.BID : proto.Side.ASK,
279
+ });
280
+ const prices = (0, protobuf_1.create)(proto.Action_TriggerPricesSchema, {
281
+ triggerPrice,
282
+ limitPrice,
283
+ });
284
+ const action = createAction(currentTimestamp, nonce, {
285
+ case: "addTrigger",
286
+ value: (0, protobuf_1.create)(proto.Action_AddTriggerSchema, {
287
+ sessionId: BigInt(params.sessionId),
288
+ marketId: params.marketId,
289
+ key,
290
+ prices,
291
+ accountId: params.accountId,
292
+ }),
293
+ });
294
+ const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action);
295
+ if (resp.kind?.case === "triggerAdded") {
296
+ return { actionId: resp.actionId };
297
+ }
298
+ throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
299
+ }
300
+ async function removeTrigger(serverUrl, signFn, currentTimestamp, nonce, params) {
301
+ const key = (0, protobuf_1.create)(proto.TriggerKeySchema, {
302
+ kind: params.kind === types_1.TriggerKind.StopLoss
303
+ ? proto.TriggerKind.STOP_LOSS
304
+ : proto.TriggerKind.TAKE_PROFIT,
305
+ side: params.side === types_1.Side.Bid ? proto.Side.BID : proto.Side.ASK,
306
+ });
307
+ const action = createAction(currentTimestamp, nonce, {
308
+ case: "removeTrigger",
309
+ value: (0, protobuf_1.create)(proto.Action_RemoveTriggerSchema, {
310
+ sessionId: BigInt(params.sessionId),
311
+ marketId: params.marketId,
312
+ key,
313
+ accountId: params.accountId,
314
+ }),
315
+ });
316
+ const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action);
317
+ if (resp.kind?.case === "triggerRemoved") {
318
+ return { actionId: resp.actionId };
319
+ }
320
+ throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
321
+ }
254
322
  async function atomic(serverUrl, signFn, currentTimestamp, nonce, params) {
255
323
  (0, utils_1.assert)(params.actions.length > 0 && params.actions.length <= 4, "Atomic action must contain between 1 and 4 sub-actions");
256
324
  const subactions = params.actions.map((a) => {
@@ -258,7 +326,7 @@ async function atomic(serverUrl, signFn, currentTimestamp, nonce, params) {
258
326
  const price = (0, utils_1.toScaledU64)(a.price ?? 0, a.priceDecimals);
259
327
  const size = (0, utils_1.toScaledU64)(a.size ?? 0, a.sizeDecimals);
260
328
  const scaledQuote = a.quoteSize
261
- ? a.quoteSize.toScaledU64(a.priceDecimals, a.sizeDecimals)
329
+ ? a.quoteSize.toWire(a.priceDecimals, a.sizeDecimals)
262
330
  : undefined;
263
331
  // Require at least one limit to be set (non-zero size, non-zero price, or quoteSize)
264
332
  (0, utils_1.assert)(price > 0n || size > 0n || scaledQuote !== undefined, "OrderLimit must include at least one of: size, price, or quoteSize");
@@ -300,7 +368,7 @@ async function atomic(serverUrl, signFn, currentTimestamp, nonce, params) {
300
368
  actions: subactions,
301
369
  }),
302
370
  });
303
- const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action, "execute atomic action");
371
+ const resp = await sendAction(serverUrl, (m) => sessionSign(signFn, m), action);
304
372
  if (resp.kind?.case === "atomic") {
305
373
  return {
306
374
  actionId: resp.actionId,
@@ -0,0 +1,7 @@
1
+ import { components } from "../../gen/openapi";
2
+ type AccountTriggerInfo = components["schemas"]["AccountTriggerInfo"];
3
+ type TriggerHistoryPage = components["schemas"]["PageResult_for_uint64_and_HistoryTriggerInfo"];
4
+ type HistoryTriggerQuery = components["schemas"]["AccountTriggersQuery"];
5
+ export type { AccountTriggerInfo, TriggerHistoryPage, HistoryTriggerQuery };
6
+ export declare function getAccountTriggers(serverUrl: string, accountId: number): Promise<AccountTriggerInfo[]>;
7
+ export declare function getAccountTriggerHistory(serverUrl: string, accountId: number, options: HistoryTriggerQuery): Promise<TriggerHistoryPage>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getAccountTriggers = getAccountTriggers;
7
+ exports.getAccountTriggerHistory = getAccountTriggerHistory;
8
+ const openapi_fetch_1 = __importDefault(require("openapi-fetch"));
9
+ async function getAccountTriggers(serverUrl, accountId) {
10
+ const client = (0, openapi_fetch_1.default)({ baseUrl: serverUrl });
11
+ const response = await client.GET("/account/{account_id}/triggers", {
12
+ params: {
13
+ path: { account_id: accountId },
14
+ },
15
+ });
16
+ if (response.data === undefined) {
17
+ throw new Error(`Failed to fetch triggers for account ${accountId}: HTTP ${response.response.status}`);
18
+ }
19
+ return response.data ?? [];
20
+ }
21
+ async function getAccountTriggerHistory(serverUrl, accountId, options) {
22
+ const client = (0, openapi_fetch_1.default)({ baseUrl: serverUrl });
23
+ const response = await client.GET("/account/{account_id}/triggers/history", {
24
+ params: {
25
+ path: { account_id: accountId },
26
+ query: {
27
+ since: options.since,
28
+ until: options.until,
29
+ pageSize: options.pageSize,
30
+ startInclusive: options.startInclusive,
31
+ },
32
+ },
33
+ });
34
+ if (!response.data) {
35
+ throw new Error(`Failed to fetch trigger history for account ${accountId}: HTTP ${response.response.status}`);
36
+ }
37
+ return response.data;
38
+ }
@@ -1,7 +1,7 @@
1
1
  import { ProtonClient } from "@n1xyz/proton";
2
2
  import { PublicKey } from "@solana/web3.js";
3
3
  import { EventEmitter } from "events";
4
- import { Account, ActionResponse, AggregateMetrics, Info, Market, MarketStats, NordConfig, OrderbookQuery, OrderbookResponse, PeakTpsPeriodUnit, Token, TradesResponse, User } from "../../types";
4
+ import { Account, AccountPnlPage, AccountPnlQuery, ActionResponse, AggregateMetrics, Info, Market, MarketStats, NordConfig, OrderbookQuery, OrderbookResponse, PeakTpsPeriodUnit, Token, TradesResponse, User } from "../../types";
5
5
  import { NordWebSocketClient } from "../../websocket/index";
6
6
  import { OrderbookSubscription, TradeSubscription } from "../models/Subscriber";
7
7
  /**
@@ -263,6 +263,15 @@ export declare class Nord {
263
263
  * @throws {NordError} If the request fails
264
264
  */
265
265
  getAccount(accountId: number): Promise<Account>;
266
+ /**
267
+ * Get profit and loss history for an account
268
+ *
269
+ * @param accountId - Account ID to query
270
+ * @param query - Optional time and pagination filters
271
+ * @returns Page of PnL entries ordered from latest to oldest
272
+ * @throws {NordError} If the request fails
273
+ */
274
+ getAccountPnl(accountId: number, query?: Partial<AccountPnlQuery>): Promise<AccountPnlPage>;
266
275
  /**
267
276
  * Get market statistics (alias for marketsStats for backward compatibility)
268
277
  *
@@ -502,6 +502,27 @@ class Nord {
502
502
  },
503
503
  });
504
504
  }
505
+ /**
506
+ * Get profit and loss history for an account
507
+ *
508
+ * @param accountId - Account ID to query
509
+ * @param query - Optional time and pagination filters
510
+ * @returns Page of PnL entries ordered from latest to oldest
511
+ * @throws {NordError} If the request fails
512
+ */
513
+ async getAccountPnl(accountId, query) {
514
+ return await this.GET("/account/{account_id}/pnl", {
515
+ params: {
516
+ path: { account_id: accountId },
517
+ query: {
518
+ since: query?.since,
519
+ until: query?.until,
520
+ startInclusive: query?.startInclusive,
521
+ pageSize: query?.pageSize,
522
+ },
523
+ },
524
+ });
525
+ }
505
526
  /**
506
527
  * Get market statistics (alias for marketsStats for backward compatibility)
507
528
  *
@@ -1,8 +1,9 @@
1
1
  import { Connection, PublicKey, Transaction, SendOptions } from "@solana/web3.js";
2
2
  import Decimal from "decimal.js";
3
- import { FillMode, Side, SPLTokenInfo, QuoteSize } from "../../types";
3
+ import { FillMode, Side, SPLTokenInfo, QuoteSize, TriggerKind } from "../../types";
4
4
  import * as proto from "../../gen/nord_pb";
5
5
  import { BigIntValue } from "../../utils";
6
+ import type { AccountTriggerInfo, TriggerHistoryPage, HistoryTriggerQuery } from "../api/triggers";
6
7
  import { Nord } from "./Nord";
7
8
  /**
8
9
  * Parameters for creating a NordUser instance
@@ -48,6 +49,20 @@ export interface PlaceOrderParams {
48
49
  /** Account ID to place the order from */
49
50
  accountId?: number;
50
51
  }
52
+ export interface AddTriggerParams {
53
+ marketId: number;
54
+ side: Side;
55
+ kind: TriggerKind;
56
+ triggerPrice: Decimal.Value;
57
+ limitPrice?: Decimal.Value;
58
+ accountId?: number;
59
+ }
60
+ export interface RemoveTriggerParams {
61
+ marketId: number;
62
+ side: Side;
63
+ kind: TriggerKind;
64
+ accountId?: number;
65
+ }
51
66
  /**
52
67
  * Parameters for transferring tokens between accounts
53
68
  */
@@ -288,6 +303,44 @@ export declare class NordUser {
288
303
  orderId: bigint;
289
304
  accountId: number;
290
305
  }>;
306
+ /**
307
+ * Add a trigger for the current session
308
+ *
309
+ * @param params - Trigger parameters including market, side, and prices
310
+ * @returns Object containing the actionId of the submitted trigger
311
+ * @throws {NordError} If the operation fails
312
+ */
313
+ addTrigger(params: AddTriggerParams): Promise<{
314
+ actionId: bigint;
315
+ }>;
316
+ /**
317
+ * Remove a trigger for the current session
318
+ *
319
+ * @param params - Trigger parameters identifying the trigger to remove
320
+ * @returns Object containing the actionId of the removal action
321
+ * @throws {NordError} If the operation fails
322
+ */
323
+ removeTrigger(params: RemoveTriggerParams): Promise<{
324
+ actionId: bigint;
325
+ }>;
326
+ /**
327
+ * Fetch active triggers for an account.
328
+ *
329
+ * @param params Optional parameters containing an explicit account id.
330
+ * @throws {NordError} If no account can be resolved or the request fails.
331
+ */
332
+ getAccountTriggers(params?: {
333
+ accountId?: number;
334
+ }): Promise<AccountTriggerInfo[]>;
335
+ /**
336
+ * Fetch trigger history for an account.
337
+ *
338
+ * @param params Optional parameters with account id and history query filters.
339
+ * @throws {NordError} If no account can be resolved or the request fails.
340
+ */
341
+ getAccountTriggerHistory(params: HistoryTriggerQuery & {
342
+ accountId?: number;
343
+ }): Promise<TriggerHistoryPage>;
291
344
  /**
292
345
  * Transfer tokens to another account
293
346
  *