@n1xyz/nord-ts 0.0.18-8121ed05.0 → 0.0.19

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 (77) hide show
  1. package/.claude/settings.local.json +11 -0
  2. package/.local/qa.ts +77 -0
  3. package/.local/test-atomic.ts +112 -0
  4. package/check.sh +4 -0
  5. package/default.nix +47 -0
  6. package/package.json +20 -27
  7. package/src/index.ts +0 -16
  8. package/src/nord/api/actions.ts +131 -9
  9. package/src/nord/api/core.ts +0 -71
  10. package/src/nord/client/Nord.ts +142 -76
  11. package/src/nord/client/NordUser.ts +171 -50
  12. package/src/nord/index.ts +0 -2
  13. package/src/nord/models/Subscriber.ts +2 -2
  14. package/src/types.ts +55 -216
  15. package/src/utils.ts +6 -42
  16. package/src/websocket/NordWebSocketClient.ts +23 -15
  17. package/src/websocket/index.ts +1 -1
  18. package/tests/utils.spec.ts +1 -34
  19. package/dist/bridge/client.d.ts +0 -151
  20. package/dist/bridge/client.js +0 -434
  21. package/dist/bridge/const.d.ts +0 -23
  22. package/dist/bridge/const.js +0 -47
  23. package/dist/bridge/index.d.ts +0 -4
  24. package/dist/bridge/index.js +0 -23
  25. package/dist/bridge/types.d.ts +0 -120
  26. package/dist/bridge/types.js +0 -18
  27. package/dist/bridge/utils.d.ts +0 -64
  28. package/dist/bridge/utils.js +0 -131
  29. package/dist/const.d.ts +0 -8
  30. package/dist/const.js +0 -30
  31. package/dist/gen/common.d.ts +0 -68
  32. package/dist/gen/common.js +0 -215
  33. package/dist/gen/nord.d.ts +0 -853
  34. package/dist/gen/nord.js +0 -6368
  35. package/dist/idl/bridge.d.ts +0 -569
  36. package/dist/idl/bridge.js +0 -8
  37. package/dist/idl/bridge.json +0 -1506
  38. package/dist/idl/index.d.ts +0 -607
  39. package/dist/idl/index.js +0 -8
  40. package/dist/index.d.ts +0 -6
  41. package/dist/index.js +0 -30
  42. package/dist/nord/api/actions.d.ts +0 -106
  43. package/dist/nord/api/actions.js +0 -256
  44. package/dist/nord/api/core.d.ts +0 -49
  45. package/dist/nord/api/core.js +0 -164
  46. package/dist/nord/api/market.d.ts +0 -36
  47. package/dist/nord/api/market.js +0 -96
  48. package/dist/nord/api/metrics.d.ts +0 -67
  49. package/dist/nord/api/metrics.js +0 -229
  50. package/dist/nord/api/queries.d.ts +0 -46
  51. package/dist/nord/api/queries.js +0 -109
  52. package/dist/nord/client/Nord.d.ts +0 -284
  53. package/dist/nord/client/Nord.js +0 -491
  54. package/dist/nord/client/NordUser.d.ts +0 -287
  55. package/dist/nord/client/NordUser.js +0 -595
  56. package/dist/nord/index.d.ts +0 -9
  57. package/dist/nord/index.js +0 -33
  58. package/dist/nord/models/Subscriber.d.ts +0 -37
  59. package/dist/nord/models/Subscriber.js +0 -25
  60. package/dist/nord/utils/NordError.d.ts +0 -35
  61. package/dist/nord/utils/NordError.js +0 -49
  62. package/dist/types.d.ts +0 -407
  63. package/dist/types.js +0 -103
  64. package/dist/utils.d.ts +0 -116
  65. package/dist/utils.js +0 -271
  66. package/dist/websocket/NordWebSocketClient.d.ts +0 -68
  67. package/dist/websocket/NordWebSocketClient.js +0 -338
  68. package/dist/websocket/events.d.ts +0 -19
  69. package/dist/websocket/events.js +0 -2
  70. package/dist/websocket/index.d.ts +0 -2
  71. package/dist/websocket/index.js +0 -5
  72. package/jest.config.ts +0 -9
  73. package/nodemon.json +0 -4
  74. package/protoc-generate.sh +0 -23
  75. package/src/idl/bridge.json +0 -1506
  76. package/src/nord/api/market.ts +0 -122
  77. package/src/nord/api/queries.ts +0 -135
