@n1xyz/nord-ts 0.1.7 → 0.1.9

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 (84) hide show
  1. package/dist/actions.js +39 -82
  2. package/dist/bundle.js +79181 -0
  3. package/dist/client/Nord.d.ts +13 -2
  4. package/dist/client/Nord.js +68 -78
  5. package/dist/client/NordAdmin.d.ts +2 -2
  6. package/dist/client/NordAdmin.js +57 -89
  7. package/dist/client/NordUser.js +118 -147
  8. package/dist/const.js +5 -8
  9. package/dist/error.js +7 -5
  10. package/dist/gen/nord_pb.js +88 -92
  11. package/dist/gen/openapi.d.ts +83 -6
  12. package/dist/gen/openapi.js +1 -2
  13. package/dist/index.js +10 -49
  14. package/dist/types.d.ts +3 -0
  15. package/dist/types.js +21 -60
  16. package/dist/utils.js +38 -86
  17. package/dist/websocket/NordWebSocketClient.js +12 -17
  18. package/dist/websocket/Subscriber.js +6 -7
  19. package/dist/websocket/events.js +1 -2
  20. package/dist/websocket/index.js +10 -15
  21. package/package.json +3 -4
  22. package/dist/api/client.d.ts +0 -14
  23. package/dist/api/client.js +0 -45
  24. package/dist/bridge/client.d.ts +0 -151
  25. package/dist/bridge/client.js +0 -434
  26. package/dist/bridge/const.d.ts +0 -23
  27. package/dist/bridge/const.js +0 -47
  28. package/dist/bridge/index.d.ts +0 -4
  29. package/dist/bridge/index.js +0 -23
  30. package/dist/bridge/types.d.ts +0 -120
  31. package/dist/bridge/types.js +0 -18
  32. package/dist/bridge/utils.d.ts +0 -64
  33. package/dist/bridge/utils.js +0 -131
  34. package/dist/gen/common.d.ts +0 -68
  35. package/dist/gen/common.js +0 -215
  36. package/dist/gen/nord.d.ts +0 -882
  37. package/dist/gen/nord.js +0 -6520
  38. package/dist/idl/bridge.d.ts +0 -569
  39. package/dist/idl/bridge.js +0 -8
  40. package/dist/idl/bridge.json +0 -1506
  41. package/dist/idl/index.d.ts +0 -607
  42. package/dist/idl/index.js +0 -8
  43. package/dist/nord/api/actions.d.ts +0 -126
  44. package/dist/nord/api/actions.js +0 -397
  45. package/dist/nord/api/core.d.ts +0 -16
  46. package/dist/nord/api/core.js +0 -81
  47. package/dist/nord/api/market.d.ts +0 -36
  48. package/dist/nord/api/market.js +0 -96
  49. package/dist/nord/api/metrics.d.ts +0 -67
  50. package/dist/nord/api/metrics.js +0 -229
  51. package/dist/nord/api/queries.d.ts +0 -46
  52. package/dist/nord/api/queries.js +0 -109
  53. package/dist/nord/api/triggers.d.ts +0 -7
  54. package/dist/nord/api/triggers.js +0 -38
  55. package/dist/nord/client/Nord.d.ts +0 -396
  56. package/dist/nord/client/Nord.js +0 -747
  57. package/dist/nord/client/NordAdmin.d.ts +0 -259
  58. package/dist/nord/client/NordAdmin.js +0 -395
  59. package/dist/nord/client/NordClient.d.ts +0 -33
  60. package/dist/nord/client/NordClient.js +0 -45
  61. package/dist/nord/client/NordUser.d.ts +0 -362
  62. package/dist/nord/client/NordUser.js +0 -781
  63. package/dist/nord/index.d.ts +0 -11
  64. package/dist/nord/index.js +0 -36
  65. package/dist/nord/models/Subscriber.d.ts +0 -37
  66. package/dist/nord/models/Subscriber.js +0 -25
  67. package/dist/nord/utils/NordError.d.ts +0 -35
  68. package/dist/nord/utils/NordError.js +0 -49
  69. package/src/actions.ts +0 -333
  70. package/src/client/Nord.ts +0 -934
  71. package/src/client/NordAdmin.ts +0 -484
  72. package/src/client/NordUser.ts +0 -1122
  73. package/src/const.ts +0 -34
  74. package/src/error.ts +0 -76
  75. package/src/gen/.gitkeep +0 -0
  76. package/src/gen/nord_pb.ts +0 -5053
  77. package/src/gen/openapi.ts +0 -2904
  78. package/src/index.ts +0 -11
  79. package/src/types.ts +0 -327
  80. package/src/utils.ts +0 -266
  81. package/src/websocket/NordWebSocketClient.ts +0 -316
  82. package/src/websocket/Subscriber.ts +0 -56
  83. package/src/websocket/events.ts +0 -31
  84. package/src/websocket/index.ts +0 -105
