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

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 (192) hide show
  1. package/dist/bridge/client.js +45 -6
  2. package/dist/gen/nord.d.ts +48 -4
  3. package/dist/gen/nord.js +634 -34
  4. package/dist/idl/bridge.d.ts +569 -0
  5. package/dist/idl/bridge.js +8 -0
  6. package/dist/idl/bridge.json +75 -62
  7. package/dist/idl/index.d.ts +71 -49
  8. package/dist/index.d.ts +1 -3
  9. package/dist/index.js +6 -13
  10. package/dist/nord/api/actions.d.ts +7 -2
  11. package/dist/nord/api/actions.js +7 -1
  12. package/dist/nord/api/core.d.ts +1 -1
  13. package/dist/nord/api/core.js +3 -3
  14. package/dist/nord/api/market.js +1 -3
  15. package/dist/nord/api/queries.js +2 -2
  16. package/dist/nord/client/Nord.d.ts +9 -14
  17. package/dist/nord/client/Nord.js +27 -38
  18. package/dist/nord/client/NordUser.d.ts +7 -23
  19. package/dist/nord/client/NordUser.js +67 -143
  20. package/dist/nord/utils/NordError.js +5 -2
  21. package/dist/types.d.ts +34 -50
  22. package/dist/utils.d.ts +2 -9
  23. package/dist/utils.js +13 -18
  24. package/package.json +17 -18
  25. package/protoc-generate.sh +0 -0
  26. package/src/idl/bridge.json +75 -62
  27. package/src/index.ts +9 -12
  28. package/src/nord/api/actions.ts +14 -3
  29. package/src/nord/api/core.ts +4 -2
  30. package/src/nord/api/market.ts +1 -4
  31. package/src/nord/api/queries.ts +2 -2
  32. package/src/nord/client/Nord.ts +45 -50
  33. package/src/nord/client/NordUser.ts +90 -171
  34. package/src/nord/utils/NordError.ts +6 -2
  35. package/src/types.ts +34 -49
  36. package/src/utils.ts +16 -19
  37. package/codebase.md +0 -18886
  38. package/docs/.nojekyll +0 -1
  39. package/docs/assets/hierarchy.js +0 -1
  40. package/docs/assets/highlight.css +0 -92
  41. package/docs/assets/icons.js +0 -18
  42. package/docs/assets/icons.svg +0 -1
  43. package/docs/assets/main.js +0 -60
  44. package/docs/assets/navigation.js +0 -1
  45. package/docs/assets/search.js +0 -1
  46. package/docs/assets/style.css +0 -1611
  47. package/docs/classes/Nord.html +0 -189
  48. package/docs/classes/NordError.html +0 -24
  49. package/docs/classes/NordUser.html +0 -115
  50. package/docs/classes/NordWebSocketClient.html +0 -330
  51. package/docs/classes/SolanaBridgeClient.html +0 -91
  52. package/docs/classes/Subscriber.html +0 -10
  53. package/docs/enums/FillMode.html +0 -5
  54. package/docs/enums/KeyType.html +0 -4
  55. package/docs/enums/MetricPeriod.html +0 -9
  56. package/docs/enums/PdaSeedType.html +0 -11
  57. package/docs/enums/PeakTpsPeriodUnit.html +0 -15
  58. package/docs/enums/Side.html +0 -3
  59. package/docs/enums/WebSocketMessageType.html +0 -7
  60. package/docs/functions/actionQueryRollman.html +0 -6
  61. package/docs/functions/actionsQueryRollman.html +0 -6
  62. package/docs/functions/aggregateMetrics-1.html +0 -7
  63. package/docs/functions/assert.html +0 -1
  64. package/docs/functions/bigIntToProtoU128.html +0 -4
  65. package/docs/functions/bridgeToBN.html +0 -5
  66. package/docs/functions/bufferToHex.html +0 -4
  67. package/docs/functions/cancelOrder.html +0 -1
  68. package/docs/functions/checkPubKeyLength.html +0 -1
  69. package/docs/functions/checkedFetch.html +0 -6
  70. package/docs/functions/createSession.html +0 -1
  71. package/docs/functions/decodeLengthDelimited.html +0 -11
  72. package/docs/functions/encodeLengthDelimited.html +0 -6
  73. package/docs/functions/fillModeToProtoFillMode.html +0 -5
  74. package/docs/functions/findMarket.html +0 -1
  75. package/docs/functions/findPda.html +0 -6
  76. package/docs/functions/findToken.html +0 -1
  77. package/docs/functions/fromBN.html +0 -5
  78. package/docs/functions/getAccount.html +0 -6
  79. package/docs/functions/getActionNonce.html +0 -5
  80. package/docs/functions/getCurrentTps.html +0 -6
  81. package/docs/functions/getInfo.html +0 -5
  82. package/docs/functions/getLastActionId.html +0 -5
  83. package/docs/functions/getMedianLatency.html +0 -6
  84. package/docs/functions/getOrderbook.html +0 -6
  85. package/docs/functions/getPeakTps.html +0 -6
  86. package/docs/functions/getTimestamp.html +0 -5
  87. package/docs/functions/getTotalTransactions.html +0 -5
  88. package/docs/functions/getTrades.html +0 -6
  89. package/docs/functions/getUserAccountIds.html +0 -6
  90. package/docs/functions/hexToBuffer.html +0 -4
  91. package/docs/functions/initWebSocketClient.html +0 -12
  92. package/docs/functions/keypairFromPrivateKey.html +0 -4
  93. package/docs/functions/makeSigningFunction.html +0 -4
  94. package/docs/functions/makeWalletSignFn.html +0 -6
  95. package/docs/functions/marketsStats.html +0 -5
  96. package/docs/functions/optExpect.html +0 -5
  97. package/docs/functions/optMap.html +0 -5
  98. package/docs/functions/optUnwrap.html +0 -2
  99. package/docs/functions/panic.html +0 -1
  100. package/docs/functions/placeOrder.html +0 -1
  101. package/docs/functions/queryAction.html +0 -6
  102. package/docs/functions/queryPrometheus.html +0 -6
  103. package/docs/functions/queryRecentActions.html +0 -7
  104. package/docs/functions/revokeSession.html +0 -1
  105. package/docs/functions/shortenPublicKey.html +0 -5
  106. package/docs/functions/signAction.html +0 -6
  107. package/docs/functions/toBN.html +0 -5
  108. package/docs/functions/toScaledU128.html +0 -8
  109. package/docs/functions/toScaledU64.html +0 -8
  110. package/docs/functions/transfer.html +0 -1
  111. package/docs/functions/withdraw.html +0 -1
  112. package/docs/hierarchy.html +0 -1
  113. package/docs/index.html +0 -40
  114. package/docs/interfaces/Account.html +0 -8
  115. package/docs/interfaces/ActionInfo.html +0 -8
  116. package/docs/interfaces/ActionNonceResponse.html +0 -3
  117. package/docs/interfaces/ActionQuery.html +0 -4
  118. package/docs/interfaces/ActionResponse.html +0 -8
  119. package/docs/interfaces/ActionsExtendedInfo.html +0 -10
  120. package/docs/interfaces/ActionsQuery.html +0 -5
  121. package/docs/interfaces/ActionsResponse.html +0 -6
  122. package/docs/interfaces/AggregateMetrics.html +0 -12
  123. package/docs/interfaces/BlockFacts.html +0 -10
  124. package/docs/interfaces/BlockQuery.html +0 -6
  125. package/docs/interfaces/BlockResponse.html +0 -6
  126. package/docs/interfaces/BlockSummary.html +0 -8
  127. package/docs/interfaces/BlockSummaryResponse.html +0 -6
  128. package/docs/interfaces/DeltaEvent.html +0 -6
  129. package/docs/interfaces/DepositSplParams.html +0 -8
  130. package/docs/interfaces/Info.html +0 -3
  131. package/docs/interfaces/Market.html +0 -8
  132. package/docs/interfaces/MarketStats.html +0 -7
  133. package/docs/interfaces/MarketsStatsResponse.html +0 -2
  134. package/docs/interfaces/NordConfig.html +0 -24
  135. package/docs/interfaces/NordWebSocketClientEvents.html +0 -4
  136. package/docs/interfaces/NordWebSocketEvents.html +0 -8
  137. package/docs/interfaces/Order.html +0 -6
  138. package/docs/interfaces/OrderInfo.html +0 -6
  139. package/docs/interfaces/OrderbookEntry.html +0 -4
  140. package/docs/interfaces/OrderbookQuery.html +0 -6
  141. package/docs/interfaces/OrderbookResponse.html +0 -6
  142. package/docs/interfaces/OrderbookSubscription.html +0 -159
  143. package/docs/interfaces/PerpMarketStats.html +0 -5
  144. package/docs/interfaces/RollmanActionExtendedInfo.html +0 -4
  145. package/docs/interfaces/RollmanActionInfo.html +0 -4
  146. package/docs/interfaces/RollmanActionResponse.html +0 -4
  147. package/docs/interfaces/RollmanActionsResponse.html +0 -2
  148. package/docs/interfaces/RollmanBlockResponse.html +0 -3
  149. package/docs/interfaces/SPLTokenInfo.html +0 -10
  150. package/docs/interfaces/SolanaBridgeConfig.html +0 -12
  151. package/docs/interfaces/StateFacts.html +0 -10
  152. package/docs/interfaces/SubscriberConfig.html +0 -3
  153. package/docs/interfaces/TimestampResponse.html +0 -3
  154. package/docs/interfaces/Token.html +0 -5
  155. package/docs/interfaces/TokenInfo.html +0 -6
  156. package/docs/interfaces/Trade.html +0 -5
  157. package/docs/interfaces/TradeSubscription.html +0 -159
  158. package/docs/interfaces/Trades.html +0 -5
  159. package/docs/interfaces/TradesQuery.html +0 -6
  160. package/docs/interfaces/TradesResponse.html +0 -7
  161. package/docs/interfaces/TransferParams.html +0 -8
  162. package/docs/interfaces/UserAccountIdsQuery.html +0 -3
  163. package/docs/interfaces/UserAccountIdsResponse.html +0 -3
  164. package/docs/interfaces/WebSocketAccountUpdate.html +0 -6
  165. package/docs/interfaces/WebSocketDeltaUpdate.html +0 -9
  166. package/docs/interfaces/WebSocketSubscription.html +0 -4
  167. package/docs/interfaces/WebSocketTradeUpdate.html +0 -6
  168. package/docs/interfaces/WithdrawalClaim.html +0 -14
  169. package/docs/interfaces/WithdrawalParams.html +0 -8
  170. package/docs/modules.html +0 -1
  171. package/docs/types/BigIntValue.html +0 -2
  172. package/docs/types/SubscriptionPattern.html +0 -4
  173. package/docs/types/SubscriptionType.html +0 -2
  174. package/docs/types/WebSocketMessage.html +0 -1
  175. package/docs/variables/DEBUG_KEYS.html +0 -1
  176. package/docs/variables/DEFAULT_FUNDING_AMOUNTS.html +0 -1
  177. package/docs/variables/DEV_TOKEN_INFOS.html +0 -1
  178. package/docs/variables/DEV_URL.html +0 -1
  179. package/docs/variables/MAX_BUFFER_LEN.html +0 -1
  180. package/docs/variables/SESSION_TTL.html +0 -1
  181. package/docs/variables/WEBSERVER_DEV_URL.html +0 -1
  182. package/docs/variables/ZERO_DECIMAL.html +0 -1
  183. package/docs/variables/_private.html +0 -2
  184. package/idl-generate.sh +0 -4
  185. package/src/bridge/client.ts +0 -498
  186. package/src/bridge/const.ts +0 -53
  187. package/src/bridge/index.ts +0 -6
  188. package/src/bridge/types.ts +0 -129
  189. package/src/bridge/utils.ts +0 -140
  190. package/src/gen/common.ts +0 -297
  191. package/src/gen/nord.ts +0 -6716
  192. package/src/idl/index.ts +0 -2
