@n1xyz/nord-ts 0.0.16 → 0.0.17

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 +633 -33
  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 +66 -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 -0
  23. package/dist/utils.js +14 -0
  24. package/package.json +18 -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 +89 -169
  34. package/src/nord/utils/NordError.ts +6 -2
  35. package/src/types.ts +34 -49
  36. package/src/utils.ts +18 -0
  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 } from "@n1xyz/proton";
15
13
  import { FillMode, Order, Side } from "../../types";
16
14
  import {
17
15
  BigIntValue,
@@ -20,6 +18,7 @@ import {
20
18
  findToken,
21
19
  optExpect,
22
20
  toBN as utilsToBN,
21
+ keypairFromPrivateKey,
23
22
  } from "../../utils";
24
23
  import {
25
24
  cancelOrder,
@@ -121,7 +120,7 @@ export class NordUser {
121
120
  public readonly nord: Nord;
122
121
 
123
122
  /** User's blockchain address */
124
- public readonly address: string;
123
+ public readonly address: PublicKey;
125
124
 
126
125
  /** Function to sign messages with the user's wallet */
127
126
  public readonly walletSignFn: (
@@ -191,10 +190,6 @@ export class NordUser {
191
190
  /** Last nonce used */
192
191
  public lastNonce = 0;
193
192
 
194
- // Solana-specific properties
195
- /** Solana bridge client */
196
- public bridgeClient?: SolanaBridgeClient;
197
-
198
193
  /** Solana connection */
199
194
  public connection: Connection;
200
195
 
@@ -207,46 +202,48 @@ export class NordUser {
207
202
  * @param params - Parameters for creating a NordUser
208
203
  * @throws {NordError} If required parameters are missing
209
204
  */
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) {
205
+ constructor({
206
+ address,
207
+ nord,
208
+ publicKey,
209
+ sessionPubKey,
210
+ sessionSignFn,
211
+ transactionSignFn,
212
+ walletSignFn,
213
+ connection,
214
+ sessionId,
215
+ }: NordUserParams) {
216
+ if (!walletSignFn) {
218
217
  throw new NordError("Wallet sign function is required");
219
218
  }
220
- if (!params.sessionSignFn) {
219
+ if (!sessionSignFn) {
221
220
  throw new NordError("Session sign function is required");
222
221
  }
223
- if (!params.sessionPubKey) {
222
+ if (!sessionPubKey) {
224
223
  throw new NordError("Session public key is required");
225
224
  }
226
225
 
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;
226
+ try {
227
+ this.address = new PublicKey(address);
228
+ } catch (error) {
229
+ throw new NordError("Invalid Solana address", { cause: error });
230
+ }
231
+
232
+ this.nord = nord;
233
+ this.walletSignFn = walletSignFn;
234
+ this.sessionSignFn = sessionSignFn;
235
+ this.transactionSignFn = transactionSignFn;
236
+ this.sessionPubKey = sessionPubKey;
237
+ this.publicKey = publicKey;
234
238
  this.connection =
235
- params.connection ||
236
- new Connection(params.nord.solanaUrl, {
239
+ connection ||
240
+ new Connection(nord.solanaUrl, {
237
241
  commitment: "confirmed",
238
242
  });
239
243
 
240
244
  // 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);
245
+ if (sessionId !== undefined) {
246
+ this.sessionId = sessionId;
250
247
  }
251
248
 
252
249
  // Convert tokens from info endpoint to SPLTokenInfo
@@ -268,7 +265,7 @@ export class NordUser {
268
265
  clone(): NordUser {
269
266
  const cloned = new NordUser({
270
267
  nord: this.nord,
271
- address: this.address,
268
+ address: this.address.toBase58(),
272
269
  walletSignFn: this.walletSignFn,
273
270
  sessionSignFn: this.sessionSignFn,
274
271
  transactionSignFn: this.transactionSignFn,
@@ -292,56 +289,6 @@ export class NordUser {
292
289
  return cloned;
293
290
  }
294
291
 
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
292
  /**
346
293
  * Create a NordUser from a private key
347
294
  *
@@ -391,9 +338,9 @@ export class NordUser {
391
338
  // Create a transaction signing function
392
339
  const transactionSignFn = async (transaction: any): Promise<any> => {
393
340
  // This is a basic implementation - actual implementation would depend on the transaction type
394
- if (transaction.serializeMessage) {
341
+ if (transaction.sign) {
395
342
  // Solana transaction
396
- transaction.sign([keypair]);
343
+ transaction.sign(keypair);
397
344
  return transaction;
398
345
  }
399
346
 
@@ -433,13 +380,31 @@ export class NordUser {
433
380
  }
434
381
 
435
382
  try {
436
- return await getAssociatedTokenAddress(
383
+ // Get the token program ID from the mint account
384
+ const mintAccount = await this.connection.getAccountInfo(mint);
385
+ if (!mintAccount) {
386
+ throw new NordError("Mint account not found");
387
+ }
388
+ const tokenProgramId = mintAccount.owner;
389
+
390
+ // Validate that the mint is owned by a supported SPL token program
391
+ if (
392
+ !tokenProgramId.equals(TOKEN_PROGRAM_ID) &&
393
+ !tokenProgramId.equals(TOKEN_2022_PROGRAM_ID)
394
+ ) {
395
+ throw new NordError(
396
+ "Mint Account is not owned by a supported SPL token program",
397
+ );
398
+ }
399
+
400
+ const associatedTokenAddress = await getAssociatedTokenAddress(
437
401
  mint,
438
402
  this.getSolanaPublicKey(),
439
403
  false,
440
- TOKEN_2022_PROGRAM_ID,
404
+ tokenProgramId,
441
405
  ASSOCIATED_TOKEN_PROGRAM_ID,
442
406
  );
407
+ return associatedTokenAddress;
443
408
  } catch (error) {
444
409
  throw new NordError("Failed to get associated token account", {
445
410
  cause: error,
@@ -456,12 +421,6 @@ export class NordUser {
456
421
  * @throws {NordError} If required parameters are missing or operation fails
457
422
  */
458
423
  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
424
  try {
466
425
  // Find the token info
467
426
  const tokenInfo = this.splTokenInfos.find((t) => t.tokenId === tokenId);
@@ -472,82 +431,43 @@ export class NordUser {
472
431
  const mint = new PublicKey(tokenInfo.mint);
473
432
  // Get the user's token account
474
433
  const fromAccount = await this.getAssociatedTokenAccount(mint);
434
+
475
435
  // Convert amount to BN with proper decimals
476
436
  const amountBN = utilsToBN(amount, tokenInfo.precision);
477
437
 
478
- // Deposit tokens
479
- return await this.bridgeClient.depositSpl({
438
+ // Create deposit parameters
439
+ const depositParams: DepositSplParams = {
480
440
  amount: amountBN,
481
441
  mint,
482
442
  fromAccount,
483
- });
484
- } catch (error) {
485
- throw new NordError(
486
- `Failed to deposit ${amount} of token ID ${tokenId}`,
487
- { cause: error },
488
- );
489
- }
490
- }
443
+ };
491
444
 
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",
445
+ // Build the deposit transaction using proton client
446
+ const depositTx = await this.nord.protonClient.buildDepositTx(
447
+ depositParams,
448
+ this.getSolanaPublicKey(),
449
+ this.connection,
503
450
  );
504
- }
505
451
 
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
- }
452
+ const { blockhash } = await this.connection.getLatestBlockhash();
514
453
 
515
- const mint = new PublicKey(tokenInfo.mint);
454
+ depositTx.recentBlockhash = blockhash;
455
+ depositTx.feePayer = this.getSolanaPublicKey();
516
456
 
517
- // Get the user's token account
518
- const toAccount = await this.getAssociatedTokenAccount(mint);
457
+ const signedTx = await this.transactionSignFn(depositTx);
519
458
 
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,
459
+ // TODO: should use `VersionedTransaction` and remove any for `transactionSignFn`,
460
+ // this is incredibly annoying to debug and i could've saved 30 mins.
461
+ const signature = await this.connection.sendRawTransaction(
462
+ signedTx.serialize(),
527
463
  );
528
464
 
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
- );
465
+ return signature;
549
466
  } catch (error) {
550
- throw new NordError("Failed to withdraw SPL tokens", { cause: error });
467
+ throw new NordError(
468
+ `Failed to deposit ${amount} of token ID ${tokenId}`,
469
+ { cause: error },
470
+ );
551
471
  }
552
472
  }
553
473
 
@@ -747,10 +667,13 @@ export class NordUser {
747
667
  * @param amount - Amount to withdraw
748
668
  * @throws {NordError} If the operation fails
749
669
  */
750
- async withdraw(tokenId: number, amount: number): Promise<void> {
670
+ async withdraw(
671
+ tokenId: number,
672
+ amount: number,
673
+ ): Promise<{ actionId: bigint }> {
751
674
  try {
752
675
  this.checkSessionValidity();
753
- await withdraw(
676
+ const { actionId } = await withdraw(
754
677
  this.nord.webServerUrl,
755
678
  this.sessionSignFn,
756
679
  await this.nord.getTimestamp(),
@@ -762,6 +685,7 @@ export class NordUser {
762
685
  amount,
763
686
  },
764
687
  );
688
+ return { actionId };
765
689
  } catch (error) {
766
690
  throw new NordError(
767
691
  `Failed to withdraw ${amount} of token ID ${tokenId}`,
@@ -813,7 +737,7 @@ export class NordUser {
813
737
  * Cancel an order
814
738
  *
815
739
  * @param orderId - Order ID to cancel
816
- * @param accountId - Account ID that placed the order
740
+ * @param providedAccountId - Account ID that placed the order
817
741
  * @returns Action ID if successful
818
742
  * @throws {NordError} If the operation fails
819
743
  */
@@ -989,7 +913,7 @@ export class NordUser {
989
913
  try {
990
914
  const tokenBalance = await this.retryWithBackoff(
991
915
  () =>
992
- this.connection!.getTokenAccountBalance(
916
+ this.connection.getTokenAccountBalance(
993
917
  associatedTokenAddress,
994
918
  ),
995
919
  maxRetries,
@@ -1035,10 +959,6 @@ export class NordUser {
1035
959
  * @returns The Solana public key
1036
960
  */
1037
961
  getSolanaPublicKey(): PublicKey {
1038
- try {
1039
- return new PublicKey(this.address);
1040
- } catch (error) {
1041
- throw new NordError("Invalid Solana address", { cause: error });
1042
- }
962
+ return this.address;
1043
963
  }
1044
964
  }
@@ -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;