@@ -1,484 +0,0 @@
1
- import { create } from "@bufbuild/protobuf";
2
- import { PublicKey, Transaction } from "@solana/web3.js";
3
- import * as proto from "../gen/nord_pb";
4
- import { decodeHex, signUserPayload } from "../utils";
5
- import { createAction, sendAction, expectReceiptKind } from "../actions";
6
- import { NordError } from "../error";
7
- import { Nord } from "./Nord";
8
- import { FeeTierConfig } from "../gen/nord_pb";
9
-
10
- // NOTE: keep in sync with `acl.rs`.
11
- // NOTE: don't forget `number` as int is internally a u32.
12
- export enum AclRole {
13
- FEE_MANAGER = 1 << 0,
14
- MARKET_MANAGER = 1 << 1,
15
- // TODO: unsure about this?
16
- ADMIN = 1 << 31,
17
- }
18
-
19
- /**
20
- * Administrative client capable of submitting privileged configuration actions.
21
- */
22
- export class NordAdmin {
23
- private readonly nord: Nord;
24
- private readonly admin: PublicKey;
25
- private readonly signFn: (_: Transaction) => Promise<Transaction>;
26
-
27
- private constructor({
28
- nord,
29
- admin,
30
- signFn,
31
- }: {
32
- nord: Nord;
33
- admin: PublicKey;
34
- signFn: (x: Transaction) => Promise<Transaction>;
35
- }) {
36
- this.nord = nord;
37
- this.admin = admin;
38
- this.signFn = signFn;
39
- }
40
-
41
- /** Create a new admin client.
42
- *
43
- * @param nord - Nord instance
44
- * @param admin - The user that will be signing actions.
45
- * @param signFn - Function to sign messages with the admin's wallet.
46
- */
47
- public static new({
48
- nord,
49
- admin,
50
- signFn,
51
- }: Readonly<{
52
- nord: Nord;
53
- admin: PublicKey;
54
- signFn: (m: Transaction) => Promise<Transaction>;
55
- }>): NordAdmin {
56
- return new NordAdmin({
57
- nord,
58
- admin,
59
- signFn,
60
- });
61
- }
62
-
63
- /**
64
- * Submit an action and append the admin signature before sending it to Nord.
65
- *
66
- * @param kind - Action payload describing the admin request
67
- * @throws {NordError} If signing or submission fails
68
- */
69
- private async submitAction(
70
- kind: proto.Action["kind"],
71
- ): Promise<proto.Receipt> {
72
- const timestamp = await this.nord.getTimestamp();
73
- const action = createAction(timestamp, 0, kind);
74
- return sendAction(
75
- this.nord.httpClient,
76
- async (xs: Uint8Array) => {
77
- const signature = await signUserPayload({
78
- payload: xs,
79
- user: this.admin,
80
- signTransaction: this.signFn,
81
- });
82
- return Uint8Array.from([...xs, ...signature]);
83
- },
84
- action,
85
- );
86
- }
87
-
88
- /** Set acl permissions for a given user.
89
- *
90
- * If all roles are removed, the user is removed from the acl.
91
- *
92
- * @param target - User to update.
93
- * @param addRoles - Roles to add to the user.
94
- * @param removeRoles - Reles to remove from the user.
95
- */
96
- async updateAcl({
97
- target,
98
- addRoles,
99
- removeRoles,
100
- }: Readonly<{
101
- target: PublicKey;
102
- addRoles: AclRole[];
103
- removeRoles: AclRole[];
104
- }>): Promise<{ actionId: bigint } & proto.Receipt_AclUpdated> {
105
- const allRoles = addRoles.concat(removeRoles);
106
- if (allRoles.length !== new Set(allRoles).size) {
107
- throw new NordError("duplicate roles in acl update; must be unique");
108
- }
109
-
110
- let mask = 0;
111
- let values = 0;
112
- for (const role of allRoles) {
113
- mask |= role;
114
- }
115
- for (const role of addRoles) {
116
- values |= role;
117
- }
118
-
119
- const receipt = await this.submitAction({
120
- case: "updateAcl",
121
- value: create(proto.Action_UpdateAclSchema, {
122
- aclPubkey: this.admin.toBytes(),
123
- targetPubkey: target.toBytes(),
124
- rolesValue: values,
125
- rolesMask: mask,
126
- }),
127
- });
128
- expectReceiptKind(receipt, "aclUpdated", "update acl");
129
-
130
- return { ...receipt.kind.value, actionId: receipt.actionId };
131
- }
132
-
133
- /**
134
- * Register a new token that can be listed on Nord.
135
- *
136
- * @param tokenDecimals - Decimal shift used when parsing deposits/withdrawals
137
- * @param weightBps - Risk weight in basis points applied in account value calculations
138
- * @param viewSymbol - Symbol surfaced to Nord clients
139
- * @param oracleSymbol - Symbol resolved by the oracle adapter
140
- * @param mintAddr - Solana mint backing this token
141
- * @returns Action identifier and resulting token metadata
142
- * @throws {NordError} If the action submission fails
143
- */
144
- async createToken({
145
- tokenDecimals,
146
- weightBps,
147
- viewSymbol,
148
- oracleSymbol,
149
- mintAddr,
150
- }: Readonly<{
151
- tokenDecimals: number;
152
- weightBps: number;
153
- viewSymbol: string;
154
- oracleSymbol: string;
155
- mintAddr: PublicKey;
156
- }>): Promise<{ actionId: bigint } & proto.Receipt_InsertTokenResult> {
157
- const receipt = await this.submitAction({
158
- case: "createToken",
159
- value: create(proto.Action_CreateTokenSchema, {
160
- aclPubkey: this.admin.toBytes(),
161
- tokenDecimals,
162
- weightBps,
163
- viewSymbol,
164
- oracleSymbol,
165
- solAddr: mintAddr.toBytes(),
166
- }),
167
- });
168
- expectReceiptKind(receipt, "insertTokenResult", "create token");
169
- return { actionId: receipt.actionId, ...receipt.kind.value };
170
- }
171
-
172
- /**
173
- * Open a new market with the provided trading parameters.
174
- *
175
- * @param sizeDecimals - Decimal shift for contract sizes
176
- * @param priceDecimals - Decimal shift for price ticks
177
- * @param imfBps - Base initial margin fraction (IMF) in basis points, see docs/MARKETS.md
178
- * @param cmfBps - Cancel margin fraction (CMF) in basis points, see docs/MARKETS.md
179
- * @param mmfBps - Maintenance margin fraction (MMF) in basis points, see docs/MARKETS.md
180
- * @param marketType - Spot or perpetual market type
181
- * @param viewSymbol - Symbol exposed to Nord clients
182
- * @param oracleSymbol - Symbol resolved by the oracle adapter
183
- * @param baseTokenId - Registered base token backing this market
184
- * @returns Action identifier and resulting market metadata
185
- * @throws {NordError} If the action submission fails
186
- */
187
- async createMarket({
188
- sizeDecimals,
189
- priceDecimals,
190
- imfBps,
191
- cmfBps,
192
- mmfBps,
193
- marketType,
194
- viewSymbol,
195
- oracleSymbol,
196
- baseTokenId,
197
- }: Readonly<{
198
- sizeDecimals: number;
199
- priceDecimals: number;
200
- imfBps: number;
201
- cmfBps: number;
202
- mmfBps: number;
203
- marketType: proto.MarketType;
204
- viewSymbol: string;
205
- oracleSymbol: string;
206
- baseTokenId: number;
207
- }>): Promise<{ actionId: bigint } & proto.Receipt_InsertMarketResult> {
208
- const receipt = await this.submitAction({
209
- case: "createMarket",
210
- value: create(proto.Action_CreateMarketSchema, {
211
- aclPubkey: this.admin.toBytes(),
212
- sizeDecimals,
213
- priceDecimals,
214
- imfBps,
215
- cmfBps,
216
- mmfBps,
217
- marketType,
218
- viewSymbol,
219
- oracleSymbol,
220
- baseTokenId,
221
- }),
222
- });
223
- expectReceiptKind(receipt, "insertMarketResult", "create market");
224
- return { actionId: receipt.actionId, ...receipt.kind.value };
225
- }
226
-
227
- /**
228
- * Update the Pyth guardian set used for verifying Wormhole messages.
229
- *
230
- * Each address must decode from a 20-byte hex string (with or without a
231
- * leading `0x` prefix). The engine validates the supplied guardian set index
232
- * before applying the update.
233
- *
234
- * @param guardianSetIndex - Wormhole guardian set index that must already exist
235
- * @param addresses - 20-byte hex-encoded guardian addresses
236
- * @returns Action identifier and guardian update receipt
237
- * @throws {NordError} If the action submission fails
238
- */
239
- async pythSetWormholeGuardians({
240
- guardianSetIndex,
241
- addresses,
242
- }: Readonly<{
243
- guardianSetIndex: number;
244
- addresses: readonly string[];
245
- }>): Promise<{ actionId: bigint } & proto.Receipt_UpdateGuardianSetResult> {
246
- const parsedAddresses = addresses.map((address) => {
247
- try {
248
- const decoded = decodeHex(address);
249
- if (decoded.length !== 20) {
250
- throw new Error("guardian address must be 20 bytes");
251
- }
252
- return decoded;
253
- } catch (e) {
254
- throw new NordError(
255
- "invalid guardian address; must be a 20 byte hex address",
256
- { cause: e },
257
- );
258
- }
259
- });
260
-
261
- const receipt = await this.submitAction({
262
- case: "pythSetWormholeGuardians",
263
- value: create(proto.Action_PythSetWormholeGuardiansSchema, {
264
- aclPubkey: this.admin.toBytes(),
265
- guardianSetIndex,
266
- addresses: parsedAddresses,
267
- }),
268
- });
269
- expectReceiptKind(
270
- receipt,
271
- "updateGuardianSetResult",
272
- "update wormhole guardians",
273
- );
274
- return { actionId: receipt.actionId, ...receipt.kind.value };
275
- }
276
-
277
- /**
278
- * Link an oracle symbol to a specific Pyth price feed.
279
- *
280
- * The price feed identifier must decode to 32 bytes (with or without a
281
- * leading `0x` prefix). Use this call to create or update the mapping used
282
- * by the oracle integration.
283
- *
284
- * @param oracleSymbol - Symbol resolved by the oracle adapter
285
- * @param priceFeedId - 32-byte hex-encoded Pyth price feed identifier
286
- * @returns Action identifier and symbol feed receipt
287
- * @throws {NordError} If the action submission fails
288
- */
289
- async pythSetSymbolFeed({
290
- oracleSymbol,
291
- priceFeedId: priceFeedIdHex,
292
- }: Readonly<{
293
- oracleSymbol: string;
294
- priceFeedId: string;
295
- }>): Promise<{ actionId: bigint } & proto.Receipt_OracleSymbolFeedResult> {
296
- let priceFeedId: Uint8Array;
297
- try {
298
- priceFeedId = decodeHex(priceFeedIdHex);
299
- if (priceFeedId.length !== 32) {
300
- throw new Error("price feed id must be 32 bytes");
301
- }
302
- } catch (e) {
303
- throw new NordError("invalid price feed id; must be a 32 byte hex id", {
304
- cause: e,
305
- });
306
- }
307
-
308
- const receipt = await this.submitAction({
309
- case: "pythSetSymbolFeed",
310
- value: create(proto.Action_PythSetSymbolFeedSchema, {
311
- aclPubkey: this.admin.toBytes(),
312
- oracleSymbol,
313
- priceFeedId,
314
- }),
315
- });
316
- expectReceiptKind(receipt, "oracleSymbolFeedResult", "set symbol feed");
317
- return { actionId: receipt.actionId, ...receipt.kind.value };
318
- }
319
-
320
- /**
321
- * Pause all trading activity on the exchange.
322
- *
323
- * @returns Action identifier confirming the pause
324
- * @throws {NordError} If the action submission fails
325
- */
326
- async pause(): Promise<{ actionId: bigint }> {
327
- const receipt = await this.submitAction({
328
- case: "pause",
329
- value: create(proto.Action_PauseSchema, {
330
- aclPubkey: this.admin.toBytes(),
331
- }),
332
- });
333
- expectReceiptKind(receipt, "paused", "pause");
334
- return { actionId: receipt.actionId };
335
- }
336
-
337
- /**
338
- * Resume trading activity after a pause.
339
- *
340
- * @returns Action identifier confirming the unpause
341
- * @throws {NordError} If the action submission fails
342
- */
343
- async unpause(): Promise<{ actionId: bigint }> {
344
- const receipt = await this.submitAction({
345
- case: "unpause",
346
- value: create(proto.Action_UnpauseSchema, {
347
- aclPubkey: this.admin.toBytes(),
348
- }),
349
- });
350
- expectReceiptKind(receipt, "unpaused", "unpause");
351
- return { actionId: receipt.actionId };
352
- }
353
-
354
- /**
355
- * Freeze an individual market, preventing new trades and orders.
356
- *
357
- * @param marketId - Target market identifier
358
- * @returns Action identifier and freeze receipt
359
- * @throws {NordError} If the action submission fails
360
- */
361
- async freezeMarket({
362
- marketId,
363
- }: Readonly<{
364
- marketId: number;
365
- }>): Promise<{ actionId: bigint } & proto.Receipt_MarketFreezeUpdated> {
366
- const receipt = await this.submitAction({
367
- case: "freezeMarket",
368
- value: create(proto.Action_FreezeMarketSchema, {
369
- marketId,
370
- aclPubkey: this.admin.toBytes(),
371
- }),
372
- });
373
- expectReceiptKind(receipt, "marketFreezeUpdated", "freeze market");
374
- return { actionId: receipt.actionId, ...receipt.kind.value };
375
- }
376
-
377
- /**
378
- * Unfreeze a market that was previously halted.
379
- *
380
- * @param marketId - Target market identifier
381
- * @returns Action identifier and freeze receipt
382
- * @throws {NordError} If the action submission fails
383
- */
384
- async unfreezeMarket({
385
- marketId,
386
- }: Readonly<{
387
- marketId: number;
388
- }>): Promise<{ actionId: bigint } & proto.Receipt_MarketFreezeUpdated> {
389
- const receipt = await this.submitAction({
390
- case: "unfreezeMarket",
391
- value: create(proto.Action_UnfreezeMarketSchema, {
392
- marketId,
393
- aclPubkey: this.admin.toBytes(),
394
- }),
395
- });
396
- expectReceiptKind(receipt, "marketFreezeUpdated", "unfreeze market");
397
- return { actionId: receipt.actionId, ...receipt.kind.value };
398
- }
399
-
400
- /**
401
- * Append a new fee tier to the account bracket configuration.
402
- *
403
- * - The engine supports at most 16 tiers (ids 0–15). Tier 0 is reserved for
404
- * the default Nord fees; use `updateFeeTier` if you need to change it.
405
- * - The first appended tier receives id 1, and subsequent tiers increment the id.
406
- *
407
- * @param config - Fee tier configuration to insert
408
- * @returns Action identifier and fee tier addition receipt
409
- * @throws {NordError} If the action submission fails or the new tier exceeds the maximum range (0-15).
410
- */
411
- async addFeeTier({
412
- config,
413
- }: Readonly<{
414
- config: FeeTierConfig;
415
- }>): Promise<{ actionId: bigint } & proto.Receipt_FeeTierAdded> {
416
- const receipt = await this.submitAction({
417
- case: "addFeeTier",
418
- value: create(proto.Action_AddFeeTierSchema, {
419
- aclPubkey: this.admin.toBytes(),
420
- config: create(proto.FeeTierConfigSchema, config),
421
- }),
422
- });
423
- expectReceiptKind(receipt, "feeTierAdded", "add fee tier");
424
- return { actionId: receipt.actionId, ...receipt.kind.value };
425
- }
426
-
427
- /**
428
- * Update an existing fee tier with new maker/taker rates.
429
- *
430
- * Tier identifiers must already exist; attempting to update a missing tier
431
- * causes the action to fail.
432
- *
433
- * @param tierId - Existing fee tier identifier to update
434
- * @param config - Replacement configuration for the tier
435
- * @returns Action identifier and fee tier update receipt
436
- * @throws {NordError} If the action submission fails or the tier ID exceeds the configured range.
437
- */
438
- async updateFeeTier({
439
- tierId,
440
- config,
441
- }: Readonly<{
442
- tierId: number;
443
- config: FeeTierConfig;
444
- }>): Promise<{ actionId: bigint } & proto.Receipt_FeeTierUpdated> {
445
- const receipt = await this.submitAction({
446
- case: "updateFeeTier",
447
- value: create(proto.Action_UpdateFeeTierSchema, {
448
- aclPubkey: this.admin.toBytes(),
449
- id: tierId,
450
- config: create(proto.FeeTierConfigSchema, config),
451
- }),
452
- });
453
- expectReceiptKind(receipt, "feeTierUpdated", "update fee tier");
454
- return { actionId: receipt.actionId, ...receipt.kind.value };
455
- }
456
-
457
- /**
458
- * Assign a fee tier to one or more accounts.
459
- *
460
- * The tier id must be within the configured range (0–15). Every account starts
461
- * on tier 0; assigning it to another tier requires that tier to exist already.
462
- * Invalid account ids or tier ids cause the action to fail.
463
- *
464
- * @param accounts - Account IDs to update
465
- * @param tierId - Target fee tier identifier
466
- * @returns Action identifier and accounts-tier receipt
467
- * @throws {NordError} If the tier id exceeds the configured range or an account id is invalid.
468
- */
469
- async updateAccountsTier(
470
- accounts: number[],
471
- tierId: number,
472
- ): Promise<{ actionId: bigint } & proto.Receipt_AccountsTierUpdated> {
473
- const receipt = await this.submitAction({
474
- case: "updateAccountsTier",
475
- value: create(proto.Action_UpdateAccountsTierSchema, {
476
- aclPubkey: this.admin.toBytes(),
477
- accounts,
478
- tierId,
479
- }),
480
- });
481
- expectReceiptKind(receipt, "accountsTierUpdated", "update accounts tier");
482
- return { actionId: receipt.actionId, ...receipt.kind.value };
483
- }
484
- }