@n1xyz/nord-ts 0.0.1 → 0.0.5

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 (260) hide show
  1. package/README.md +148 -65
  2. package/dist/bridge/client.d.ts +150 -0
  3. package/dist/bridge/client.js +394 -0
  4. package/dist/bridge/const.d.ts +23 -0
  5. package/dist/bridge/const.js +47 -0
  6. package/dist/bridge/index.d.ts +5 -0
  7. package/dist/bridge/index.js +23 -0
  8. package/dist/bridge/types.d.ts +118 -0
  9. package/dist/bridge/types.js +16 -0
  10. package/dist/bridge/utils.d.ts +64 -0
  11. package/dist/bridge/utils.js +131 -0
  12. package/dist/const.d.ts +2 -5
  13. package/dist/const.js +2 -6
  14. package/dist/gen/common.d.ts +6 -1
  15. package/dist/gen/common.js +19 -9
  16. package/dist/gen/nord.d.ts +76 -21
  17. package/dist/gen/nord.js +987 -423
  18. package/dist/idl/bridge.d.ts +2 -0
  19. package/dist/idl/bridge.js +703 -0
  20. package/dist/index.d.ts +5 -2
  21. package/dist/index.js +18 -2
  22. package/dist/nord/{actions.d.ts → api/actions.d.ts} +6 -6
  23. package/dist/nord/{actions.js → api/actions.js} +6 -10
  24. package/dist/nord/api/core.d.ts +49 -0
  25. package/dist/nord/api/core.js +121 -0
  26. package/dist/nord/api/market.d.ts +36 -0
  27. package/dist/nord/api/market.js +98 -0
  28. package/dist/nord/api/metrics.d.ts +67 -0
  29. package/dist/nord/api/metrics.js +132 -0
  30. package/dist/nord/api/queries.d.ts +81 -0
  31. package/dist/nord/api/queries.js +187 -0
  32. package/dist/nord/client/Nord.d.ts +335 -0
  33. package/dist/nord/client/Nord.js +532 -0
  34. package/dist/nord/client/NordUser.d.ts +320 -0
  35. package/dist/nord/client/NordUser.js +697 -0
  36. package/dist/nord/index.d.ts +9 -2
  37. package/dist/nord/index.js +30 -6
  38. package/dist/nord/models/Subscriber.d.ts +37 -0
  39. package/dist/nord/models/Subscriber.js +25 -0
  40. package/dist/nord/utils/NordError.d.ts +35 -0
  41. package/dist/nord/utils/NordError.js +46 -0
  42. package/dist/types.d.ts +143 -86
  43. package/dist/types.js +12 -1
  44. package/dist/utils.d.ts +9 -0
  45. package/dist/utils.js +20 -1
  46. package/dist/websocket/NordWebSocketClient.d.ts +71 -0
  47. package/dist/websocket/NordWebSocketClient.js +343 -0
  48. package/dist/websocket/events.d.ts +19 -0
  49. package/dist/websocket/events.js +2 -0
  50. package/dist/websocket/index.d.ts +2 -0
  51. package/dist/websocket/index.js +5 -0
  52. package/docs/assets/hierarchy.js +1 -0
  53. package/docs/assets/highlight.css +16 -16
  54. package/docs/assets/icons.js +17 -14
  55. package/docs/assets/icons.svg +1 -1
  56. package/docs/assets/main.js +5 -4
  57. package/docs/assets/navigation.js +1 -1
  58. package/docs/assets/search.js +1 -1
  59. package/docs/assets/style.css +1423 -1227
  60. package/docs/classes/Nord.html +189 -43
  61. package/docs/classes/NordError.html +24 -0
  62. package/docs/classes/NordUser.html +120 -35
  63. package/docs/classes/NordWebSocketClient.html +335 -0
  64. package/docs/classes/SolanaBridgeClient.html +86 -0
  65. package/docs/classes/Subscriber.html +10 -6
  66. package/docs/enums/FillMode.html +5 -5
  67. package/docs/enums/KeyType.html +4 -4
  68. package/docs/enums/MetricPeriod.html +9 -0
  69. package/docs/enums/PdaSeedType.html +9 -0
  70. package/docs/enums/PeakTpsPeriodUnit.html +7 -7
  71. package/docs/enums/Side.html +3 -3
  72. package/docs/enums/WebSocketMessageType.html +7 -0
  73. package/docs/functions/actionQueryRollman.html +6 -0
  74. package/docs/functions/actionsQueryRollman.html +6 -0
  75. package/docs/functions/aggregateMetrics-1.html +7 -0
  76. package/docs/functions/assert.html +1 -1
  77. package/docs/functions/bigIntToProtoU128.html +3 -3
  78. package/docs/functions/blockQueryRollman.html +6 -0
  79. package/docs/functions/blockSummaryQueryRollman.html +6 -0
  80. package/docs/functions/bridgeToBN.html +5 -0
  81. package/docs/functions/bufferToHex.html +4 -0
  82. package/docs/functions/cancelOrder.html +1 -0
  83. package/docs/functions/checkPubKeyLength.html +1 -1
  84. package/docs/functions/checkedFetch.html +4 -4
  85. package/docs/functions/createSession.html +1 -0
  86. package/docs/functions/decodeLengthDelimited.html +7 -6
  87. package/docs/functions/encodeLengthDelimited.html +4 -4
  88. package/docs/functions/fillModeToProtoFillMode.html +4 -4
  89. package/docs/functions/findMarket.html +1 -1
  90. package/docs/functions/findPda.html +6 -0
  91. package/docs/functions/findToken.html +1 -1
  92. package/docs/functions/fromBN.html +5 -0
  93. package/docs/functions/getAccount.html +6 -0
  94. package/docs/functions/getActionNonce.html +5 -0
  95. package/docs/functions/getCurrentTps.html +6 -0
  96. package/docs/functions/getInfo.html +5 -0
  97. package/docs/functions/getMedianLatency.html +6 -0
  98. package/docs/functions/getOrderbook.html +6 -0
  99. package/docs/functions/getPeakTps.html +6 -0
  100. package/docs/functions/getTimestamp.html +5 -0
  101. package/docs/functions/getTotalTransactions.html +5 -0
  102. package/docs/functions/getTrades.html +6 -0
  103. package/docs/functions/getUserAccountIds.html +6 -0
  104. package/docs/functions/hexToBuffer.html +4 -0
  105. package/docs/functions/initWebSocketClient.html +12 -0
  106. package/docs/functions/keypairFromPrivateKey.html +4 -0
  107. package/docs/functions/makeSigningFunction.html +4 -0
  108. package/docs/functions/makeWalletSignFn.html +5 -5
  109. package/docs/functions/marketsStats.html +5 -0
  110. package/docs/functions/optExpect.html +4 -4
  111. package/docs/functions/optMap.html +5 -5
  112. package/docs/functions/optUnwrap.html +2 -2
  113. package/docs/functions/panic.html +1 -1
  114. package/docs/functions/placeOrder.html +1 -0
  115. package/docs/functions/queryAction.html +6 -0
  116. package/docs/functions/queryBlock.html +6 -0
  117. package/docs/functions/queryLastNBlocks.html +5 -0
  118. package/docs/functions/queryPrometheus.html +6 -0
  119. package/docs/functions/queryRecentActions.html +6 -0
  120. package/docs/functions/queryRecentBlocks.html +6 -0
  121. package/docs/functions/revokeSession.html +1 -0
  122. package/docs/functions/shortenPublicKey.html +5 -0
  123. package/docs/functions/signAction.html +2 -2
  124. package/docs/functions/toBN.html +5 -0
  125. package/docs/functions/toScaledU128.html +5 -5
  126. package/docs/functions/toScaledU64.html +5 -5
  127. package/docs/functions/transfer.html +1 -0
  128. package/docs/functions/withdraw.html +1 -0
  129. package/docs/hierarchy.html +1 -0
  130. package/docs/index.html +39 -20
  131. package/docs/interfaces/Account.html +8 -8
  132. package/docs/interfaces/ActionInfo.html +8 -8
  133. package/docs/interfaces/ActionNonceResponse.html +3 -0
  134. package/docs/interfaces/ActionQuery.html +4 -4
  135. package/docs/interfaces/ActionResponse.html +8 -8
  136. package/docs/interfaces/ActionsExtendedInfo.html +10 -10
  137. package/docs/interfaces/ActionsQuery.html +5 -5
  138. package/docs/interfaces/ActionsResponse.html +6 -6
  139. package/docs/interfaces/AggregateMetrics.html +12 -12
  140. package/docs/interfaces/BlockFacts.html +10 -0
  141. package/docs/interfaces/BlockQuery.html +6 -6
  142. package/docs/interfaces/BlockResponse.html +6 -6
  143. package/docs/interfaces/BlockSummary.html +8 -8
  144. package/docs/interfaces/BlockSummaryResponse.html +6 -6
  145. package/docs/interfaces/DeltaEvent.html +6 -6
  146. package/docs/interfaces/DepositSplParams.html +10 -0
  147. package/docs/interfaces/Info.html +3 -3
  148. package/docs/interfaces/Market.html +8 -6
  149. package/docs/interfaces/MarketStats.html +7 -7
  150. package/docs/interfaces/MarketsStatsResponse.html +2 -2
  151. package/docs/interfaces/NordConfig.html +14 -5
  152. package/docs/interfaces/NordWebSocketClientEvents.html +4 -0
  153. package/docs/interfaces/NordWebSocketEvents.html +8 -0
  154. package/docs/interfaces/Order.html +6 -6
  155. package/docs/interfaces/OrderInfo.html +6 -6
  156. package/docs/interfaces/OrderbookEntry.html +4 -0
  157. package/docs/interfaces/OrderbookQuery.html +6 -0
  158. package/docs/interfaces/OrderbookResponse.html +6 -10
  159. package/docs/interfaces/OrderbookSubscription.html +159 -0
  160. package/docs/interfaces/PerpMarketStats.html +5 -5
  161. package/docs/interfaces/RollmanActionExtendedInfo.html +4 -4
  162. package/docs/interfaces/RollmanActionInfo.html +4 -4
  163. package/docs/interfaces/RollmanActionResponse.html +4 -4
  164. package/docs/interfaces/RollmanActionsResponse.html +2 -2
  165. package/docs/interfaces/RollmanBlockResponse.html +3 -3
  166. package/docs/interfaces/SPLTokenInfo.html +10 -0
  167. package/docs/interfaces/SolanaBridgeConfig.html +10 -0
  168. package/docs/interfaces/StateFacts.html +10 -0
  169. package/docs/interfaces/SubscriberConfig.html +3 -3
  170. package/docs/interfaces/TimestampResponse.html +3 -0
  171. package/docs/interfaces/Token.html +5 -5
  172. package/docs/interfaces/TokenInfo.html +5 -0
  173. package/docs/interfaces/Trade.html +5 -5
  174. package/docs/interfaces/TradeSubscription.html +159 -0
  175. package/docs/interfaces/Trades.html +5 -5
  176. package/docs/interfaces/TradesQuery.html +6 -0
  177. package/docs/interfaces/TradesResponse.html +7 -12
  178. package/docs/interfaces/TransferParams.html +8 -0
  179. package/docs/interfaces/UserAccountIdsQuery.html +3 -0
  180. package/docs/interfaces/UserAccountIdsResponse.html +3 -0
  181. package/docs/interfaces/WebSocketDeltaUpdate.html +9 -0
  182. package/docs/interfaces/WebSocketSubscription.html +4 -0
  183. package/docs/interfaces/WebSocketTradeUpdate.html +6 -0
  184. package/docs/interfaces/WebSocketUserUpdate.html +6 -0
  185. package/docs/interfaces/WithdrawalClaim.html +14 -0
  186. package/docs/interfaces/WithdrawalParams.html +8 -0
  187. package/docs/modules.html +1 -77
  188. package/docs/types/BigIntValue.html +2 -2
  189. package/docs/types/WebSocketMessage.html +1 -0
  190. package/docs/variables/DEBUG_KEYS.html +1 -1
  191. package/docs/variables/DEFAULT_FUNDING_AMOUNTS.html +1 -1
  192. package/docs/variables/DEV_TOKEN_INFOS.html +1 -1
  193. package/docs/variables/DEV_URL.html +1 -1
  194. package/docs/variables/MAX_BUFFER_LEN.html +1 -1
  195. package/docs/variables/SESSION_TTL.html +1 -1
  196. package/docs/variables/WEBSERVER_DEV_URL.html +1 -1
  197. package/docs/variables/ZERO_DECIMAL.html +1 -1
  198. package/docs/variables/_private.html +2 -0
  199. package/eslint.config.mjs +66 -0
  200. package/package.json +20 -23
  201. package/src/bridge/client.ts +487 -0
  202. package/src/bridge/const.ts +53 -0
  203. package/src/bridge/index.ts +7 -0
  204. package/src/bridge/types.ts +127 -0
  205. package/src/bridge/utils.ts +140 -0
  206. package/src/const.ts +4 -9
  207. package/src/gen/common.ts +27 -10
  208. package/src/gen/nord.ts +1045 -487
  209. package/src/idl/bridge.ts +702 -0
  210. package/src/index.ts +21 -2
  211. package/src/nord/{actions.ts → api/actions.ts} +12 -16
  212. package/src/nord/api/core.ts +130 -0
  213. package/src/nord/api/market.ts +125 -0
  214. package/src/nord/api/metrics.ts +154 -0
  215. package/src/nord/api/queries.ts +236 -0
  216. package/src/nord/client/Nord.ts +652 -0
  217. package/src/nord/client/NordUser.ts +1101 -0
  218. package/src/nord/index.ts +16 -2
  219. package/src/nord/models/Subscriber.ts +56 -0
  220. package/src/nord/utils/NordError.ts +72 -0
  221. package/src/types.ts +163 -92
  222. package/src/utils.ts +22 -1
  223. package/src/websocket/NordWebSocketClient.ts +432 -0
  224. package/src/websocket/events.ts +31 -0
  225. package/src/websocket/index.ts +2 -0
  226. package/tsconfig.eslint.json +12 -0
  227. package/.eslintignore +0 -1
  228. package/.eslintrc.js +0 -20
  229. package/dist/abis/ERC20_ABI.d.ts +0 -39
  230. package/dist/abis/ERC20_ABI.js +0 -313
  231. package/dist/abis/NORD_GETTERS_FACET_ABI.d.ts +0 -34
  232. package/dist/abis/NORD_GETTERS_FACET_ABI.js +0 -195
  233. package/dist/abis/NORD_RAMP_FACET_ABI.d.ts +0 -35
  234. package/dist/abis/NORD_RAMP_FACET_ABI.js +0 -144
  235. package/dist/abis/index.d.ts +0 -3
  236. package/dist/abis/index.js +0 -9
  237. package/dist/nord/Nord.d.ts +0 -76
  238. package/dist/nord/Nord.js +0 -376
  239. package/dist/nord/NordImpl.d.ts +0 -7
  240. package/dist/nord/NordImpl.js +0 -6
  241. package/dist/nord/NordUser.d.ts +0 -77
  242. package/dist/nord/NordUser.js +0 -249
  243. package/docs/functions/createWebSocketSubscription.html +0 -12
  244. package/docs/interfaces/ERC20TokenInfo.html +0 -5
  245. package/docs/interfaces/OrderbookOrder.html +0 -6
  246. package/docs/interfaces/TradeInfo.html +0 -20
  247. package/docs/interfaces/TradesQueryParams.html +0 -10
  248. package/docs/variables/DEV_CONTRACT_ADDRESS.html +0 -1
  249. package/docs/variables/ERC20_ABI.html +0 -1
  250. package/docs/variables/EVM_DEV_URL.html +0 -1
  251. package/docs/variables/FAUCET_PRIVATE_ADDRESS.html +0 -1
  252. package/docs/variables/NORD_GETTERS_FACET_ABI.html +0 -1
  253. package/docs/variables/NORD_RAMP_FACET_ABI.html +0 -1
  254. package/src/abis/ERC20_ABI.ts +0 -310
  255. package/src/abis/NORD_GETTERS_FACET_ABI.ts +0 -192
  256. package/src/abis/NORD_RAMP_FACET_ABI.ts +0 -141
  257. package/src/abis/index.ts +0 -3
  258. package/src/nord/Nord.ts +0 -504
  259. package/src/nord/NordImpl.ts +0 -8
  260. package/src/nord/NordUser.ts +0 -469
