@n1xyz/nord-ts 0.1.6 → 0.1.7

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