@n1xyz/nord-ts 0.1.6 → 0.1.8

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 (85) hide show
  1. package/dist/actions.d.ts +57 -0
  2. package/dist/actions.js +186 -0
  3. package/dist/bundle.js +79181 -0
  4. package/dist/{nord/client → client}/Nord.d.ts +90 -107
  5. package/dist/{nord/client → client}/Nord.js +157 -218
  6. package/dist/{nord/client → client}/NordAdmin.d.ts +68 -102
  7. package/dist/{nord/client → client}/NordAdmin.js +109 -140
  8. package/dist/{nord/client → client}/NordUser.d.ts +86 -98
  9. package/dist/{nord/client → client}/NordUser.js +204 -271
  10. package/dist/const.js +5 -8
  11. package/dist/{nord/utils/NordError.js → error.js} +7 -5
  12. package/dist/gen/nord_pb.js +88 -92
  13. package/dist/gen/openapi.d.ts +39 -0
  14. package/dist/gen/openapi.js +1 -2
  15. package/dist/index.d.ts +6 -1
  16. package/dist/index.js +10 -21
  17. package/dist/types.d.ts +5 -50
  18. package/dist/types.js +21 -83
  19. package/dist/utils.d.ts +8 -11
  20. package/dist/utils.js +55 -90
  21. package/dist/websocket/NordWebSocketClient.js +12 -17
  22. package/dist/{nord/models → websocket}/Subscriber.d.ts +1 -1
  23. package/dist/{nord/models → websocket}/Subscriber.js +6 -7
  24. package/dist/websocket/events.js +1 -2
  25. package/dist/websocket/index.d.ts +19 -2
  26. package/dist/websocket/index.js +80 -5
  27. package/package.json +2 -3
  28. package/dist/api/client.d.ts +0 -14
  29. package/dist/api/client.js +0 -45
  30. package/dist/bridge/client.d.ts +0 -151
  31. package/dist/bridge/client.js +0 -434
  32. package/dist/bridge/const.d.ts +0 -23
  33. package/dist/bridge/const.js +0 -47
  34. package/dist/bridge/index.d.ts +0 -4
  35. package/dist/bridge/index.js +0 -23
  36. package/dist/bridge/types.d.ts +0 -120
  37. package/dist/bridge/types.js +0 -18
  38. package/dist/bridge/utils.d.ts +0 -64
  39. package/dist/bridge/utils.js +0 -131
  40. package/dist/gen/common.d.ts +0 -68
  41. package/dist/gen/common.js +0 -215
  42. package/dist/gen/nord.d.ts +0 -882
  43. package/dist/gen/nord.js +0 -6520
  44. package/dist/idl/bridge.d.ts +0 -569
  45. package/dist/idl/bridge.js +0 -8
  46. package/dist/idl/bridge.json +0 -1506
  47. package/dist/idl/index.d.ts +0 -607
  48. package/dist/idl/index.js +0 -8
  49. package/dist/nord/api/actions.d.ts +0 -126
  50. package/dist/nord/api/actions.js +0 -397
  51. package/dist/nord/api/core.d.ts +0 -16
  52. package/dist/nord/api/core.js +0 -81
  53. package/dist/nord/api/market.d.ts +0 -36
  54. package/dist/nord/api/market.js +0 -96
  55. package/dist/nord/api/metrics.d.ts +0 -67
  56. package/dist/nord/api/metrics.js +0 -229
  57. package/dist/nord/api/queries.d.ts +0 -46
  58. package/dist/nord/api/queries.js +0 -109
  59. package/dist/nord/api/triggers.d.ts +0 -7
  60. package/dist/nord/api/triggers.js +0 -38
  61. package/dist/nord/client/NordClient.d.ts +0 -33
  62. package/dist/nord/client/NordClient.js +0 -45
  63. package/dist/nord/index.d.ts +0 -11
  64. package/dist/nord/index.js +0 -36
  65. package/src/const.ts +0 -34
  66. package/src/gen/.gitkeep +0 -0
  67. package/src/gen/nord_pb.ts +0 -5053
  68. package/src/gen/openapi.ts +0 -2864
  69. package/src/index.ts +0 -5
  70. package/src/nord/api/actions.ts +0 -648
  71. package/src/nord/api/core.ts +0 -96
  72. package/src/nord/api/metrics.ts +0 -269
  73. package/src/nord/client/Nord.ts +0 -937
  74. package/src/nord/client/NordAdmin.ts +0 -514
  75. package/src/nord/client/NordClient.ts +0 -79
  76. package/src/nord/client/NordUser.ts +0 -1211
  77. package/src/nord/index.ts +0 -25
  78. package/src/nord/models/Subscriber.ts +0 -56
  79. package/src/nord/utils/NordError.ts +0 -76
  80. package/src/types.ts +0 -377
  81. package/src/utils.ts +0 -269
  82. package/src/websocket/NordWebSocketClient.ts +0 -316
  83. package/src/websocket/events.ts +0 -31
  84. package/src/websocket/index.ts +0 -2
  85. /package/dist/{nord/utils/NordError.d.ts → error.d.ts} +0 -0