@@ -1,595 +0,0 @@
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 utils_1 = require("../../utils");
44
- const actions_1 = require("../api/actions");
45
- const NordError_1 = require("../utils/NordError");
46
- /**
47
- * User class for interacting with the Nord protocol
48
- */
49
- class NordUser {
50
- /**
51
- * Create a new NordUser instance
52
- *
53
- * @param params - Parameters for creating a NordUser
54
- * @throws {NordError} If required parameters are missing
55
- */
56
- constructor({ address, nord, publicKey, sessionPubKey, sessionSignFn, transactionSignFn, walletSignFn, connection, sessionId, }) {
57
- /** User balances by token symbol */
58
- this.balances = {};
59
- /** User orders by market symbol */
60
- this.orders = {};
61
- /** User positions by account ID */
62
- this.positions = {};
63
- /** User margins by account ID */
64
- this.margins = {};
65
- /** Last timestamp used */
66
- this.lastTs = 0;
67
- /** Last nonce used */
68
- this.lastNonce = 0;
69
- /** SPL token information */
70
- this.splTokenInfos = [];
71
- if (!walletSignFn) {
72
- throw new NordError_1.NordError("Wallet sign function is required");
73
- }
74
- if (!sessionSignFn) {
75
- throw new NordError_1.NordError("Session sign function is required");
76
- }
77
- if (!sessionPubKey) {
78
- throw new NordError_1.NordError("Session public key is required");
79
- }
80
- try {
81
- this.address = new web3_js_1.PublicKey(address);
82
- }
83
- catch (error) {
84
- throw new NordError_1.NordError("Invalid Solana address", { cause: error });
85
- }
86
- this.nord = nord;
87
- this.walletSignFn = walletSignFn;
88
- this.sessionSignFn = sessionSignFn;
89
- this.transactionSignFn = transactionSignFn;
90
- this.sessionPubKey = sessionPubKey;
91
- this.publicKey = publicKey;
92
- this.connection =
93
- connection ||
94
- new web3_js_1.Connection(nord.solanaUrl, {
95
- commitment: "confirmed",
96
- });
97
- // Set sessionId if provided
98
- if (sessionId !== undefined) {
99
- this.sessionId = sessionId;
100
- }
101
- // Convert tokens from info endpoint to SPLTokenInfo
102
- if (this.nord.tokens && this.nord.tokens.length > 0) {
103
- this.splTokenInfos = this.nord.tokens.map((token) => ({
104
- mint: token.mintAddr, // Use mintAddr as mint
105
- precision: token.decimals,
106
- tokenId: token.tokenId,
107
- name: token.symbol,
108
- }));
109
- }
110
- }
111
- /**
112
- * Create a clone of this NordUser instance
113
- *
114
- * @returns A new NordUser instance with the same properties
115
- */
116
- clone() {
117
- const cloned = new NordUser({
118
- nord: this.nord,
119
- address: this.address.toBase58(),
120
- walletSignFn: this.walletSignFn,
121
- sessionSignFn: this.sessionSignFn,
122
- transactionSignFn: this.transactionSignFn,
123
- connection: this.connection,
124
- sessionPubKey: this.sessionPubKey,
125
- publicKey: this.publicKey,
126
- });
127
- // Copy other properties
128
- cloned.balances = { ...this.balances };
129
- cloned.orders = { ...this.orders };
130
- cloned.positions = { ...this.positions };
131
- cloned.margins = { ...this.margins };
132
- cloned.accountIds = this.accountIds ? [...this.accountIds] : undefined;
133
- cloned.sessionId = this.sessionId;
134
- cloned.publicKey = this.publicKey;
135
- cloned.lastTs = this.lastTs;
136
- cloned.lastNonce = this.lastNonce;
137
- cloned.splTokenInfos = [...this.splTokenInfos];
138
- return cloned;
139
- }
140
- /**
141
- * Create a NordUser from a private key
142
- *
143
- * @param nord - Nord instance
144
- * @param privateKey - Private key as string or Uint8Array
145
- * @param connection - Solana connection (optional)
146
- * @returns NordUser instance
147
- * @throws {NordError} If the private key is invalid
148
- */
149
- static fromPrivateKey(nord, privateKey, connection) {
150
- try {
151
- const keypair = (0, utils_1.keypairFromPrivateKey)(privateKey);
152
- const publicKey = keypair.publicKey;
153
- // Create a signing function that uses the keypair but doesn't expose it
154
- const walletSignFn = async (message) => {
155
- function toHex(buffer) {
156
- return Array.from(buffer)
157
- .map((byte) => byte.toString(16).padStart(2, "0"))
158
- .join("");
159
- }
160
- const messageBuffer = new TextEncoder().encode(toHex(message));
161
- // Use ed25519 to sign the message
162
- const signature = ed.sign(messageBuffer, keypair.secretKey.slice(0, 32));
163
- return signature;
164
- };
165
- const sessionSignFn = async (message) => {
166
- // Use ed25519 to sign the message
167
- return ed.sign(message, keypair.secretKey.slice(0, 32));
168
- };
169
- // Create a transaction signing function
170
- const transactionSignFn = async (transaction) => {
171
- // This is a basic implementation - actual implementation would depend on the transaction type
172
- if (transaction.sign) {
173
- // Solana transaction
174
- transaction.sign(keypair);
175
- return transaction;
176
- }
177
- // For other transaction types, would need specific implementation
178
- throw new NordError_1.NordError("Unsupported transaction type for signing");
179
- };
180
- return new NordUser({
181
- nord,
182
- address: publicKey.toBase58(),
183
- walletSignFn,
184
- sessionSignFn,
185
- transactionSignFn,
186
- connection,
187
- publicKey,
188
- sessionPubKey: publicKey.toBytes(), // Use the public key derived from the private key as the session public key
189
- });
190
- }
191
- catch (error) {
192
- throw new NordError_1.NordError("Failed to create NordUser from private key", {
193
- cause: error,
194
- });
195
- }
196
- }
197
- /**
198
- * Get the associated token account for a token mint
199
- *
200
- * @param mint - Token mint address
201
- * @returns Associated token account address
202
- * @throws {NordError} If required parameters are missing or operation fails
203
- */
204
- async getAssociatedTokenAccount(mint) {
205
- if (!this.getSolanaPublicKey()) {
206
- throw new NordError_1.NordError("Solana public key is required to get associated token account");
207
- }
208
- try {
209
- // Get the token program ID from the mint account
210
- const mintAccount = await this.connection.getAccountInfo(mint);
211
- if (!mintAccount) {
212
- throw new NordError_1.NordError("Mint account not found");
213
- }
214
- const tokenProgramId = mintAccount.owner;
215
- // Validate that the mint is owned by a supported SPL token program
216
- if (!tokenProgramId.equals(spl_token_1.TOKEN_PROGRAM_ID) &&
217
- !tokenProgramId.equals(spl_token_1.TOKEN_2022_PROGRAM_ID)) {
218
- throw new NordError_1.NordError("Mint Account is not owned by a supported SPL token program");
219
- }
220
- const associatedTokenAddress = await (0, spl_token_1.getAssociatedTokenAddress)(mint, this.getSolanaPublicKey(), false, tokenProgramId, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
221
- return associatedTokenAddress;
222
- }
223
- catch (error) {
224
- throw new NordError_1.NordError("Failed to get associated token account", {
225
- cause: error,
226
- });
227
- }
228
- }
229
- /**
230
- * Deposit SPL tokens to the bridge
231
- *
232
- * @param amount - Amount to deposit
233
- * @param tokenId - Token ID
234
- * @returns Transaction signature
235
- * @throws {NordError} If required parameters are missing or operation fails
236
- */
237
- async depositSpl(amount, tokenId) {
238
- try {
239
- // Find the token info
240
- const tokenInfo = this.splTokenInfos.find((t) => t.tokenId === tokenId);
241
- if (!tokenInfo) {
242
- throw new NordError_1.NordError(`Token with ID ${tokenId} not found`);
243
- }
244
- const mint = new web3_js_1.PublicKey(tokenInfo.mint);
245
- // Get the user's token account
246
- const fromAccount = await this.getAssociatedTokenAccount(mint);
247
- // Convert amount to BN with proper decimals
248
- const amountBN = (0, proton_1.floatToBn)(amount, tokenInfo.precision);
249
- // Create deposit parameters
250
- const depositParams = {
251
- amount: amountBN,
252
- mint,
253
- fromAccount,
254
- };
255
- // Build the deposit transaction using proton client
256
- const depositTx = await this.nord.protonClient.buildDepositTx(depositParams, this.getSolanaPublicKey(), this.connection);
257
- const { blockhash } = await this.connection.getLatestBlockhash();
258
- depositTx.recentBlockhash = blockhash;
259
- depositTx.feePayer = this.getSolanaPublicKey();
260
- const signedTx = await this.transactionSignFn(depositTx);
261
- // TODO: should use `VersionedTransaction` and remove any for `transactionSignFn`,
262
- // this is incredibly annoying to debug and i could've saved 30 mins.
263
- const signature = await this.connection.sendRawTransaction(signedTx.serialize());
264
- return signature;
265
- }
266
- catch (error) {
267
- throw new NordError_1.NordError(`Failed to deposit ${amount} of token ID ${tokenId}`, { cause: error });
268
- }
269
- }
270
- /**
271
- * Get a new nonce for actions
272
- *
273
- * @returns Nonce as number
274
- */
275
- getNonce() {
276
- return ++this.lastNonce;
277
- }
278
- /**
279
- * Update account IDs for this user
280
- *
281
- * @throws {NordError} If the operation fails
282
- */
283
- async updateAccountId() {
284
- try {
285
- if (!this.publicKey) {
286
- throw new NordError_1.NordError("Public key is required to update account ID");
287
- }
288
- const resp = await this.nord.getUserAccountIds({
289
- pubkey: this.publicKey.toBase58(),
290
- });
291
- this.accountIds = resp.accountIds;
292
- }
293
- catch (error) {
294
- throw new NordError_1.NordError("Failed to update account ID", { cause: error });
295
- }
296
- }
297
- /**
298
- * Fetch user information including balances and orders
299
- *
300
- * @throws {NordError} If the operation fails
301
- */
302
- async fetchInfo() {
303
- if (this.accountIds !== undefined) {
304
- const accountsData = await Promise.all(this.accountIds.map(async (accountId) => {
305
- const response = await (0, utils_1.checkedFetch)(`${this.nord.webServerUrl}/account/${accountId}`);
306
- const accountData = (await response.json());
307
- // Ensure we have the correct accountId
308
- return {
309
- ...accountData,
310
- accountId,
311
- };
312
- }));
313
- for (const accountData of accountsData) {
314
- // Process balances
315
- this.balances[accountData.accountId] = [];
316
- for (const balance of accountData.balances) {
317
- this.balances[accountData.accountId].push({
318
- accountId: accountData.accountId,
319
- balance: balance.amount,
320
- symbol: balance.token,
321
- });
322
- }
323
- // Process orders
324
- this.orders[accountData.accountId] = accountData.orders.map((order) => {
325
- return {
326
- orderId: order.orderId,
327
- isLong: order.side === "bid",
328
- size: order.size,
329
- price: order.price,
330
- marketId: order.marketId,
331
- };
332
- });
333
- // Process positions
334
- this.positions[accountData.accountId] = accountData.positions;
335
- // Process margins
336
- this.margins[accountData.accountId] = accountData.margins;
337
- }
338
- }
339
- }
340
- /**
341
- * Refresh the user's session
342
- *
343
- * @throws {NordError} If the operation fails
344
- */
345
- async refreshSession() {
346
- console.log(this.publicKey);
347
- this.sessionId = await (0, actions_1.createSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
348
- userPubkey: (0, utils_1.optExpect)(this.publicKey.toBytes(), "No user's public key"),
349
- sessionPubkey: this.sessionPubKey,
350
- });
351
- }
352
- /**
353
- * Revoke a session
354
- *
355
- * @param sessionId - Session ID to revoke
356
- * @throws {NordError} If the operation fails
357
- */
358
- async revokeSession(sessionId) {
359
- try {
360
- await (0, actions_1.revokeSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
361
- sessionId,
362
- });
363
- }
364
- catch (error) {
365
- throw new NordError_1.NordError(`Failed to revoke session ${sessionId}`, {
366
- cause: error,
367
- });
368
- }
369
- }
370
- /**
371
- * Checks if the session is valid
372
- * @private
373
- * @throws {NordError} If the session is not valid
374
- */
375
- checkSessionValidity() {
376
- if (this.sessionId === undefined || this.sessionId === BigInt(0)) {
377
- throw new NordError_1.NordError("Invalid or empty session ID. Please create or refresh your session.");
378
- }
379
- }
380
- /**
381
- * Withdraw tokens from the exchange
382
- *
383
- * @param tokenId - Token ID to withdraw
384
- * @param amount - Amount to withdraw
385
- * @throws {NordError} If the operation fails
386
- */
387
- async withdraw(tokenId, amount) {
388
- try {
389
- this.checkSessionValidity();
390
- const { actionId } = await (0, actions_1.withdraw)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
391
- sizeDecimals: (0, utils_1.findToken)(this.nord.tokens, tokenId).decimals,
392
- sessionId: (0, utils_1.optExpect)(this.sessionId, "No session"),
393
- tokenId: tokenId,
394
- amount,
395
- });
396
- return { actionId };
397
- }
398
- catch (error) {
399
- throw new NordError_1.NordError(`Failed to withdraw ${amount} of token ID ${tokenId}`, { cause: error });
400
- }
401
- }
402
- /**
403
- * Place an order on the exchange
404
- *
405
- * @param params - Order parameters
406
- * @returns Order ID if successful
407
- * @throws {NordError} If the operation fails
408
- */
409
- async placeOrder(params) {
410
- try {
411
- this.checkSessionValidity();
412
- const market = (0, utils_1.findMarket)(this.nord.markets, params.marketId);
413
- if (!market) {
414
- throw new NordError_1.NordError(`Market with ID ${params.marketId} not found`);
415
- }
416
- return (0, actions_1.placeOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
417
- sessionId: (0, utils_1.optExpect)(this.sessionId, "No session"),
418
- senderId: params.accountId,
419
- sizeDecimals: market.sizeDecimals,
420
- priceDecimals: market.priceDecimals,
421
- marketId: params.marketId,
422
- side: params.side,
423
- fillMode: params.fillMode,
424
- isReduceOnly: params.isReduceOnly,
425
- size: params.size,
426
- price: params.price,
427
- quoteSize: params.quoteSize,
428
- });
429
- }
430
- catch (error) {
431
- throw new NordError_1.NordError("Failed to place order", { cause: error });
432
- }
433
- }
434
- /**
435
- * Cancel an order
436
- *
437
- * @param orderId - Order ID to cancel
438
- * @param providedAccountId - Account ID that placed the order
439
- * @returns Action ID if successful
440
- * @throws {NordError} If the operation fails
441
- */
442
- async cancelOrder(orderId, providedAccountId) {
443
- const accountId = providedAccountId != null ? providedAccountId : this.accountIds?.[0];
444
- try {
445
- this.checkSessionValidity();
446
- return (0, actions_1.cancelOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
447
- sessionId: (0, utils_1.optExpect)(this.sessionId, "No session"),
448
- senderId: accountId,
449
- orderId,
450
- });
451
- }
452
- catch (error) {
453
- throw new NordError_1.NordError(`Failed to cancel order ${orderId}`, {
454
- cause: error,
455
- });
456
- }
457
- }
458
- /**
459
- * Transfer tokens to another account
460
- *
461
- * @param params - Transfer parameters
462
- * @throws {NordError} If the operation fails
463
- */
464
- async transferToAccount(params) {
465
- try {
466
- this.checkSessionValidity();
467
- const token = (0, utils_1.findToken)(this.nord.tokens, params.tokenId);
468
- await (0, actions_1.transfer)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
469
- sessionId: (0, utils_1.optExpect)(this.sessionId, "No session"),
470
- fromAccountId: (0, utils_1.optExpect)(params.fromAccountId, "No source account"),
471
- toAccountId: (0, utils_1.optExpect)(params.toAccountId, "No target account"),
472
- tokenId: params.tokenId,
473
- tokenDecimals: token.decimals,
474
- amount: params.amount,
475
- });
476
- }
477
- catch (error) {
478
- throw new NordError_1.NordError("Failed to transfer tokens", { cause: error });
479
- }
480
- }
481
- /**
482
- * Helper function to retry a promise with exponential backoff
483
- *
484
- * @param fn - Function to retry
485
- * @param maxRetries - Maximum number of retries
486
- * @param initialDelay - Initial delay in milliseconds
487
- * @returns Promise result
488
- */
489
- async retryWithBackoff(fn, maxRetries = 3, initialDelay = 500) {
490
- let retries = 0;
491
- let delay = initialDelay;
492
- while (true) {
493
- try {
494
- return await fn();
495
- }
496
- catch (error) {
497
- if (retries >= maxRetries) {
498
- throw error;
499
- }
500
- // Check if error is rate limiting related
501
- const isRateLimitError = error instanceof Error &&
502
- (error.message.includes("rate limit") ||
503
- error.message.includes("429") ||
504
- error.message.includes("too many requests"));
505
- if (!isRateLimitError) {
506
- throw error;
507
- }
508
- retries++;
509
- await new Promise((resolve) => setTimeout(resolve, delay));
510
- delay *= 2; // Exponential backoff
511
- }
512
- }
513
- }
514
- /**
515
- * Get user's token balances on Solana chain using mintAddr
516
- *
517
- * @param options - Optional parameters
518
- * @param options.includeZeroBalances - Whether to include tokens with zero balance (default: true)
519
- * @param options.includeTokenAccounts - Whether to include token account addresses in the result (default: false)
520
- * @param options.maxConcurrent - Maximum number of concurrent requests (default: 5)
521
- * @param options.maxRetries - Maximum number of retries for rate-limited requests (default: 3)
522
- * @returns Object with token balances and optional token account addresses
523
- * @throws {NordError} If required parameters are missing or operation fails
524
- */
525
- async getSolanaBalances(options = {}) {
526
- const { includeZeroBalances = true, includeTokenAccounts = false, maxConcurrent = 5, maxRetries = 3, } = options;
527
- if (!this.connection || !this.getSolanaPublicKey()) {
528
- throw new NordError_1.NordError("Connection and Solana public key are required to get Solana balances");
529
- }
530
- const balances = {};
531
- const tokenAccounts = {};
532
- try {
533
- // Get SOL balance (native token)
534
- const solBalance = await this.retryWithBackoff(() => this.connection.getBalance(this.getSolanaPublicKey()), maxRetries);
535
- balances["SOL"] = solBalance / 1e9; // Convert lamports to SOL
536
- if (includeTokenAccounts) {
537
- tokenAccounts["SOL"] = this.getSolanaPublicKey().toString();
538
- }
539
- // Get SPL token balances using mintAddr from Nord tokens
540
- if (this.nord.tokens && this.nord.tokens.length > 0) {
541
- const tokens = this.nord.tokens.filter((token) => !!token.mintAddr);
542
- // Process tokens in batches to avoid rate limiting
543
- for (let i = 0; i < tokens.length; i += maxConcurrent) {
544
- const batch = tokens.slice(i, i + maxConcurrent);
545
- // Process batch in parallel
546
- const batchPromises = batch.map(async (token) => {
547
- try {
548
- const mint = new web3_js_1.PublicKey(token.mintAddr);
549
- const associatedTokenAddress = await this.retryWithBackoff(() => (0, spl_token_1.getAssociatedTokenAddress)(mint, this.getSolanaPublicKey()), maxRetries);
550
- if (includeTokenAccounts) {
551
- tokenAccounts[token.symbol] = associatedTokenAddress.toString();
552
- }
553
- try {
554
- const tokenBalance = await this.retryWithBackoff(() => this.connection.getTokenAccountBalance(associatedTokenAddress), maxRetries);
555
- const balance = Number(tokenBalance.value.uiAmount);
556
- if (balance > 0 || includeZeroBalances) {
557
- balances[token.symbol] = balance;
558
- }
559
- }
560
- catch {
561
- // Token account might not exist yet, set balance to 0
562
- if (includeZeroBalances) {
563
- balances[token.symbol] = 0;
564
- }
565
- }
566
- }
567
- catch (error) {
568
- console.error(`Error getting balance for token ${token.symbol}:`, error);
569
- if (includeZeroBalances) {
570
- balances[token.symbol] = 0;
571
- }
572
- }
573
- });
574
- // Wait for current batch to complete before processing next batch
575
- await Promise.all(batchPromises);
576
- }
577
- }
578
- return includeTokenAccounts ? { balances, tokenAccounts } : { balances };
579
- }
580
- catch (error) {
581
- throw new NordError_1.NordError("Failed to get Solana token balances", {
582
- cause: error,
583
- });
584
- }
585
- }
586
- /**
587
- * Get the Solana public key derived from the address
588
- *
589
- * @returns The Solana public key
590
- */
591
- getSolanaPublicKey() {
592
- return this.address;
593
- }
594
- }
595
- exports.NordUser = NordUser;
@@ -1,9 +0,0 @@
1
- export { Nord } from "./client/Nord";
2
- export { NordUser } from "./client/NordUser";
3
- export { NordError } from "./utils/NordError";
4
- export * from "./api/core";
5
- export * from "./api/metrics";
6
- export * from "./api/queries";
7
- export * from "./api/market";
8
- export * from "./api/actions";
9
- export * from "./models/Subscriber";
@@ -1,33 +0,0 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.NordError = exports.NordUser = exports.Nord = void 0;
18
- // Export main client classes
19
- var Nord_1 = require("./client/Nord");
20
- Object.defineProperty(exports, "Nord", { enumerable: true, get: function () { return Nord_1.Nord; } });
21
- var NordUser_1 = require("./client/NordUser");
22
- Object.defineProperty(exports, "NordUser", { enumerable: true, get: function () { return NordUser_1.NordUser; } });
23
- // Export utility classes
24
- var NordError_1 = require("./utils/NordError");
25
- Object.defineProperty(exports, "NordError", { enumerable: true, get: function () { return NordError_1.NordError; } });
26
- // Export API modules
27
- __exportStar(require("./api/core"), exports);
28
- __exportStar(require("./api/metrics"), exports);
29
- __exportStar(require("./api/queries"), exports);
30
- __exportStar(require("./api/market"), exports);
31
- __exportStar(require("./api/actions"), exports);
32
- // Export models
33
- __exportStar(require("./models/Subscriber"), exports);
@@ -1,37 +0,0 @@
1
- import { EventEmitter } from "events";
2
- import { Account, DeltaEvent, OrderbookResponse, SubscriberConfig, Trade, Trades } from "../../types";
3
- /**
4
- * Subscriber class for handling WebSocket subscriptions
5
- */
6
- export declare class Subscriber {
7
- streamURL: string;
8
- buffer: (DeltaEvent | Trades | Account)[];
9
- maxBufferLen: number;
10
- /**
11
- * Create a new Subscriber instance
12
- * @param config Subscriber configuration
13
- */
14
- constructor(config: SubscriberConfig);
15
- /**
16
- * Subscribe to WebSocket events
17
- */
18
- subscribe(): void;
19
- }
20
- /**
21
- * Interface for orderbook subscription
22
- */
23
- export interface OrderbookSubscription extends EventEmitter {
24
- on(event: "message", listener: (data: OrderbookResponse) => void): this;
25
- on(event: "error", listener: (error: Error) => void): this;
26
- close(): void;
27
- removeAllListeners(event?: string): this;
28
- }
29
- /**
30
- * Interface for trade subscription
31
- */
32
- export interface TradeSubscription extends EventEmitter {
33
- on(event: "message", listener: (data: Trade[]) => void): this;
34
- on(event: "error", listener: (error: Error) => void): this;
35
- close(): void;
36
- removeAllListeners(event?: string): this;
37
- }