@@ -1,5 +1,4 @@
1
1
  import { EventEmitter } from "events";
2
- import { Connection, PublicKey } from "@solana/web3.js";
3
2
  import {
4
3
  Account,
5
4
  ActionQuery,
@@ -22,6 +21,7 @@ import {
22
21
  UserAccountIdsQuery,
23
22
  UserAccountIdsResponse,
24
23
  } from "../../types";
24
+ import { ProtonClient } from "@n1xyz/proton";
25
25
  import { NordWebSocketClient } from "../../websocket/index";
26
26
  import * as core from "../api/core";
27
27
  import * as market from "../api/market";
@@ -29,6 +29,7 @@ import * as metrics from "../api/metrics";
29
29
  import * as queries from "../api/queries";
30
30
  import { OrderbookSubscription, TradeSubscription } from "../models/Subscriber";
31
31
  import { NordError } from "../utils/NordError";
32
+ import { PublicKey, Connection } from "@solana/web3.js";
32
33
 
33
34
  /**
34
35
  * User subscription interface
@@ -57,10 +58,7 @@ export class Nord {
57
58
  public readonly webServerUrl: string;
58
59
 
59
60
  /** Bridge verification key */
60
- public readonly bridgeVk: string;
61
-
62
- /** Optional Solana program ID (will be derived from bridgeVk) */
63
- private _solanaProgramId!: string;
61
+ public readonly bridgeVk: PublicKey;
64
62
 
65
63
  /** Solana RPC URL */
66
64
  public readonly solanaUrl: string;
@@ -74,6 +72,9 @@ export class Nord {
74
72
  /** Map of symbol to market_id */
75
73
  private symbolToMarketId: Map<string, number> = new Map();
76
74
 
75
+ /** Proton client for bridge and indexd operations */
76
+ public protonClient: ProtonClient;
77
+
77
78
  /**
78
79
  * Create a new Nord client
79
80
  *
@@ -83,22 +84,21 @@ export class Nord {
83
84
  * @param config.solanaUrl - Solana cluster URL
84
85
  * @throws {Error} If required configuration is missing
85
86
  */
86
- constructor(config: NordConfig) {
87
- if (!config.webServerUrl) {
88
- throw new NordError("webServerUrl is required");
89
- }
90
-
91
- if (!config.bridgeVk) {
92
- throw new NordError("bridgeVk is required");
93
- }
94
-
95
- if (!config.solanaUrl) {
96
- throw new NordError("solanaUrl is required");
97
- }
98
-
99
- this.webServerUrl = config.webServerUrl;
100
- this.bridgeVk = config.bridgeVk;
101
- this.solanaUrl = config.solanaUrl;
87
+ private constructor({
88
+ bridgeVk,
89
+ solanaUrl,
90
+ webServerUrl,
91
+ protonClient,
92
+ }: Readonly<{
93
+ bridgeVk: PublicKey;
94
+ solanaUrl: string;
95
+ webServerUrl: string;
96
+ protonClient: ProtonClient;
97
+ }>) {
98
+ this.webServerUrl = webServerUrl;
99
+ this.bridgeVk = bridgeVk;
100
+ this.solanaUrl = solanaUrl;
101
+ this.protonClient = protonClient;
102
102
  }
103
103
 
104
104
  /**
@@ -173,13 +173,13 @@ export class Nord {
173
173
  }
174
174
 
175
175
  /**
176
- * Get the next action nonce from the Nord server
176
+ * Get the last event nonce from the Nord server
177
177
  *
178
178
  * @returns Next action nonce
179
179
  * @throws {NordError} If the request fails
180
180
  */
181
181
  async getActionNonce(): Promise<number> {
182
- return core.getActionNonce(this.webServerUrl);
182
+ return core.getLastEventNonce(this.webServerUrl);
183
183
  }
184
184
 
185
185
  /**
@@ -213,44 +213,39 @@ export class Nord {
213
213
  * @returns Initialized Nord client
214
214
  * @throws {NordError} If initialization fails
215
215
  */
216
- public static async initNord(nordConfig: NordConfig): Promise<Nord> {
217
- const nord = new Nord(nordConfig);
216
+ public static async initNord({
217
+ bridgeVk: bridgeVk_,
218
+ solanaUrl,
219
+ webServerUrl,
220
+ }: Readonly<NordConfig>): Promise<Nord> {
221
+ // TODO: we should parametrize the connectionn not have it done here.
222
+ // this is a dogshit api, only here to be compatible with the shitty
223
+ // vibecoded code and not break zero one team's workflow.
224
+ const connection = new Connection(solanaUrl, { commitment: "confirmed" });
225
+ const bridgeVk = new PublicKey(bridgeVk_);
226
+ const protonClient = await ProtonClient.init({
227
+ protonUrl: webServerUrl,
228
+ bridgeVk,
229
+ solConn: connection,
230
+ });
231
+ const nord = new Nord({
232
+ bridgeVk,
233
+ protonClient,
234
+ solanaUrl,
235
+ webServerUrl,
236
+ });
218
237
  await nord.init();
219
238
  return nord;
220
239
  }
221
240
 
222
241
  /**
223
- * Initialize the Nord client by deriving program ID and fetching info
242
+ * Initialize the Nord client
224
243
  * @private
225
244
  */
226
245
  private async init(): Promise<void> {
227
- const connection = new Connection(this.solanaUrl);
228
- const bridgeVkPubkey = new PublicKey(this.bridgeVk);
229
-
230
- const bridgeAccount = await connection.getAccountInfo(bridgeVkPubkey);
231
- if (!bridgeAccount) {
232
- throw new NordError(`Bridge account ${this.bridgeVk} not found`);
233
- }
234
-
235
- this._solanaProgramId = bridgeAccount.owner.toString();
236
246
  await this.fetchNordInfo();
237
247
  }
238
248
 
239
- /**
240
- * Get the Solana program ID derived from bridge VK
241
- *
242
- * @returns Program ID string
243
- * @throws {NordError} If program ID hasn't been initialized
244
- */
245
- public getSolanaProgramId(): string {
246
- if (!this._solanaProgramId) {
247
- throw new NordError(
248
- "Solana program ID not initialized. Have you called Nord.initNord()?",
249
- );
250
- }
251
- return this._solanaProgramId;
252
- }
253
-
254
249
  /**
255
250
  * Get market statistics
256
251
  *
@@ -1,17 +1,15 @@
1
- import * as anchor from "@coral-xyz/anchor";
2
1
  import {
3
2
  ASSOCIATED_TOKEN_PROGRAM_ID,
4
3
  getAssociatedTokenAddress,
4
+ TOKEN_PROGRAM_ID,
5
5
  TOKEN_2022_PROGRAM_ID,
6
6
  } from "@solana/spl-token";
7
- import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";
7
+ import { Connection, PublicKey, Transaction } from "@solana/web3.js";
8
8
  import Decimal from "decimal.js";
9
9
  import * as ed from "@noble/ed25519";
10
10
  import { sha512 } from "@noble/hashes/sha512";
11
11
  ed.etc.sha512Sync = sha512;
12
- import { SolanaBridgeClient } from "../../bridge/client";
13
- import { SPLTokenInfo } from "../../bridge/types";
14
- import { keypairFromPrivateKey } from "../../bridge/utils";
12
+ import { SPLTokenInfo, DepositSplParams, floatToBn } from "@n1xyz/proton";
15
13
  import { FillMode, Order, Side } from "../../types";
16
14
  import {
17
15
  BigIntValue,
@@ -19,7 +17,7 @@ import {
19
17
  findMarket,
20
18
  findToken,
21
19
  optExpect,
22
- toBN as utilsToBN,
20
+ keypairFromPrivateKey,
23
21
  } from "../../utils";
24
22
  import {
25
23
  cancelOrder,
@@ -121,7 +119,7 @@ export class NordUser {
121
119
  public readonly nord: Nord;
122
120
 
123
121
  /** User's blockchain address */
124
- public readonly address: string;
122
+ public readonly address: PublicKey;
125
123
 
126
124
  /** Function to sign messages with the user's wallet */
127
125
  public readonly walletSignFn: (
@@ -191,10 +189,6 @@ export class NordUser {
191
189
  /** Last nonce used */
192
190
  public lastNonce = 0;
193
191
 
194
- // Solana-specific properties
195
- /** Solana bridge client */
196
- public bridgeClient?: SolanaBridgeClient;
197
-
198
192
  /** Solana connection */
199
193
  public connection: Connection;
200
194
 
@@ -207,46 +201,48 @@ export class NordUser {
207
201
  * @param params - Parameters for creating a NordUser
208
202
  * @throws {NordError} If required parameters are missing
209
203
  */
210
- constructor(params: NordUserParams) {
211
- if (!params.nord) {
212
- throw new NordError("Nord instance is required");
213
- }
214
- if (!params.address) {
215
- throw new NordError("Address is required");
216
- }
217
- if (!params.walletSignFn) {
204
+ constructor({
205
+ address,
206
+ nord,
207
+ publicKey,
208
+ sessionPubKey,
209
+ sessionSignFn,
210
+ transactionSignFn,
211
+ walletSignFn,
212
+ connection,
213
+ sessionId,
214
+ }: NordUserParams) {
215
+ if (!walletSignFn) {
218
216
  throw new NordError("Wallet sign function is required");
219
217
  }
220
- if (!params.sessionSignFn) {
218
+ if (!sessionSignFn) {
221
219
  throw new NordError("Session sign function is required");
222
220
  }
223
- if (!params.sessionPubKey) {
221
+ if (!sessionPubKey) {
224
222
  throw new NordError("Session public key is required");
225
223
  }
226
224
 
227
- this.nord = params.nord;
228
- this.address = params.address;
229
- this.walletSignFn = params.walletSignFn;
230
- this.sessionSignFn = params.sessionSignFn;
231
- this.transactionSignFn = params.transactionSignFn;
232
- this.sessionPubKey = params.sessionPubKey;
233
- this.publicKey = params.publicKey;
225
+ try {
226
+ this.address = new PublicKey(address);
227
+ } catch (error) {
228
+ throw new NordError("Invalid Solana address", { cause: error });
229
+ }
230
+
231
+ this.nord = nord;
232
+ this.walletSignFn = walletSignFn;
233
+ this.sessionSignFn = sessionSignFn;
234
+ this.transactionSignFn = transactionSignFn;
235
+ this.sessionPubKey = sessionPubKey;
236
+ this.publicKey = publicKey;
234
237
  this.connection =
235
- params.connection ||
236
- new Connection(params.nord.solanaUrl, {
238
+ connection ||
239
+ new Connection(nord.solanaUrl, {
237
240
  commitment: "confirmed",
238
241
  });
239
242
 
240
243
  // Set sessionId if provided
241
- if (params.sessionId !== undefined) {
242
- this.sessionId = params.sessionId;
243
- }
244
-
245
- // Initialize bridge client if needed
246
- try {
247
- this.initBridgeClient();
248
- } catch (error) {
249
- console.warn("Failed to initialize bridge client:", error);
244
+ if (sessionId !== undefined) {
245
+ this.sessionId = sessionId;
250
246
  }
251
247
 
252
248
  // Convert tokens from info endpoint to SPLTokenInfo
@@ -268,7 +264,7 @@ export class NordUser {
268
264
  clone(): NordUser {
269
265
  const cloned = new NordUser({
270
266
  nord: this.nord,
271
- address: this.address,
267
+ address: this.address.toBase58(),
272
268
  walletSignFn: this.walletSignFn,
273
269
  sessionSignFn: this.sessionSignFn,
274
270
  transactionSignFn: this.transactionSignFn,
@@ -292,56 +288,6 @@ export class NordUser {
292
288
  return cloned;
293
289
  }
294
290
 
295
- /**
296
- * Initialize the Solana bridge client
297
- *
298
- * @private
299
- * @throws {NordError} If required parameters are missing
300
- */
301
- private initBridgeClient(): void {
302
- if (
303
- !this.getSolanaPublicKey() ||
304
- !this.connection ||
305
- !this.nord.getSolanaProgramId()
306
- ) {
307
- throw new NordError(
308
- "Solana public key, connection, and program ID are required to initialize bridge client",
309
- );
310
- }
311
-
312
- // Create an Anchor wallet that uses walletSignFn for signing
313
- const wallet: anchor.Wallet = {
314
- publicKey: this.getSolanaPublicKey(),
315
- signTransaction: async (tx: any) => {
316
- return await this.transactionSignFn(tx);
317
- },
318
- signAllTransactions: async (txs: any[]) => {
319
- return Promise.all(
320
- txs.map(async (tx) => {
321
- return await this.transactionSignFn(tx);
322
- }),
323
- );
324
- },
325
- // Create a keypair-like object with just the public key
326
- payer: {
327
- publicKey: this.getSolanaPublicKey(),
328
- secretKey: new Uint8Array(64), // Dummy secret key to satisfy the type
329
- } as Keypair,
330
- };
331
-
332
- // Initialize the bridge client
333
- this.bridgeClient = new SolanaBridgeClient(
334
- {
335
- rpcUrl: this.connection.rpcEndpoint,
336
- programId: this.nord.getSolanaProgramId(),
337
- commitment: "confirmed",
338
- tokenInfos: this.splTokenInfos,
339
- bridgeVk: this.nord.bridgeVk,
340
- },
341
- wallet,
342
- );
343
- }
344
-
345
291
  /**
346
292
  * Create a NordUser from a private key
347
293
  *
@@ -391,9 +337,9 @@ export class NordUser {
391
337
  // Create a transaction signing function
392
338
  const transactionSignFn = async (transaction: any): Promise<any> => {
393
339
  // This is a basic implementation - actual implementation would depend on the transaction type
394
- if (transaction.serializeMessage) {
340
+ if (transaction.sign) {
395
341
  // Solana transaction
396
- transaction.sign([keypair]);
342
+ transaction.sign(keypair);
397
343
  return transaction;
398
344
  }
399
345
 
@@ -433,13 +379,31 @@ export class NordUser {
433
379
  }
434
380
 
435
381
  try {
436
- return await getAssociatedTokenAddress(
382
+ // Get the token program ID from the mint account
383
+ const mintAccount = await this.connection.getAccountInfo(mint);
384
+ if (!mintAccount) {
385
+ throw new NordError("Mint account not found");
386
+ }
387
+ const tokenProgramId = mintAccount.owner;
388
+
389
+ // Validate that the mint is owned by a supported SPL token program
390
+ if (
391
+ !tokenProgramId.equals(TOKEN_PROGRAM_ID) &&
392
+ !tokenProgramId.equals(TOKEN_2022_PROGRAM_ID)
393
+ ) {
394
+ throw new NordError(
395
+ "Mint Account is not owned by a supported SPL token program",
396
+ );
397
+ }
398
+
399
+ const associatedTokenAddress = await getAssociatedTokenAddress(
437
400
  mint,
438
401
  this.getSolanaPublicKey(),
439
402
  false,
440
- TOKEN_2022_PROGRAM_ID,
403
+ tokenProgramId,
441
404
  ASSOCIATED_TOKEN_PROGRAM_ID,
442
405
  );
406
+ return associatedTokenAddress;
443
407
  } catch (error) {
444
408
  throw new NordError("Failed to get associated token account", {
445
409
  cause: error,
@@ -456,12 +420,6 @@ export class NordUser {
456
420
  * @throws {NordError} If required parameters are missing or operation fails
457
421
  */
458
422
  async depositSpl(amount: number, tokenId: number): Promise<string> {
459
- if (!this.bridgeClient || !this.getSolanaPublicKey() || !this.connection) {
460
- throw new NordError(
461
- "Bridge client, Solana public key, and connection are required for deposit",
462
- );
463
- }
464
-
465
423
  try {
466
424
  // Find the token info
467
425
  const tokenInfo = this.splTokenInfos.find((t) => t.tokenId === tokenId);
@@ -472,82 +430,43 @@ export class NordUser {
472
430
  const mint = new PublicKey(tokenInfo.mint);
473
431
  // Get the user's token account
474
432
  const fromAccount = await this.getAssociatedTokenAccount(mint);
433
+
475
434
  // Convert amount to BN with proper decimals
476
- const amountBN = utilsToBN(amount, tokenInfo.precision);
435
+ const amountBN = floatToBn(amount, tokenInfo.precision);
477
436
 
478
- // Deposit tokens
479
- return await this.bridgeClient.depositSpl({
437
+ // Create deposit parameters
438
+ const depositParams: DepositSplParams = {
480
439
  amount: amountBN,
481
440
  mint,
482
441
  fromAccount,
483
- });
484
- } catch (error) {
485
- throw new NordError(
486
- `Failed to deposit ${amount} of token ID ${tokenId}`,
487
- { cause: error },
488
- );
489
- }
490
- }
442
+ };
491
443
 
492
- /**
493
- * Withdraw SPL tokens from the bridge
494
- *
495
- * @param claim - Claim data
496
- * @returns Transaction signature
497
- * @throws {NordError} If required parameters are missing or operation fails
498
- */
499
- async withdrawSpl(claim: any): Promise<string> {
500
- if (!this.bridgeClient || !this.getSolanaPublicKey() || !this.connection) {
501
- throw new NordError(
502
- "Bridge client, Solana public key, and connection are required for withdrawal",
444
+ // Build the deposit transaction using proton client
445
+ const depositTx = await this.nord.protonClient.buildDepositTx(
446
+ depositParams,
447
+ this.getSolanaPublicKey(),
448
+ this.connection,
503
449
  );
504
- }
505
450
 
506
- try {
507
- // Find the token info
508
- const tokenInfo = this.splTokenInfos.find(
509
- (t) => t.tokenId === claim.tokenId,
510
- );
511
- if (!tokenInfo) {
512
- throw new NordError(`Token with ID ${claim.tokenId} not found`);
513
- }
451
+ const { blockhash } = await this.connection.getLatestBlockhash();
514
452
 
515
- const mint = new PublicKey(tokenInfo.mint);
453
+ depositTx.recentBlockhash = blockhash;
454
+ depositTx.feePayer = this.getSolanaPublicKey();
516
455
 
517
- // Get the user's token account
518
- const toAccount = await this.getAssociatedTokenAccount(mint);
456
+ const signedTx = await this.transactionSignFn(depositTx);
519
457
 
520
- // Get the bridge's token account
521
- const [authority] = await this.bridgeClient.findAuthorityPda();
522
- const fromAccount = await getAssociatedTokenAddress(
523
- mint,
524
- authority,
525
- true,
526
- TOKEN_2022_PROGRAM_ID,
458
+ // TODO: should use `VersionedTransaction` and remove any for `transactionSignFn`,
459
+ // this is incredibly annoying to debug and i could've saved 30 mins.
460
+ const signature = await this.connection.sendRawTransaction(
461
+ signedTx.serialize(),
527
462
  );
528
463
 
529
- // Create a transaction signer that uses walletSignFn
530
- const transactionSigner = {
531
- publicKey: this.getSolanaPublicKey(),
532
- secretKey: new Uint8Array(64), // Dummy secret key, not actually used
533
- sign: async (tx: Transaction) => {
534
- const message = tx.serializeMessage();
535
- await this.walletSignFn(message);
536
- return tx;
537
- },
538
- };
539
-
540
- // Withdraw tokens
541
- return await this.bridgeClient.withdraw(
542
- {
543
- claim,
544
- fromAccount,
545
- toAccount,
546
- },
547
- transactionSigner as unknown as Keypair, // Type cast to satisfy the API
548
- );
464
+ return signature;
549
465
  } catch (error) {
550
- throw new NordError("Failed to withdraw SPL tokens", { cause: error });
466
+ throw new NordError(
467
+ `Failed to deposit ${amount} of token ID ${tokenId}`,
468
+ { cause: error },
469
+ );
551
470
  }
552
471
  }
553
472
 
@@ -747,10 +666,13 @@ export class NordUser {
747
666
  * @param amount - Amount to withdraw
748
667
  * @throws {NordError} If the operation fails
749
668
  */
750
- async withdraw(tokenId: number, amount: number): Promise<void> {
669
+ async withdraw(
670
+ tokenId: number,
671
+ amount: number,
672
+ ): Promise<{ actionId: bigint }> {
751
673
  try {
752
674
  this.checkSessionValidity();
753
- await withdraw(
675
+ const { actionId } = await withdraw(
754
676
  this.nord.webServerUrl,
755
677
  this.sessionSignFn,
756
678
  await this.nord.getTimestamp(),
@@ -762,6 +684,7 @@ export class NordUser {
762
684
  amount,
763
685
  },
764
686
  );
687
+ return { actionId };
765
688
  } catch (error) {
766
689
  throw new NordError(
767
690
  `Failed to withdraw ${amount} of token ID ${tokenId}`,
@@ -813,7 +736,7 @@ export class NordUser {
813
736
  * Cancel an order
814
737
  *
815
738
  * @param orderId - Order ID to cancel
816
- * @param accountId - Account ID that placed the order
739
+ * @param providedAccountId - Account ID that placed the order
817
740
  * @returns Action ID if successful
818
741
  * @throws {NordError} If the operation fails
819
742
  */
@@ -989,7 +912,7 @@ export class NordUser {
989
912
  try {
990
913
  const tokenBalance = await this.retryWithBackoff(
991
914
  () =>
992
- this.connection!.getTokenAccountBalance(
915
+ this.connection.getTokenAccountBalance(
993
916
  associatedTokenAddress,
994
917
  ),
995
918
  maxRetries,
@@ -1035,10 +958,6 @@ export class NordUser {
1035
958
  * @returns The Solana public key
1036
959
  */
1037
960
  getSolanaPublicKey(): PublicKey {
1038
- try {
1039
- return new PublicKey(this.address);
1040
- } catch (error) {
1041
- throw new NordError("Invalid Solana address", { cause: error });
1042
- }
961
+ return this.address;
1043
962
  }
1044
963
  }
@@ -60,11 +60,15 @@ export class NordError extends Error {
60
60
  let result = `${this.name}: ${this.message}`;
61
61
 
62
62
  if (this.statusCode) {
63
- result += ` (Status: ${this.statusCode})`;
63
+ result += ` \nstatus: ${this.statusCode}`;
64
64
  }
65
65
 
66
66
  if (this.details && Object.keys(this.details).length > 0) {
67
- result += `\nDetails: ${JSON.stringify(this.details, null, 2)}`;
67
+ result += ` \ndetails: ${JSON.stringify(this.details, null, 2)}`;
68
+ }
69
+
70
+ if (this.cause) {
71
+ result += ` \ncause: ${this.cause.toString()}`;
68
72
  }
69
73
 
70
74
  return result;