@@ -1,98 +1,53 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.NordUser = void 0;
37
- const spl_token_1 = require("@solana/spl-token");
38
- const web3_js_1 = require("@solana/web3.js");
39
- const ed = __importStar(require("@noble/ed25519"));
40
- const sha512_1 = require("@noble/hashes/sha512");
41
- ed.etc.sha512Sync = sha512_1.sha512;
42
- const proton_1 = require("@n1xyz/proton");
43
- const types_1 = require("../../types");
44
- const proto = __importStar(require("../../gen/nord_pb"));
45
- const utils_1 = require("../../utils");
46
- const protobuf_1 = require("@bufbuild/protobuf");
47
- const actions_1 = require("../api/actions");
48
- const NordError_1 = require("../utils/NordError");
49
- const NordClient_1 = require("./NordClient");
1
+ import { ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, } from "@solana/spl-token";
2
+ import { PublicKey, Transaction } from "@solana/web3.js";
3
+ import * as ed from "@noble/ed25519";
4
+ import { floatToScaledBigIntLossy } from "@n1xyz/proton";
5
+ import { Side, TriggerKind, fillModeToProtoFillMode, } from "../types";
6
+ import * as proto from "../gen/nord_pb";
7
+ import { checkedFetch, assert, findMarket, findToken, optExpect, keypairFromPrivateKey, toScaledU64, } from "../utils";
8
+ import { create } from "@bufbuild/protobuf";
9
+ import { createSession, revokeSession, atomic, expectReceiptKind, createAction, sendAction, } from "../actions";
10
+ import { NordError } from "../error";
50
11
  /**
51
12
  * User class for interacting with the Nord protocol
52
13
  */