@@ -0,0 +1,697 @@
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 nacl = __importStar(require("tweetnacl"));
40
+ const client_1 = require("../../bridge/client");
41
+ const utils_1 = require("../../bridge/utils");
42
+ const utils_2 = require("../../utils");
43
+ const actions_1 = require("../api/actions");
44
+ const NordError_1 = require("../utils/NordError");
45
+ /**
46
+ * User class for interacting with the Nord protocol
47
+ */
48
+ class NordUser {
49
+ /**
50
+ * Create a new NordUser instance
51
+ *
52
+ * @param params - Parameters for creating a NordUser
53
+ * @throws {NordError} If required parameters are missing
54
+ */
55
+ constructor(params) {
56
+ /** User balances by token symbol */
57
+ this.balances = {};
58
+ /** User orders by market symbol */
59
+ this.orders = {};
60
+ /** User positions by account ID */
61
+ this.positions = {};
62
+ /** User margins by account ID */
63
+ this.margins = {};
64
+ /** Last timestamp used */
65
+ this.lastTs = 0;
66
+ /** Last nonce used */
67
+ this.lastNonce = 0;
68
+ /** SPL token information */
69
+ this.splTokenInfos = [];
70
+ if (!params.nord) {
71
+ throw new NordError_1.NordError("Nord instance is required");
72
+ }
73
+ if (!params.address) {
74
+ throw new NordError_1.NordError("Address is required");
75
+ }
76
+ if (!params.walletSignFn) {
77
+ throw new NordError_1.NordError("Wallet sign function is required");
78
+ }
79
+ if (!params.sessionSignFn) {
80
+ throw new NordError_1.NordError("Session sign function is required");
81
+ }
82
+ if (!params.sessionPubKey) {
83
+ throw new NordError_1.NordError("Session public key is required");
84
+ }
85
+ this.nord = params.nord;
86
+ this.address = params.address;
87
+ this.walletSignFn = params.walletSignFn;
88
+ this.sessionSignFn = params.sessionSignFn;
89
+ this.transactionSignFn = params.transactionSignFn;
90
+ this.sessionPubKey = params.sessionPubKey;
91
+ this.publicKey = params.publicKey;
92
+ this.connection =
93
+ params.connection ||
94
+ new web3_js_1.Connection(params.nord.solanaUrl, {
95
+ commitment: "confirmed",
96
+ });
97
+ // Set sessionId if provided
98
+ if (params.sessionId !== undefined) {
99
+ this.sessionId = params.sessionId;
100
+ }
101
+ // Initialize bridge client if needed
102
+ try {
103
+ this.initBridgeClient();
104
+ }
105
+ catch (error) {
106
+ console.warn("Failed to initialize bridge client:", error);
107
+ }
108
+ // Convert tokens from info endpoint to SPLTokenInfo
109
+ if (this.nord.tokens && this.nord.tokens.length > 0) {
110
+ this.splTokenInfos = this.nord.tokens.map((token) => ({
111
+ mint: token.mintAddr, // Use mintAddr as mint
112
+ precision: token.decimals,
113
+ tokenId: token.tokenId,
114
+ name: token.symbol,
115
+ }));
116
+ }
117
+ }
118
+ /**
119
+ * Create a clone of this NordUser instance
120
+ *
121
+ * @returns A new NordUser instance with the same properties
122
+ */
123
+ clone() {
124
+ const cloned = new NordUser({
125
+ nord: this.nord,
126
+ address: this.address,
127
+ walletSignFn: this.walletSignFn,
128
+ sessionSignFn: this.sessionSignFn,
129
+ transactionSignFn: this.transactionSignFn,
130
+ connection: this.connection,
131
+ sessionPubKey: this.sessionPubKey,
132
+ publicKey: this.publicKey,
133
+ });
134
+ // Copy other properties
135
+ cloned.balances = { ...this.balances };
136
+ cloned.orders = { ...this.orders };
137
+ cloned.positions = { ...this.positions };
138
+ cloned.margins = { ...this.margins };
139
+ cloned.accountIds = this.accountIds ? [...this.accountIds] : undefined;
140
+ cloned.sessionId = this.sessionId;
141
+ cloned.publicKey = this.publicKey;
142
+ cloned.lastTs = this.lastTs;
143
+ cloned.lastNonce = this.lastNonce;
144
+ cloned.splTokenInfos = [...this.splTokenInfos];
145
+ return cloned;
146
+ }
147
+ /**
148
+ * Initialize the Solana bridge client
149
+ *
150
+ * @private
151
+ * @throws {NordError} If required parameters are missing
152
+ */
153
+ initBridgeClient() {
154
+ if (!this.getSolanaPublicKey() ||
155
+ !this.connection ||
156
+ !this.nord.solanaProgramId) {
157
+ throw new NordError_1.NordError("Solana public key, connection, and program ID are required to initialize bridge client");
158
+ }
159
+ // Create an Anchor wallet that uses walletSignFn for signing
160
+ const wallet = {
161
+ publicKey: this.getSolanaPublicKey(),
162
+ signTransaction: async (tx) => {
163
+ return await this.transactionSignFn(tx);
164
+ },
165
+ signAllTransactions: async (txs) => {
166
+ return Promise.all(txs.map(async (tx) => {
167
+ return await this.transactionSignFn(tx);
168
+ }));
169
+ },
170
+ // Create a keypair-like object with just the public key
171
+ payer: {
172
+ publicKey: this.getSolanaPublicKey(),
173
+ secretKey: new Uint8Array(64), // Dummy secret key to satisfy the type
174
+ },
175
+ };
176
+ // Initialize the bridge client
177
+ this.bridgeClient = new client_1.SolanaBridgeClient({
178
+ rpcUrl: this.connection.rpcEndpoint,
179
+ programId: this.nord.solanaProgramId,
180
+ commitment: "confirmed",
181
+ tokenInfos: this.splTokenInfos,
182
+ }, wallet);
183
+ }
184
+ /**
185
+ * Create a NordUser from a private key
186
+ *
187
+ * @param nord - Nord instance
188
+ * @param privateKey - Private key as string or Uint8Array
189
+ * @param connection - Solana connection (optional)
190
+ * @returns NordUser instance
191
+ * @throws {NordError} If the private key is invalid
192
+ */
193
+ static fromPrivateKey(nord, privateKey, connection) {
194
+ try {
195
+ const keypair = (0, utils_1.keypairFromPrivateKey)(privateKey);
196
+ const publicKey = keypair.publicKey;
197
+ // Create a signing function that uses the keypair but doesn't expose it
198
+ const walletSignFn = async (message) => {
199
+ const messageBuffer = typeof message === "string"
200
+ ? Buffer.from(message)
201
+ : Buffer.from(message);
202
+ // Use the keypair to sign the message
203
+ const signature = nacl.sign.detached(messageBuffer, keypair.secretKey);
204
+ return signature;
205
+ };
206
+ const sessionSignFn = async (message) => {
207
+ // Use the keypair to sign the message
208
+ return nacl.sign.detached(message, keypair.secretKey);
209
+ };
210
+ // Create a transaction signing function
211
+ const transactionSignFn = async (transaction) => {
212
+ // This is a basic implementation - actual implementation would depend on the transaction type
213
+ if (transaction.serializeMessage) {
214
+ // Solana transaction
215
+ transaction.sign([keypair]);
216
+ return transaction;
217
+ }
218
+ // For other transaction types, would need specific implementation
219
+ throw new NordError_1.NordError("Unsupported transaction type for signing");
220
+ };
221
+ return new NordUser({
222
+ nord,
223
+ address: publicKey.toBase58(),
224
+ walletSignFn,
225
+ sessionSignFn,
226
+ transactionSignFn,
227
+ connection,
228
+ publicKey,
229
+ sessionPubKey: publicKey.toBytes(), // Use the public key derived from the private key as the session public key
230
+ });
231
+ }
232
+ catch (error) {
233
+ throw new NordError_1.NordError("Failed to create NordUser from private key", {
234
+ cause: error,
235
+ });
236
+ }
237
+ }
238
+ /**
239
+ * Get the associated token account for a token mint
240
+ *
241
+ * @param mint - Token mint address
242
+ * @returns Associated token account address
243
+ * @throws {NordError} If required parameters are missing or operation fails
244
+ */
245
+ async getAssociatedTokenAccount(mint) {
246
+ if (!this.getSolanaPublicKey()) {
247
+ throw new NordError_1.NordError("Solana public key is required to get associated token account");
248
+ }
249
+ try {
250
+ return await (0, spl_token_1.getAssociatedTokenAddress)(mint, this.getSolanaPublicKey(), false, spl_token_1.TOKEN_2022_PROGRAM_ID, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
251
+ }
252
+ catch (error) {
253
+ throw new NordError_1.NordError("Failed to get associated token account", {
254
+ cause: error,
255
+ });
256
+ }
257
+ }
258
+ /**
259
+ * Deposit SPL tokens to the bridge
260
+ *
261
+ * @param amount - Amount to deposit
262
+ * @param tokenId - Token ID
263
+ * @returns Transaction signature
264
+ * @throws {NordError} If required parameters are missing or operation fails
265
+ */
266
+ async depositSpl(amount, tokenId) {
267
+ if (!this.bridgeClient || !this.getSolanaPublicKey() || !this.connection) {
268
+ throw new NordError_1.NordError("Bridge client, Solana public key, and connection are required for deposit");
269
+ }
270
+ try {
271
+ // Find the token info
272
+ const tokenInfo = this.splTokenInfos.find((t) => t.tokenId === tokenId);
273
+ if (!tokenInfo) {
274
+ throw new NordError_1.NordError(`Token with ID ${tokenId} not found`);
275
+ }
276
+ const mint = new web3_js_1.PublicKey(tokenInfo.mint);
277
+ // Get the user's token account
278
+ const fromAccount = await this.getAssociatedTokenAccount(mint);
279
+ // Get the bridge's token account
280
+ const [authority] = await this.bridgeClient.findAuthorityPda();
281
+ const toAccount = await (0, spl_token_1.getAssociatedTokenAddress)(mint, authority, true, spl_token_1.TOKEN_2022_PROGRAM_ID);
282
+ // Convert amount to BN with proper decimals
283
+ const amountBN = (0, utils_2.toBN)(amount, tokenInfo.precision);
284
+ // Deposit tokens
285
+ return await this.bridgeClient.depositSpl({
286
+ amount: amountBN,
287
+ mint,
288
+ fromAccount,
289
+ toAccount,
290
+ });
291
+ }
292
+ catch (error) {
293
+ throw new NordError_1.NordError(`Failed to deposit ${amount} of token ID ${tokenId}`, { cause: error });
294
+ }
295
+ }
296
+ /**
297
+ * Withdraw SPL tokens from the bridge
298
+ *
299
+ * @param claim - Claim data
300
+ * @returns Transaction signature
301
+ * @throws {NordError} If required parameters are missing or operation fails
302
+ */
303
+ async withdrawSpl(claim) {
304
+ if (!this.bridgeClient || !this.getSolanaPublicKey() || !this.connection) {
305
+ throw new NordError_1.NordError("Bridge client, Solana public key, and connection are required for withdrawal");
306
+ }
307
+ try {
308
+ // Find the token info
309
+ const tokenInfo = this.splTokenInfos.find((t) => t.tokenId === claim.tokenId);
310
+ if (!tokenInfo) {
311
+ throw new NordError_1.NordError(`Token with ID ${claim.tokenId} not found`);
312
+ }
313
+ const mint = new web3_js_1.PublicKey(tokenInfo.mint);
314
+ // Get the user's token account
315
+ const toAccount = await this.getAssociatedTokenAccount(mint);
316
+ // Get the bridge's token account
317
+ const [authority] = await this.bridgeClient.findAuthorityPda();
318
+ const fromAccount = await (0, spl_token_1.getAssociatedTokenAddress)(mint, authority, true, spl_token_1.TOKEN_2022_PROGRAM_ID);
319
+ // Create a transaction signer that uses walletSignFn
320
+ const transactionSigner = {
321
+ publicKey: this.getSolanaPublicKey(),
322
+ secretKey: new Uint8Array(64), // Dummy secret key, not actually used
323
+ sign: async (tx) => {
324
+ const message = tx.serializeMessage();
325
+ await this.walletSignFn(message);
326
+ return tx;
327
+ },
328
+ };
329
+ // Withdraw tokens
330
+ return await this.bridgeClient.withdraw({
331
+ claim,
332
+ fromAccount,
333
+ toAccount,
334
+ }, transactionSigner);
335
+ }
336
+ catch (error) {
337
+ throw new NordError_1.NordError("Failed to withdraw SPL tokens", { cause: error });
338
+ }
339
+ }
340
+ /**
341
+ * Get a new nonce for actions
342
+ *
343
+ * @returns Nonce as number
344
+ */
345
+ getNonce() {
346
+ return ++this.lastNonce;
347
+ }
348
+ /**
349
+ * Update account IDs for this user
350
+ *
351
+ * @throws {NordError} If the operation fails
352
+ */
353
+ async updateAccountId() {
354
+ try {
355
+ if (!this.publicKey) {
356
+ throw new NordError_1.NordError("Public key is required to update account ID");
357
+ }
358
+ const resp = await this.nord.getUserAccountIds({
359
+ pubkey: this.publicKey.toBase58(),
360
+ });
361
+ this.accountIds = resp.accountIds;
362
+ }
363
+ catch (error) {
364
+ throw new NordError_1.NordError("Failed to update account ID", { cause: error });
365
+ }
366
+ }
367
+ /**
368
+ * Fetch user information including balances and orders
369
+ *
370
+ * @throws {NordError} If the operation fails
371
+ */
372
+ async fetchInfo() {
373
+ if (this.accountIds !== undefined) {
374
+ const accountsData = await Promise.all(this.accountIds.map(async (accountId) => {
375
+ const response = await (0, utils_2.checkedFetch)(`${this.nord.webServerUrl}/account?account_id=${accountId}`);
376
+ const accountData = (await response.json());
377
+ // Ensure we have the correct accountId
378
+ return {
379
+ ...accountData,
380
+ accountId,
381
+ };
382
+ }));
383
+ for (const accountData of accountsData) {
384
+ // Process balances
385
+ this.balances[accountData.accountId] = [];
386
+ for (const balance of accountData.balances) {
387
+ this.balances[accountData.accountId].push({
388
+ accountId: accountData.accountId,
389
+ balance: balance.amount,
390
+ symbol: balance.token,
391
+ });
392
+ }
393
+ // Process orders
394
+ this.orders[accountData.accountId] = accountData.orders.map((order) => {
395
+ return {
396
+ orderId: order.orderId,
397
+ isLong: order.side === "bid",
398
+ size: order.size,
399
+ price: order.price,
400
+ marketId: order.marketId,
401
+ };
402
+ });
403
+ // Process positions
404
+ this.positions[accountData.accountId] = accountData.positions;
405
+ // Process margins
406
+ this.margins[accountData.accountId] = accountData.margins;
407
+ }
408
+ }
409
+ }
410
+ /**
411
+ * Refresh the user's session
412
+ *
413
+ * @throws {NordError} If the operation fails
414
+ */
415
+ async refreshSession() {
416
+ console.log(this.publicKey);
417
+ this.sessionId = await (0, actions_1.createSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
418
+ userPubkey: (0, utils_2.optExpect)(this.publicKey.toBytes(), "No user's public key"),
419
+ sessionPubkey: this.sessionPubKey,
420
+ });
421
+ }
422
+ /**
423
+ * Revoke a session
424
+ *
425
+ * @param sessionId - Session ID to revoke
426
+ * @throws {NordError} If the operation fails
427
+ */
428
+ async revokeSession(sessionId) {
429
+ try {
430
+ await (0, actions_1.revokeSession)(this.nord.webServerUrl, this.walletSignFn, await this.nord.getTimestamp(), this.getNonce(), {
431
+ sessionId,
432
+ });
433
+ }
434
+ catch (error) {
435
+ throw new NordError_1.NordError(`Failed to revoke session ${sessionId}`, {
436
+ cause: error,
437
+ });
438
+ }
439
+ }
440
+ /**
441
+ * Checks if the session is valid
442
+ * @private
443
+ * @throws {NordError} If the session is not valid
444
+ */
445
+ checkSessionValidity() {
446
+ if (this.sessionId === undefined || this.sessionId === BigInt(0)) {
447
+ throw new NordError_1.NordError("Invalid or empty session ID. Please create or refresh your session.");
448
+ }
449
+ }
450
+ /**
451
+ * Withdraw tokens from the exchange
452
+ *
453
+ * @param tokenId - Token ID to withdraw
454
+ * @param amount - Amount to withdraw
455
+ * @throws {NordError} If the operation fails
456
+ */
457
+ async withdraw(tokenId, amount) {
458
+ try {
459
+ this.checkSessionValidity();
460
+ await (0, actions_1.withdraw)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
461
+ sizeDecimals: (0, utils_2.findToken)(this.nord.tokens, tokenId).decimals,
462
+ sessionId: (0, utils_2.optExpect)(this.sessionId, "No session"),
463
+ tokenId: tokenId,
464
+ amount,
465
+ });
466
+ }
467
+ catch (error) {
468
+ throw new NordError_1.NordError(`Failed to withdraw ${amount} of token ID ${tokenId}`, { cause: error });
469
+ }
470
+ }
471
+ /**
472
+ * Place an order on the exchange
473
+ *
474
+ * @param params - Order parameters
475
+ * @returns Order ID if successful
476
+ * @throws {NordError} If the operation fails
477
+ */
478
+ async placeOrder(params) {
479
+ try {
480
+ this.checkSessionValidity();
481
+ const market = (0, utils_2.findMarket)(this.nord.markets, params.marketId);
482
+ if (!market) {
483
+ throw new NordError_1.NordError(`Market with ID ${params.marketId} not found`);
484
+ }
485
+ return (0, actions_1.placeOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
486
+ sessionId: (0, utils_2.optExpect)(this.sessionId, "No session"),
487
+ senderId: params.accountId,
488
+ sizeDecimals: market.sizeDecimals,
489
+ priceDecimals: market.priceDecimals,
490
+ marketId: params.marketId,
491
+ side: params.side,
492
+ fillMode: params.fillMode,
493
+ isReduceOnly: params.isReduceOnly,
494
+ size: params.size,
495
+ price: params.price,
496
+ quoteSize: params.quoteSize,
497
+ });
498
+ }
499
+ catch (error) {
500
+ throw new NordError_1.NordError("Failed to place order", { cause: error });
501
+ }
502
+ }
503
+ /**
504
+ * Cancel an order
505
+ *
506
+ * @param orderId - Order ID to cancel
507
+ * @param accountId - Account ID that placed the order
508
+ * @returns Action ID if successful
509
+ * @throws {NordError} If the operation fails
510
+ */
511
+ async cancelOrder(orderId, providedAccountId) {
512
+ const accountId = providedAccountId != null ? providedAccountId : this.accountIds?.[0];
513
+ try {
514
+ this.checkSessionValidity();
515
+ return (0, actions_1.cancelOrder)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
516
+ sessionId: (0, utils_2.optExpect)(this.sessionId, "No session"),
517
+ senderId: accountId,
518
+ orderId,
519
+ });
520
+ }
521
+ catch (error) {
522
+ throw new NordError_1.NordError(`Failed to cancel order ${orderId}`, {
523
+ cause: error,
524
+ });
525
+ }
526
+ }
527
+ /**
528
+ * Transfer tokens to another account
529
+ *
530
+ * @param params - Transfer parameters
531
+ * @throws {NordError} If the operation fails
532
+ */
533
+ async transferToAccount(params) {
534
+ try {
535
+ this.checkSessionValidity();
536
+ const token = (0, utils_2.findToken)(this.nord.tokens, params.tokenId);
537
+ await (0, actions_1.transfer)(this.nord.webServerUrl, this.sessionSignFn, await this.nord.getTimestamp(), this.getNonce(), {
538
+ sessionId: (0, utils_2.optExpect)(this.sessionId, "No session"),
539
+ fromAccountId: (0, utils_2.optExpect)(params.fromAccountId, "No source account"),
540
+ toAccountId: (0, utils_2.optExpect)(params.toAccountId, "No target account"),
541
+ tokenId: params.tokenId,
542
+ tokenDecimals: token.decimals,
543
+ amount: params.amount,
544
+ });
545
+ }
546
+ catch (error) {
547
+ throw new NordError_1.NordError("Failed to transfer tokens", { cause: error });
548
+ }
549
+ }
550
+ /**
551
+ * Create a new account
552
+ *
553
+ * @param params - Account creation parameters
554
+ * @returns New NordUser instance
555
+ * @throws {NordError} If the operation fails
556
+ */
557
+ async createAccount(params) {
558
+ try {
559
+ this.checkSessionValidity();
560
+ // Create a new keypair for the account
561
+ const keypair = web3_js_1.Keypair.generate();
562
+ // Create a new NordUser
563
+ const newUser = NordUser.fromPrivateKey(this.nord, keypair.secretKey, this.connection);
564
+ // Transfer initial funds
565
+ await this.transferToAccount({
566
+ to: newUser,
567
+ tokenId: params.tokenId,
568
+ amount: params.amount,
569
+ fromAccountId: (0, utils_2.optExpect)(this.accountIds?.[0], "No account ID"),
570
+ toAccountId: (0, utils_2.optExpect)(newUser.accountIds?.[0], "No account ID for new user"),
571
+ });
572
+ return newUser;
573
+ }
574
+ catch (error) {
575
+ throw new NordError_1.NordError("Failed to create account", { cause: error });
576
+ }
577
+ }
578
+ /**
579
+ * Helper function to retry a promise with exponential backoff
580
+ *
581
+ * @param fn - Function to retry
582
+ * @param maxRetries - Maximum number of retries
583
+ * @param initialDelay - Initial delay in milliseconds
584
+ * @returns Promise result
585
+ */
586
+ async retryWithBackoff(fn, maxRetries = 3, initialDelay = 500) {
587
+ let retries = 0;
588
+ let delay = initialDelay;
589
+ while (true) {
590
+ try {
591
+ return await fn();
592
+ }
593
+ catch (error) {
594
+ if (retries >= maxRetries) {
595
+ throw error;
596
+ }
597
+ // Check if error is rate limiting related
598
+ const isRateLimitError = error instanceof Error &&
599
+ (error.message.includes("rate limit") ||
600
+ error.message.includes("429") ||
601
+ error.message.includes("too many requests"));
602
+ if (!isRateLimitError) {
603
+ throw error;
604
+ }
605
+ retries++;
606
+ await new Promise((resolve) => setTimeout(resolve, delay));
607
+ delay *= 2; // Exponential backoff
608
+ }
609
+ }
610
+ }
611
+ /**
612
+ * Get user's token balances on Solana chain using mintAddr
613
+ *
614
+ * @param options - Optional parameters
615
+ * @param options.includeZeroBalances - Whether to include tokens with zero balance (default: true)
616
+ * @param options.includeTokenAccounts - Whether to include token account addresses in the result (default: false)
617
+ * @param options.maxConcurrent - Maximum number of concurrent requests (default: 5)
618
+ * @param options.maxRetries - Maximum number of retries for rate-limited requests (default: 3)
619
+ * @returns Object with token balances and optional token account addresses
620
+ * @throws {NordError} If required parameters are missing or operation fails
621
+ */
622
+ async getSolanaBalances(options = {}) {
623
+ const { includeZeroBalances = true, includeTokenAccounts = false, maxConcurrent = 5, maxRetries = 3, } = options;
624
+ if (!this.connection || !this.getSolanaPublicKey()) {
625
+ throw new NordError_1.NordError("Connection and Solana public key are required to get Solana balances");
626
+ }
627
+ const balances = {};
628
+ const tokenAccounts = {};
629
+ try {
630
+ // Get SOL balance (native token)
631
+ const solBalance = await this.retryWithBackoff(() => this.connection.getBalance(this.getSolanaPublicKey()), maxRetries);
632
+ balances["SOL"] = solBalance / 1e9; // Convert lamports to SOL
633
+ if (includeTokenAccounts) {
634
+ tokenAccounts["SOL"] = this.getSolanaPublicKey().toString();
635
+ }
636
+ // Get SPL token balances using mintAddr from Nord tokens
637
+ if (this.nord.tokens && this.nord.tokens.length > 0) {
638
+ const tokens = this.nord.tokens.filter((token) => !!token.mintAddr);
639
+ // Process tokens in batches to avoid rate limiting
640
+ for (let i = 0; i < tokens.length; i += maxConcurrent) {
641
+ const batch = tokens.slice(i, i + maxConcurrent);
642
+ // Process batch in parallel
643
+ const batchPromises = batch.map(async (token) => {
644
+ try {
645
+ const mint = new web3_js_1.PublicKey(token.mintAddr);
646
+ const associatedTokenAddress = await this.retryWithBackoff(() => (0, spl_token_1.getAssociatedTokenAddress)(mint, this.getSolanaPublicKey()), maxRetries);
647
+ if (includeTokenAccounts) {
648
+ tokenAccounts[token.symbol] = associatedTokenAddress.toString();
649
+ }
650
+ try {
651
+ const tokenBalance = await this.retryWithBackoff(() => this.connection.getTokenAccountBalance(associatedTokenAddress), maxRetries);
652
+ const balance = Number(tokenBalance.value.uiAmount);
653
+ if (balance > 0 || includeZeroBalances) {
654
+ balances[token.symbol] = balance;
655
+ }
656
+ }
657
+ catch {
658
+ // Token account might not exist yet, set balance to 0
659
+ if (includeZeroBalances) {
660
+ balances[token.symbol] = 0;
661
+ }
662
+ }
663
+ }
664
+ catch (error) {
665
+ console.error(`Error getting balance for token ${token.symbol}:`, error);
666
+ if (includeZeroBalances) {
667
+ balances[token.symbol] = 0;
668
+ }
669
+ }
670
+ });
671
+ // Wait for current batch to complete before processing next batch
672
+ await Promise.all(batchPromises);
673
+ }
674
+ }
675
+ return includeTokenAccounts ? { balances, tokenAccounts } : { balances };
676
+ }
677
+ catch (error) {
678
+ throw new NordError_1.NordError("Failed to get Solana token balances", {
679
+ cause: error,
680
+ });
681
+ }
682
+ }
683
+ /**
684
+ * Get the Solana public key derived from the address
685
+ *
686
+ * @returns The Solana public key
687
+ */
688
+ getSolanaPublicKey() {
689
+ try {
690
+ return new web3_js_1.PublicKey(this.address);
691
+ }
692
+ catch (error) {
693
+ throw new NordError_1.NordError("Invalid Solana address", { cause: error });
694
+ }
695
+ }
696
+ }
697
+ exports.NordUser = NordUser;