53
- class NordUser extends NordClient_1.NordClient {
14
+ export class NordUser {
15
+ nord;
16
+ sessionSignFn;
17
+ transactionSignFn;
18
+ sessionId;
19
+ sessionPubKey;
20
+ publicKey;
21
+ lastTs = 0;
22
+ nonce = 0;
23
+ /** User balances by token symbol */
24
+ balances = {};
25
+ /** User positions by account ID */
26
+ positions = {};
27
+ /** User margins by account ID */
28
+ margins = {};
29
+ /** User's account IDs */
30
+ accountIds;
31
+ /** SPL token information */
32
+ splTokenInfos = [];
54
33
  /**
55
34
  * Create a new NordUser instance
56
35
  *
57
- * @param params - Parameters for creating a NordUser
36
+ * @param nord - Nord client instance
37
+ * @param sessionSignFn - Function to sign messages with the user's session key
38
+ * @param transactionSignFn - Function to sign transactions with the user's wallet (optional)
39
+ * @param sessionId - Existing session identifier
40
+ * @param sessionPubKey - Session public key
41
+ * @param publicKey - Wallet public key
58
42
  * @throws {NordError} If required parameters are missing
59
43
  */
60
- constructor({ address, nord, publicKey, sessionPubKey, sessionSignFn, transactionSignFn, walletSignFn, connection, sessionId, }) {
61
- if (!walletSignFn) {
62
- throw new NordError_1.NordError("Wallet sign function is required");
63
- }
64
- if (!sessionSignFn) {
65
- throw new NordError_1.NordError("Session sign function is required");
66
- }
67
- if (!sessionPubKey) {
68
- throw new NordError_1.NordError("Session public key is required");
69
- }
70
- let parsedAddress;
71
- try {
72
- parsedAddress = new web3_js_1.PublicKey(address);
73
- }
74
- catch (error) {
75
- throw new NordError_1.NordError("Invalid Solana address", { cause: error });
76
- }
77
- super({
78
- nord,
79
- address: parsedAddress,
80
- walletSignFn,
81
- sessionSignFn,
82
- transactionSignFn,
83
- connection,
84
- sessionId,
85
- sessionPubKey,
86
- publicKey,
87
- });
88
- /** User balances by token symbol */
89
- this.balances = {};
90
- /** User positions by account ID */
91
- this.positions = {};
92
- /** User margins by account ID */
93
- this.margins = {};
94
- /** SPL token information */
95
- this.splTokenInfos = [];
44
+ constructor({ nord, sessionSignFn, transactionSignFn, sessionId, sessionPubKey, publicKey, }) {
45
+ this.nord = nord;
46
+ this.sessionSignFn = sessionSignFn;
47
+ this.transactionSignFn = transactionSignFn;
48
+ this.sessionId = sessionId;
49
+ this.sessionPubKey = new PublicKey(sessionPubKey);
50
+ this.publicKey = publicKey;
96
51
  // Convert tokens from info endpoint to SPLTokenInfo
97
52
  if (this.nord.tokens && this.nord.tokens.length > 0) {
98
53
  this.splTokenInfos = this.nord.tokens.map((token) => ({
@@ -103,85 +58,36 @@ class NordUser extends NordClient_1.NordClient {
103
58
  }));
104
59
  }
105
60
  }
106
- /**
107
- * Create a clone of this NordUser instance
108
- *
109
- * @returns A new NordUser instance with the same properties
110
- */
111
- clone() {
112
- const cloned = new NordUser({
113
- nord: this.nord,
114
- address: this.address.toBase58(),
115
- walletSignFn: this.walletSignFn,
116
- sessionSignFn: this.sessionSignFn,
117
- transactionSignFn: this.transactionSignFn,
118
- connection: this.connection,
119
- sessionPubKey: new Uint8Array(this.sessionPubKey),
120
- publicKey: this.publicKey,
121
- sessionId: this.sessionId,
122
- });
123
- // Copy other properties
124
- cloned.balances = { ...this.balances };
125
- cloned.positions = { ...this.positions };
126
- cloned.margins = { ...this.margins };
127
- cloned.accountIds = this.accountIds ? [...this.accountIds] : undefined;
128
- cloned.splTokenInfos = [...this.splTokenInfos];
129
- this.cloneClientState(cloned);
130
- return cloned;
131
- }
132
61
  /**
133
62
  * Create a NordUser from a private key
134
63
  *
135
64
  * @param nord - Nord instance
136
65
  * @param privateKey - Private key as string or Uint8Array
137
- * @param connection - Solana connection (optional)
138
66
  * @returns NordUser instance
139
67
  * @throws {NordError} If the private key is invalid
140
68
  */
141
- static fromPrivateKey(nord, privateKey, connection) {
69
+ static fromPrivateKey(nord, privateKey) {
142
70
  try {
143
- const keypair = (0, utils_1.keypairFromPrivateKey)(privateKey);
71
+ const keypair = keypairFromPrivateKey(privateKey);
144
72
  const publicKey = keypair.publicKey;
145
- // Create a signing function that uses the keypair but doesn't expose it
146
- const walletSignFn = async (message) => {
147
- function toHex(buffer) {
148
- return Array.from(buffer)
149
- .map((byte) => byte.toString(16).padStart(2, "0"))
150
- .join("");
151
- }
152
- const messageBuffer = new TextEncoder().encode(toHex(message));
153
- // Use ed25519 to sign the message
154
- const signature = ed.sign(messageBuffer, keypair.secretKey.slice(0, 32));
155
- return signature;
156
- };
157
73
  const sessionSignFn = async (message) => {
158
74
  // Use ed25519 to sign the message
159
75
  return ed.sign(message, keypair.secretKey.slice(0, 32));
160
76
  };
161
- // Create a transaction signing function
162
- const transactionSignFn = async (transaction) => {
163
- // This is a basic implementation - actual implementation would depend on the transaction type
164
- if (transaction.sign) {
165
- // Solana transaction
166
- transaction.sign(keypair);
167
- return transaction;
168
- }
169
- // For other transaction types, would need specific implementation
170
- throw new NordError_1.NordError("Unsupported transaction type for signing");
77
+ const transactionSignFn = async (tx) => {
78
+ tx.sign(keypair);
79
+ return tx;
171
80
  };
172
81
  return new NordUser({
173
82
  nord,
174
- address: publicKey.toBase58(),
175
- walletSignFn,
176
83
  sessionSignFn,
177
84
  transactionSignFn,
178
- connection,
179
85
  publicKey,
180
- sessionPubKey: publicKey.toBytes(), // Use the public key derived from the private key as the session public key
86
+ sessionPubKey: publicKey.toBytes(),
181
87
  });
182
88
  }
183
89
  catch (error) {
184
- throw new NordError_1.NordError("Failed to create NordUser from private key", {
90
+ throw new NordError("Failed to create NordUser from private key", {
185
91
  cause: error,
186
92
  });
187
93
  }
@@ -194,26 +100,23 @@ class NordUser extends NordClient_1.NordClient {
194
100
  * @throws {NordError} If required parameters are missing or operation fails
195
101
  */
196
102
  async getAssociatedTokenAccount(mint) {
197
- if (!this.getSolanaPublicKey()) {
198
- throw new NordError_1.NordError("Solana public key is required to get associated token account");
199
- }
200
103
  try {
201
104
  // Get the token program ID from the mint account
202
- const mintAccount = await this.connection.getAccountInfo(mint);
105
+ const mintAccount = await this.nord.solanaConnection.getAccountInfo(mint);
203
106
  if (!mintAccount) {
204
- throw new NordError_1.NordError("Mint account not found");
107
+ throw new NordError("Mint account not found");
205
108
  }
206
109
  const tokenProgramId = mintAccount.owner;
207
110
  // Validate that the mint is owned by a supported SPL token program
208
- if (!tokenProgramId.equals(spl_token_1.TOKEN_PROGRAM_ID) &&
209
- !tokenProgramId.equals(spl_token_1.TOKEN_2022_PROGRAM_ID)) {
210
- throw new NordError_1.NordError("Mint Account is not owned by a supported SPL token program");
111
+ if (!tokenProgramId.equals(TOKEN_PROGRAM_ID) &&
112
+ !tokenProgramId.equals(TOKEN_2022_PROGRAM_ID)) {
113
+ throw new NordError("Mint Account is not owned by a supported SPL token program");
211
114
  }
212
- const associatedTokenAddress = await (0, spl_token_1.getAssociatedTokenAddress)(mint, this.getSolanaPublicKey(), false, tokenProgramId, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
115
+ const associatedTokenAddress = await getAssociatedTokenAddress(mint, this.publicKey, false, tokenProgramId, ASSOCIATED_TOKEN_PROGRAM_ID);
213
116
  return associatedTokenAddress;
214
117
  }
215
118
  catch (error) {
216
- throw new NordError_1.NordError("Failed to get associated token account", {
119
+ throw new NordError("Failed to get associated token account", {
217
120
  cause: error,
218
121
  });
219
122
  }
@@ -246,30 +149,30 @@ class NordUser extends NordClient_1.NordClient {
246
149
  // Find the token info
247
150
  const tokenInfo = this.splTokenInfos.find((t) => t.tokenId === tokenId);
248
151
  if (!tokenInfo) {
249
- throw new NordError_1.NordError(`Token with ID ${tokenId} not found`);
152
+ throw new NordError(`Token with ID ${tokenId} not found`);
250
153
  }
251
- const mint = new web3_js_1.PublicKey(tokenInfo.mint);
154
+ const mint = new PublicKey(tokenInfo.mint);
252
155
  const fromAccount = await this.getAssociatedTokenAccount(mint);
253
- const payer = this.getSolanaPublicKey();
156
+ const payer = this.publicKey;
254
157
  const { ix, extraSigner } = await this.nord.protonClient.buildDepositIx({
255
158
  payer,
256
159
  recipient: recipient ?? payer,
257
- quantAmount: (0, proton_1.floatToScaledBigIntLossy)(amount, tokenInfo.precision),
160
+ quantAmount: floatToScaledBigIntLossy(amount, tokenInfo.precision),
258
161
  mint,
259
162
  sourceTokenAccount: fromAccount,
260
163
  });
261
- const { blockhash } = await this.connection.getLatestBlockhash();
262
- const tx = new web3_js_1.Transaction();
164
+ const { blockhash } = await this.nord.solanaConnection.getLatestBlockhash();
165
+ const tx = new Transaction();
263
166
  tx.add(ix);
264
167
  tx.recentBlockhash = blockhash;
265
168
  tx.feePayer = payer;
266
169
  const signedTx = await this.transactionSignFn(tx);
267
170
  signedTx.partialSign(extraSigner);
268
- const signature = await this.connection.sendRawTransaction(signedTx.serialize(), sendOptions);
171
+ const signature = await this.nord.solanaConnection.sendRawTransaction(signedTx.serialize(), sendOptions);
269
172
  return signature;
270
173
  }
271
174
  catch (error) {
272
- throw new NordError_1.NordError(`Failed to deposit ${amount} of token ID ${tokenId}`, { cause: error });
175
+ throw new NordError(`Failed to deposit ${amount} of token ID ${tokenId}`, { cause: error });
273
176
  }
274
177
  }
275
178
  /**
@@ -278,7 +181,7 @@ class NordUser extends NordClient_1.NordClient {
278
181
  * @returns Nonce as number
279
182
  */
280
183
  getNonce() {
281
- return this.nextActionNonce();
184
+ return ++this.nonce;
282
185
  }
283
186
  async submitSessionAction(kind) {
284
187
  return this.submitSignedAction(kind, async (message) => {
@@ -297,18 +200,18 @@ class NordUser extends NordClient_1.NordClient {
297
200
  async updateAccountId() {
298
201
  try {
299
202
  if (!this.publicKey) {
300
- throw new NordError_1.NordError("Public key is required to update account ID");
203
+ throw new NordError("Public key is required to update account ID");
301
204
  }
302
205
  const resp = await this.nord.getUser({
303
206
  pubkey: this.publicKey.toBase58(),
304
207
  });
305
208
  if (!resp) {
306
- throw new NordError_1.NordError(`User ${this.publicKey.toBase58()} not found`);
209
+ throw new NordError(`User ${this.publicKey.toBase58()} not found`);
307
210
  }
308
211
  this.accountIds = resp.accountIds;
309
212
  }
310
213
  catch (error) {
311
- throw new NordError_1.NordError("Failed to update account ID", { cause: error });
214
+ throw new NordError("Failed to update account ID", { cause: error });
312
215
  }
313
216
  }
314
217
  /**
@@ -319,7 +222,7 @@ class NordUser extends NordClient_1.NordClient {
319
222
  async fetchInfo() {
320
223
  if (this.accountIds !== undefined) {
321
224
  const accountsData = await Promise.all(this.accountIds.map(async (accountId) => {
322
- const response = await (0, utils_1.checkedFetch)(`${this.nord.webServerUrl}/account/${accountId}`);
225
+ const response = await checkedFetch(`${this.nord.webServerUrl}/account/${accountId}`);
323
226
  const accountData = (await response.json());
324
227
  // Ensure we have the correct accountId
325
228
  return {
@@ -350,8 +253,8 @@ class NordUser extends NordClient_1.NordClient {
350
253
  * @throws {NordError} If the operation fails
351
254
  */
352
255
  async refreshSession() {
353
- const result = await (0, actions_1.createSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
354
- userPubkey: (0, utils_1.optExpect)(this.publicKey.toBytes(), "No user's public key"),
256
+ const result = await createSession(this.nord.httpClient, this.transactionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
257
+ userPubkey: this.publicKey,
355
258
  sessionPubkey: this.sessionPubKey,
356
259
  });
357
260
  this.sessionId = result.sessionId;
@@ -364,12 +267,13 @@ class NordUser extends NordClient_1.NordClient {
364
267
  */
365
268
  async revokeSession(sessionId) {
366
269
  try {
367
- await (0, actions_1.revokeSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
270
+ await revokeSession(this.nord.httpClient, this.transactionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
271
+ userPubkey: this.publicKey,
368
272
  sessionId,
369
273
  });
370
274
  }
371
275
  catch (error) {
372
- throw new NordError_1.NordError(`Failed to revoke session ${sessionId}`, {
276
+ throw new NordError(`Failed to revoke session ${sessionId}`, {
373
277
  cause: error,
374
278
  });
375
279
  }
@@ -381,7 +285,7 @@ class NordUser extends NordClient_1.NordClient {
381
285
  */
382
286
  checkSessionValidity() {
383
287
  if (this.sessionId === undefined || this.sessionId === BigInt(0)) {
384
- throw new NordError_1.NordError("Invalid or empty session ID. Please create or refresh your session.");
288
+ throw new NordError("Invalid or empty session ID. Please create or refresh your session.");
385
289
  }
386
290
  }
387
291
  /**
@@ -394,70 +298,76 @@ class NordUser extends NordClient_1.NordClient {
394
298
  async withdraw({ amount, tokenId, }) {
395
299
  try {
396
300
  this.checkSessionValidity();
397
- const token = (0, utils_1.findToken)(this.nord.tokens, tokenId);
398
- const scaledAmount = (0, utils_1.toScaledU64)(amount, token.decimals);
301
+ const token = findToken(this.nord.tokens, tokenId);
302
+ const scaledAmount = toScaledU64(amount, token.decimals);
399
303
  if (scaledAmount <= 0n) {
400
- throw new NordError_1.NordError("Withdraw amount must be positive");
304
+ throw new NordError("Withdraw amount must be positive");
401
305
  }
402
306
  const receipt = await this.submitSessionAction({
403
307
  case: "withdraw",
404
- value: (0, protobuf_1.create)(proto.Action_WithdrawSchema, {
405
- sessionId: BigInt((0, utils_1.optExpect)(this.sessionId, "No session")),
308
+ value: create(proto.Action_WithdrawSchema, {
309
+ sessionId: BigInt(optExpect(this.sessionId, "No session")),
406
310
  tokenId,
407
311
  amount: scaledAmount,
408
312
  }),
409
313
  });
410
- (0, actions_1.expectReceiptKind)(receipt, "withdrawResult", "withdraw");
314
+ expectReceiptKind(receipt, "withdrawResult", "withdraw");
411
315
  return { actionId: receipt.actionId };
412
316
  }
413
317
  catch (error) {
414
- throw new NordError_1.NordError(`Failed to withdraw ${amount} of token ID ${tokenId}`, { cause: error });
318
+ throw new NordError(`Failed to withdraw ${amount} of token ID ${tokenId}`, { cause: error });
415
319
  }
416
320
  }
417
321
  /**
418
322
  * Place an order on the exchange
419
323
  *
420
- * @param params - Order parameters
324
+ * @param marketId - Target market identifier
325
+ * @param side - Order side
326
+ * @param fillMode - Fill mode (limit, market, etc.)
327
+ * @param isReduceOnly - Reduce-only flag
328
+ * @param size - Base size to place
329
+ * @param price - Limit price
330
+ * @param quoteSize - Quote-sized order representation
331
+ * @param accountId - Account executing the order
332
+ * @param clientOrderId - Optional client-specified identifier
421
333
  * @returns Object containing actionId, orderId (if posted), fills, and clientOrderId
422
334
  * @throws {NordError} If the operation fails
423
335
  */
424
- async placeOrder(params) {
336
+ async placeOrder({ marketId, side, fillMode, isReduceOnly, size, price, quoteSize, accountId, clientOrderId, }) {
425
337
  try {
426
338
  this.checkSessionValidity();
427
- const market = (0, utils_1.findMarket)(this.nord.markets, params.marketId);
339
+ const market = findMarket(this.nord.markets, marketId);
428
340
  if (!market) {
429
- throw new NordError_1.NordError(`Market with ID ${params.marketId} not found`);
341
+ throw new NordError(`Market with ID ${marketId} not found`);
430
342
  }
431
- const sessionId = (0, utils_1.optExpect)(this.sessionId, "No session");
432
- const price = (0, utils_1.toScaledU64)(params.price ?? 0, market.priceDecimals);
433
- const size = (0, utils_1.toScaledU64)(params.size ?? 0, market.sizeDecimals);
434
- const scaledQuote = params.quoteSize
435
- ? params.quoteSize.toWire(market.priceDecimals, market.sizeDecimals)
343
+ const sessionId = optExpect(this.sessionId, "No session");
344
+ const scaledPrice = toScaledU64(price ?? 0, market.priceDecimals);
345
+ const scaledSize = toScaledU64(size ?? 0, market.sizeDecimals);
346
+ const scaledQuote = quoteSize
347
+ ? quoteSize.toWire(market.priceDecimals, market.sizeDecimals)
436
348
  : undefined;
437
- (0, utils_1.assert)(price > 0n || size > 0n || scaledQuote !== undefined, "OrderLimit must include at least one of: size, price, or quoteSize");
349
+ assert(scaledPrice > 0n || scaledSize > 0n || scaledQuote !== undefined, "OrderLimit must include at least one of: size, price, or quoteSize");
438
350
  const receipt = await this.submitSessionAction({
439
351
  case: "placeOrder",
440
- value: (0, protobuf_1.create)(proto.Action_PlaceOrderSchema, {
352
+ value: create(proto.Action_PlaceOrderSchema, {
441
353
  sessionId: BigInt(sessionId),
442
- senderAccountId: params.accountId,
443
- marketId: params.marketId,
444
- side: params.side === types_1.Side.Bid ? proto.Side.BID : proto.Side.ASK,
445
- fillMode: (0, types_1.fillModeToProtoFillMode)(params.fillMode),
446
- isReduceOnly: params.isReduceOnly,
447
- price,
448
- size,
354
+ senderAccountId: accountId,
355
+ marketId,
356
+ side: side === Side.Bid ? proto.Side.BID : proto.Side.ASK,
357
+ fillMode: fillModeToProtoFillMode(fillMode),
358
+ isReduceOnly,
359
+ price: scaledPrice,
360
+ size: scaledSize,
449
361
  quoteSize: scaledQuote === undefined
450
362
  ? undefined
451
- : (0, protobuf_1.create)(proto.QuoteSizeSchema, {
363
+ : create(proto.QuoteSizeSchema, {
452
364
  size: scaledQuote.size,
453
365
  price: scaledQuote.price,
454
366
  }),
455
- clientOrderId: params.clientOrderId === undefined
456
- ? undefined
457
- : BigInt(params.clientOrderId),
367
+ clientOrderId: clientOrderId === undefined ? undefined : BigInt(clientOrderId),
458
368
  }),
459
369
  });
460
- (0, actions_1.expectReceiptKind)(receipt, "placeOrderResult", "place order");
370
+ expectReceiptKind(receipt, "placeOrderResult", "place order");
461
371
  const result = receipt.kind.value;
462
372
  return {
463
373
  actionId: receipt.actionId,
@@ -466,7 +376,7 @@ class NordUser extends NordClient_1.NordClient {
466
376
  };
467
377
  }
468
378
  catch (error) {
469
- throw new NordError_1.NordError("Failed to place order", { cause: error });
379
+ throw new NordError("Failed to place order", { cause: error });
470
380
  }
471
381
  }
472
382
  /**
@@ -483,13 +393,13 @@ class NordUser extends NordClient_1.NordClient {
483
393
  this.checkSessionValidity();
484
394
  const receipt = await this.submitSessionAction({
485
395
  case: "cancelOrderById",
486
- value: (0, protobuf_1.create)(proto.Action_CancelOrderByIdSchema, {
396
+ value: create(proto.Action_CancelOrderByIdSchema, {
487
397
  orderId: BigInt(orderId),
488
- sessionId: BigInt((0, utils_1.optExpect)(this.sessionId, "No session")),
398
+ sessionId: BigInt(optExpect(this.sessionId, "No session")),
489
399
  senderAccountId: accountId,
490
400
  }),
491
401
  });
492
- (0, actions_1.expectReceiptKind)(receipt, "cancelOrderResult", "cancel order");
402
+ expectReceiptKind(receipt, "cancelOrderResult", "cancel order");
493
403
  return {
494
404
  actionId: receipt.actionId,
495
405
  orderId: receipt.kind.value.orderId,
@@ -497,7 +407,7 @@ class NordUser extends NordClient_1.NordClient {
497
407
  };
498
408
  }
499
409
  catch (error) {
500
- throw new NordError_1.NordError(`Failed to cancel order ${orderId}`, {
410
+ throw new NordError(`Failed to cancel order ${orderId}`, {
501
411
  cause: error,
502
412
  });
503
413
  }
@@ -505,116 +415,137 @@ class NordUser extends NordClient_1.NordClient {
505
415
  /**
506
416
  * Add a trigger for the current session
507
417
  *
508
- * @param params - Trigger parameters including market, side, and prices
418
+ * @param marketId - Market to watch
419
+ * @param side - Order side for the trigger
420
+ * @param kind - Stop-loss or take-profit trigger type
421
+ * @param triggerPrice - Price that activates the trigger
422
+ * @param limitPrice - Limit price placed once the trigger fires
423
+ * @param accountId - Account executing the trigger
509
424
  * @returns Object containing the actionId of the submitted trigger
510
425
  * @throws {NordError} If the operation fails
511
426
  */
512
- async addTrigger(params) {
427
+ async addTrigger({ marketId, side, kind, triggerPrice, limitPrice, accountId, }) {
513
428
  try {
514
429
  this.checkSessionValidity();
515
- const market = (0, utils_1.findMarket)(this.nord.markets, params.marketId);
430
+ const market = findMarket(this.nord.markets, marketId);
516
431
  if (!market) {
517
- throw new NordError_1.NordError(`Market with ID ${params.marketId} not found`);
432
+ throw new NordError(`Market with ID ${marketId} not found`);
518
433
  }
519
- const triggerPrice = (0, utils_1.toScaledU64)(params.triggerPrice, market.priceDecimals);
520
- (0, utils_1.assert)(triggerPrice > 0n, "Trigger price must be positive");
521
- const limitPrice = params.limitPrice === undefined
434
+ const scaledTriggerPrice = toScaledU64(triggerPrice, market.priceDecimals);
435
+ assert(scaledTriggerPrice > 0n, "Trigger price must be positive");
436
+ const scaledLimitPrice = limitPrice === undefined
522
437
  ? undefined
523
- : (0, utils_1.toScaledU64)(params.limitPrice, market.priceDecimals);
524
- if (limitPrice !== undefined) {
525
- (0, utils_1.assert)(limitPrice > 0n, "Limit price must be positive");
438
+ : toScaledU64(limitPrice, market.priceDecimals);
439
+ if (scaledLimitPrice !== undefined) {
440
+ assert(scaledLimitPrice > 0n, "Limit price must be positive");
526
441
  }
527
- const key = (0, protobuf_1.create)(proto.TriggerKeySchema, {
528
- kind: params.kind === types_1.TriggerKind.StopLoss
442
+ const key = create(proto.TriggerKeySchema, {
443
+ kind: kind === TriggerKind.StopLoss
529
444
  ? proto.TriggerKind.STOP_LOSS
530
445
  : proto.TriggerKind.TAKE_PROFIT,
531
- side: params.side === types_1.Side.Bid ? proto.Side.BID : proto.Side.ASK,
446
+ side: side === Side.Bid ? proto.Side.BID : proto.Side.ASK,
532
447
  });
533
- const prices = (0, protobuf_1.create)(proto.Action_TriggerPricesSchema, {
534
- triggerPrice,
535
- limitPrice,
448
+ const prices = create(proto.Action_TriggerPricesSchema, {
449
+ triggerPrice: scaledTriggerPrice,
450
+ limitPrice: scaledLimitPrice,
536
451
  });
537
452
  const receipt = await this.submitSessionAction({
538
453
  case: "addTrigger",
539
- value: (0, protobuf_1.create)(proto.Action_AddTriggerSchema, {
540
- sessionId: BigInt((0, utils_1.optExpect)(this.sessionId, "No session")),
541
- marketId: params.marketId,
454
+ value: create(proto.Action_AddTriggerSchema, {
455
+ sessionId: BigInt(optExpect(this.sessionId, "No session")),
456
+ marketId,
542
457
  key,
543
458
  prices,
544
- accountId: params.accountId,
459
+ accountId,
545
460
  }),
546
461
  });
547
- (0, actions_1.expectReceiptKind)(receipt, "triggerAdded", "add trigger");
462
+ expectReceiptKind(receipt, "triggerAdded", "add trigger");
548
463
  return { actionId: receipt.actionId };
549
464
  }
550
465
  catch (error) {
551
- throw new NordError_1.NordError("Failed to add trigger", { cause: error });
466
+ throw new NordError("Failed to add trigger", { cause: error });
552
467
  }
553
468
  }
554
469
  /**
555
470
  * Remove a trigger for the current session
556
471
  *
557
- * @param params - Trigger parameters identifying the trigger to remove
472
+ * @param marketId - Market the trigger belongs to
473
+ * @param side - Order side for the trigger
474
+ * @param kind - Stop-loss or take-profit trigger type
475
+ * @param accountId - Account executing the trigger
558
476
  * @returns Object containing the actionId of the removal action
559
477
  * @throws {NordError} If the operation fails
560
478
  */
561
- async removeTrigger(params) {
479
+ async removeTrigger({ marketId, side, kind, accountId, }) {
562
480
  try {
563
481
  this.checkSessionValidity();
564
- const market = (0, utils_1.findMarket)(this.nord.markets, params.marketId);
482
+ const market = findMarket(this.nord.markets, marketId);
565
483
  if (!market) {
566
- throw new NordError_1.NordError(`Market with ID ${params.marketId} not found`);
484
+ throw new NordError(`Market with ID ${marketId} not found`);
567
485
  }
568
- const key = (0, protobuf_1.create)(proto.TriggerKeySchema, {
569
- kind: params.kind === types_1.TriggerKind.StopLoss
486
+ const key = create(proto.TriggerKeySchema, {
487
+ kind: kind === TriggerKind.StopLoss
570
488
  ? proto.TriggerKind.STOP_LOSS
571
489
  : proto.TriggerKind.TAKE_PROFIT,
572
- side: params.side === types_1.Side.Bid ? proto.Side.BID : proto.Side.ASK,
490
+ side: side === Side.Bid ? proto.Side.BID : proto.Side.ASK,
573
491
  });
574
492
  const receipt = await this.submitSessionAction({
575
493
  case: "removeTrigger",
576
- value: (0, protobuf_1.create)(proto.Action_RemoveTriggerSchema, {
577
- sessionId: BigInt((0, utils_1.optExpect)(this.sessionId, "No session")),
578
- marketId: params.marketId,
494
+ value: create(proto.Action_RemoveTriggerSchema, {
495
+ sessionId: BigInt(optExpect(this.sessionId, "No session")),
496
+ marketId,
579
497
  key,
580
- accountId: params.accountId,
498
+ accountId,
581
499
  }),
582
500
  });
583
- (0, actions_1.expectReceiptKind)(receipt, "triggerRemoved", "remove trigger");
501
+ expectReceiptKind(receipt, "triggerRemoved", "remove trigger");
584
502
  return { actionId: receipt.actionId };
585
503
  }
586
504
  catch (error) {
587
- throw new NordError_1.NordError("Failed to remove trigger", { cause: error });
505
+ throw new NordError("Failed to remove trigger", { cause: error });
588
506
  }
589
507
  }
590
508
  /**
591
509
  * Transfer tokens to another account
592
510
  *
593
- * @param params - Transfer parameters
511
+ * @param tokenId - Token identifier to move
512
+ * @param amount - Amount to transfer
513
+ * @param fromAccountId - Source account id
514
+ * @param toAccountId - Destination account id
594
515
  * @throws {NordError} If the operation fails
595
516
  */
596
- async transferToAccount(params) {
517
+ async transferToAccount({ tokenId, amount, fromAccountId, toAccountId, }) {
597
518
  try {
598
519
  this.checkSessionValidity();
599
- const token = (0, utils_1.findToken)(this.nord.tokens, params.tokenId);
600
- const amount = (0, utils_1.toScaledU64)(params.amount, token.decimals);
601
- if (amount <= 0n) {
602
- throw new NordError_1.NordError("Transfer amount must be positive");
520
+ const token = findToken(this.nord.tokens, tokenId);
521
+ const scaledAmount = toScaledU64(amount, token.decimals);
522
+ if (scaledAmount <= 0n) {
523
+ throw new NordError("Transfer amount must be positive");
603
524
  }
604
525
  const receipt = await this.submitSessionAction({
605
526
  case: "transfer",
606
- value: (0, protobuf_1.create)(proto.Action_TransferSchema, {
607
- sessionId: BigInt((0, utils_1.optExpect)(this.sessionId, "No session")),
608
- fromAccountId: (0, utils_1.optExpect)(params.fromAccountId, "No source account"),
609
- toAccountId: (0, utils_1.optExpect)(params.toAccountId, "No target account"),
610
- tokenId: params.tokenId,
611
- amount,
527
+ value: create(proto.Action_TransferSchema, {
528
+ sessionId: BigInt(optExpect(this.sessionId, "No session")),
529
+ fromAccountId: optExpect(fromAccountId, "No source account"),
530
+ toAccountId: optExpect(toAccountId, "No target account"),
531
+ tokenId,
532
+ amount: scaledAmount,
612
533
  }),
613
534
  });
614
- (0, actions_1.expectReceiptKind)(receipt, "transferred", "transfer tokens");
535
+ expectReceiptKind(receipt, "transferred", "transfer tokens");
536
+ if (receipt.kind.value.accountCreated) {
537
+ assert(receipt.kind.value.toUserAccount !== undefined, `toAccount must be defined on new account on ${receipt.kind.value}`);
538
+ return {
539
+ actionId: receipt.actionId,
540
+ newAccountId: receipt.kind.value.toUserAccount,
541
+ };
542
+ }
543
+ else {
544
+ return { actionId: receipt.actionId };
545
+ }
615
546
  }
616
547
  catch (error) {
617
- throw new NordError_1.NordError("Failed to transfer tokens", { cause: error });
548
+ throw new NordError("Failed to transfer tokens", { cause: error });
618
549
  }
619
550
  }
620
551
  /**
@@ -634,13 +565,13 @@ class NordUser extends NordClient_1.NordClient {
634
565
  this.checkSessionValidity();
635
566
  const accountId = providedAccountId != null ? providedAccountId : this.accountIds?.[0];
636
567
  if (accountId == null) {
637
- throw new NordError_1.NordError("Account ID is undefined. Make sure to call updateAccountId() before atomic operations.");
568
+ throw new NordError("Account ID is undefined. Make sure to call updateAccountId() before atomic operations.");
638
569
  }
639
570
  const apiActions = userActions.map((act) => {
640
571
  if (act.kind === "place") {
641
- const market = (0, utils_1.findMarket)(this.nord.markets, act.marketId);
572
+ const market = findMarket(this.nord.markets, act.marketId);
642
573
  if (!market) {
643
- throw new NordError_1.NordError(`Market ${act.marketId} not found`);
574
+ throw new NordError(`Market ${act.marketId} not found`);
644
575
  }
645
576
  return {
646
577
  kind: "place",
@@ -661,15 +592,15 @@ class NordUser extends NordClient_1.NordClient {
661
592
  orderId: act.orderId,
662
593
  };
663
594
  });
664
- const result = await (0, actions_1.atomic)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
665
- sessionId: (0, utils_1.optExpect)(this.sessionId, "No session"),
595
+ const result = await atomic(this.nord.httpClient, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
596
+ sessionId: optExpect(this.sessionId, "No session"),
666
597
  accountId: accountId,
667
598
  actions: apiActions,
668
599
  });
669
600
  return result;
670
601
  }
671
602
  catch (error) {
672
- throw new NordError_1.NordError("Atomic operation failed", { cause: error });
603
+ throw new NordError("Atomic operation failed", { cause: error });
673
604
  }
674
605
  }
675
606
  /**
@@ -718,17 +649,14 @@ class NordUser extends NordClient_1.NordClient {
718
649
  */
719
650
  async getSolanaBalances(options = {}) {
720
651
  const { includeZeroBalances = true, includeTokenAccounts = false, maxConcurrent = 5, maxRetries = 3, } = options;
721
- if (!this.connection || !this.getSolanaPublicKey()) {
722
- throw new NordError_1.NordError("Connection and Solana public key are required to get Solana balances");
723
- }
724
652
  const balances = {};
725
653
  const tokenAccounts = {};
726
654
  try {
727
655
  // Get SOL balance (native token)
728
- const solBalance = await this.retryWithBackoff(() => this.connection.getBalance(this.getSolanaPublicKey()), maxRetries);
656
+ const solBalance = await this.retryWithBackoff(() => this.nord.solanaConnection.getBalance(this.publicKey), maxRetries);
729
657
  balances["SOL"] = solBalance / 1e9; // Convert lamports to SOL
730
658
  if (includeTokenAccounts) {
731
- tokenAccounts["SOL"] = this.getSolanaPublicKey().toString();
659
+ tokenAccounts["SOL"] = this.publicKey.toString();
732
660
  }
733
661
  // Get SPL token balances using mintAddr from Nord tokens
734
662
  if (this.nord.tokens && this.nord.tokens.length > 0) {
@@ -739,13 +667,13 @@ class NordUser extends NordClient_1.NordClient {
739
667
  // Process batch in parallel
740
668
  const batchPromises = batch.map(async (token) => {
741
669
  try {
742
- const mint = new web3_js_1.PublicKey(token.mintAddr);
743
- const associatedTokenAddress = await this.retryWithBackoff(() => (0, spl_token_1.getAssociatedTokenAddress)(mint, this.getSolanaPublicKey()), maxRetries);
670
+ const mint = new PublicKey(token.mintAddr);
671
+ const associatedTokenAddress = await this.retryWithBackoff(() => getAssociatedTokenAddress(mint, this.publicKey), maxRetries);
744
672
  if (includeTokenAccounts) {
745
673
  tokenAccounts[token.symbol] = associatedTokenAddress.toString();
746
674
  }
747
675
  try {
748
- const tokenBalance = await this.retryWithBackoff(() => this.connection.getTokenAccountBalance(associatedTokenAddress), maxRetries);
676
+ const tokenBalance = await this.retryWithBackoff(() => this.nord.solanaConnection.getTokenAccountBalance(associatedTokenAddress), maxRetries);
749
677
  const balance = Number(tokenBalance.value.uiAmount);
750
678
  if (balance > 0 || includeZeroBalances) {
751
679
  balances[token.symbol] = balance;
@@ -772,10 +700,15 @@ class NordUser extends NordClient_1.NordClient {
772
700
  return includeTokenAccounts ? { balances, tokenAccounts } : { balances };
773
701
  }
774
702
  catch (error) {
775
- throw new NordError_1.NordError("Failed to get Solana token balances", {
703
+ throw new NordError("Failed to get Solana token balances", {
776
704
  cause: error,
777
705
  });
778
706
  }
779
707
  }
708
+ async submitSignedAction(kind, makeSignedMessage) {
709
+ const nonce = this.getNonce();
710
+ const currentTimestamp = await this.nord.getTimestamp();
711
+ const action = createAction(currentTimestamp, nonce, kind);
712
+ return sendAction(this.nord.httpClient, makeSignedMessage, action);
713
+ }
780
714
  }
781
- exports.NordUser = NordUser;