@nadohq/engine-client 0.1.0-alpha.1

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 (142) hide show
  1. package/README.md +2 -0
  2. package/dist/EngineBaseClient.cjs +166 -0
  3. package/dist/EngineBaseClient.cjs.map +1 -0
  4. package/dist/EngineBaseClient.d.cts +75 -0
  5. package/dist/EngineBaseClient.d.ts +75 -0
  6. package/dist/EngineBaseClient.js +133 -0
  7. package/dist/EngineBaseClient.js.map +1 -0
  8. package/dist/EngineClient.cjs +40 -0
  9. package/dist/EngineClient.cjs.map +1 -0
  10. package/dist/EngineClient.d.cts +23 -0
  11. package/dist/EngineClient.d.ts +23 -0
  12. package/dist/EngineClient.js +15 -0
  13. package/dist/EngineClient.js.map +1 -0
  14. package/dist/EngineExecuteBuilder.cjs +304 -0
  15. package/dist/EngineExecuteBuilder.cjs.map +1 -0
  16. package/dist/EngineExecuteBuilder.d.cts +118 -0
  17. package/dist/EngineExecuteBuilder.d.ts +118 -0
  18. package/dist/EngineExecuteBuilder.js +282 -0
  19. package/dist/EngineExecuteBuilder.js.map +1 -0
  20. package/dist/EngineExecuteClient.cjs +114 -0
  21. package/dist/EngineExecuteClient.cjs.map +1 -0
  22. package/dist/EngineExecuteClient.d.cts +28 -0
  23. package/dist/EngineExecuteClient.d.ts +28 -0
  24. package/dist/EngineExecuteClient.js +89 -0
  25. package/dist/EngineExecuteClient.js.map +1 -0
  26. package/dist/EngineQueryClient.cjs +431 -0
  27. package/dist/EngineQueryClient.cjs.map +1 -0
  28. package/dist/EngineQueryClient.d.cts +143 -0
  29. package/dist/EngineQueryClient.d.ts +143 -0
  30. package/dist/EngineQueryClient.js +424 -0
  31. package/dist/EngineQueryClient.js.map +1 -0
  32. package/dist/EngineWebClient.cjs +75 -0
  33. package/dist/EngineWebClient.cjs.map +1 -0
  34. package/dist/EngineWebClient.d.cts +31 -0
  35. package/dist/EngineWebClient.d.ts +31 -0
  36. package/dist/EngineWebClient.js +50 -0
  37. package/dist/EngineWebClient.js.map +1 -0
  38. package/dist/endpoints.cjs +49 -0
  39. package/dist/endpoints.cjs.map +1 -0
  40. package/dist/endpoints.d.cts +7 -0
  41. package/dist/endpoints.d.ts +7 -0
  42. package/dist/endpoints.js +22 -0
  43. package/dist/endpoints.js.map +1 -0
  44. package/dist/index.cjs +31 -0
  45. package/dist/index.cjs.map +1 -0
  46. package/dist/index.d.cts +20 -0
  47. package/dist/index.d.ts +20 -0
  48. package/dist/index.js +6 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/types/EngineServerFailureError.cjs +36 -0
  51. package/dist/types/EngineServerFailureError.cjs.map +1 -0
  52. package/dist/types/EngineServerFailureError.d.cts +11 -0
  53. package/dist/types/EngineServerFailureError.d.ts +11 -0
  54. package/dist/types/EngineServerFailureError.js +11 -0
  55. package/dist/types/EngineServerFailureError.js.map +1 -0
  56. package/dist/types/clientExecuteTypes.cjs +19 -0
  57. package/dist/types/clientExecuteTypes.cjs.map +1 -0
  58. package/dist/types/clientExecuteTypes.d.cts +74 -0
  59. package/dist/types/clientExecuteTypes.d.ts +74 -0
  60. package/dist/types/clientExecuteTypes.js +1 -0
  61. package/dist/types/clientExecuteTypes.js.map +1 -0
  62. package/dist/types/clientQueryTypes.cjs +19 -0
  63. package/dist/types/clientQueryTypes.cjs.map +1 -0
  64. package/dist/types/clientQueryTypes.d.cts +189 -0
  65. package/dist/types/clientQueryTypes.d.ts +189 -0
  66. package/dist/types/clientQueryTypes.js +1 -0
  67. package/dist/types/clientQueryTypes.js.map +1 -0
  68. package/dist/types/index.cjs +39 -0
  69. package/dist/types/index.cjs.map +1 -0
  70. package/dist/types/index.d.cts +10 -0
  71. package/dist/types/index.d.ts +10 -0
  72. package/dist/types/index.js +10 -0
  73. package/dist/types/index.js.map +1 -0
  74. package/dist/types/serverExecuteTypes.cjs +19 -0
  75. package/dist/types/serverExecuteTypes.cjs.map +1 -0
  76. package/dist/types/serverExecuteTypes.d.cts +91 -0
  77. package/dist/types/serverExecuteTypes.d.ts +91 -0
  78. package/dist/types/serverExecuteTypes.js +1 -0
  79. package/dist/types/serverExecuteTypes.js.map +1 -0
  80. package/dist/types/serverQueryModelTypes.cjs +19 -0
  81. package/dist/types/serverQueryModelTypes.cjs.map +1 -0
  82. package/dist/types/serverQueryModelTypes.d.cts +73 -0
  83. package/dist/types/serverQueryModelTypes.d.ts +73 -0
  84. package/dist/types/serverQueryModelTypes.js +1 -0
  85. package/dist/types/serverQueryModelTypes.js.map +1 -0
  86. package/dist/types/serverQueryTypes.cjs +19 -0
  87. package/dist/types/serverQueryTypes.cjs.map +1 -0
  88. package/dist/types/serverQueryTypes.d.cts +292 -0
  89. package/dist/types/serverQueryTypes.d.ts +292 -0
  90. package/dist/types/serverQueryTypes.js +1 -0
  91. package/dist/types/serverQueryTypes.js.map +1 -0
  92. package/dist/types/serverSubscriptionEventTypes.cjs +19 -0
  93. package/dist/types/serverSubscriptionEventTypes.cjs.map +1 -0
  94. package/dist/types/serverSubscriptionEventTypes.d.cts +71 -0
  95. package/dist/types/serverSubscriptionEventTypes.d.ts +71 -0
  96. package/dist/types/serverSubscriptionEventTypes.js +1 -0
  97. package/dist/types/serverSubscriptionEventTypes.js.map +1 -0
  98. package/dist/types/serverSubscriptionTypes.cjs +19 -0
  99. package/dist/types/serverSubscriptionTypes.cjs.map +1 -0
  100. package/dist/types/serverSubscriptionTypes.d.cts +63 -0
  101. package/dist/types/serverSubscriptionTypes.d.ts +63 -0
  102. package/dist/types/serverSubscriptionTypes.js +1 -0
  103. package/dist/types/serverSubscriptionTypes.js.map +1 -0
  104. package/dist/utils/index.cjs +25 -0
  105. package/dist/utils/index.cjs.map +1 -0
  106. package/dist/utils/index.d.cts +6 -0
  107. package/dist/utils/index.d.ts +6 -0
  108. package/dist/utils/index.js +3 -0
  109. package/dist/utils/index.js.map +1 -0
  110. package/dist/utils/productEngineTypeMappers.cjs +49 -0
  111. package/dist/utils/productEngineTypeMappers.cjs.map +1 -0
  112. package/dist/utils/productEngineTypeMappers.d.cts +7 -0
  113. package/dist/utils/productEngineTypeMappers.d.ts +7 -0
  114. package/dist/utils/productEngineTypeMappers.js +23 -0
  115. package/dist/utils/productEngineTypeMappers.js.map +1 -0
  116. package/dist/utils/queryDataMappers.cjs +282 -0
  117. package/dist/utils/queryDataMappers.cjs.map +1 -0
  118. package/dist/utils/queryDataMappers.d.cts +18 -0
  119. package/dist/utils/queryDataMappers.d.ts +18 -0
  120. package/dist/utils/queryDataMappers.js +258 -0
  121. package/dist/utils/queryDataMappers.js.map +1 -0
  122. package/package.json +52 -0
  123. package/src/EngineBaseClient.ts +223 -0
  124. package/src/EngineClient.ts +13 -0
  125. package/src/EngineExecuteBuilder.ts +381 -0
  126. package/src/EngineExecuteClient.ts +122 -0
  127. package/src/EngineQueryClient.ts +553 -0
  128. package/src/EngineWebClient.ts +72 -0
  129. package/src/endpoints.ts +21 -0
  130. package/src/index.ts +4 -0
  131. package/src/types/EngineServerFailureError.ts +12 -0
  132. package/src/types/clientExecuteTypes.ts +118 -0
  133. package/src/types/clientQueryTypes.ts +267 -0
  134. package/src/types/index.ts +8 -0
  135. package/src/types/serverExecuteTypes.ts +138 -0
  136. package/src/types/serverQueryModelTypes.ts +83 -0
  137. package/src/types/serverQueryTypes.ts +382 -0
  138. package/src/types/serverSubscriptionEventTypes.ts +74 -0
  139. package/src/types/serverSubscriptionTypes.ts +79 -0
  140. package/src/utils/index.ts +1 -0
  141. package/src/utils/productEngineTypeMappers.ts +24 -0
  142. package/src/utils/queryDataMappers.ts +303 -0
@@ -0,0 +1,122 @@
1
+ import { EngineBaseClient, EngineClientOpts } from './EngineBaseClient';
2
+ import { EngineExecuteBuilder } from './EngineExecuteBuilder';
3
+ import {
4
+ EngineExecuteRequestParamsByType,
5
+ EnginePlaceIsolatedOrderResult,
6
+ EnginePlaceOrderResult,
7
+ } from './types';
8
+
9
+ export class EngineExecuteClient extends EngineBaseClient {
10
+ readonly payloadBuilder: EngineExecuteBuilder;
11
+
12
+ constructor(opts: EngineClientOpts) {
13
+ super(opts);
14
+ this.payloadBuilder = new EngineExecuteBuilder(this);
15
+ }
16
+
17
+ async liquidateSubaccount(
18
+ params: EngineExecuteRequestParamsByType['liquidate_subaccount'],
19
+ ) {
20
+ return this.execute(
21
+ 'liquidate_subaccount',
22
+ await this.payloadBuilder.buildLiquidateSubaccountPayload(params),
23
+ );
24
+ }
25
+
26
+ async withdrawCollateral(
27
+ params: EngineExecuteRequestParamsByType['withdraw_collateral'],
28
+ ) {
29
+ return this.execute(
30
+ 'withdraw_collateral',
31
+ await this.payloadBuilder.buildWithdrawCollateralPayload(params),
32
+ );
33
+ }
34
+
35
+ async placeOrder(
36
+ params: EngineExecuteRequestParamsByType['place_order'],
37
+ ): Promise<EnginePlaceOrderResult> {
38
+ const placeOrderPayload =
39
+ await this.payloadBuilder.buildPlaceOrderPayload(params);
40
+ return {
41
+ ...(await this.execute('place_order', placeOrderPayload.payload)),
42
+ orderParams: placeOrderPayload.orderParams,
43
+ };
44
+ }
45
+
46
+ async placeIsolatedOrder(
47
+ params: EngineExecuteRequestParamsByType['place_isolated_order'],
48
+ ): Promise<EnginePlaceIsolatedOrderResult> {
49
+ const placeOrderPayload =
50
+ await this.payloadBuilder.buildIsolatedPlaceOrderPayload(params);
51
+ return {
52
+ ...(await this.execute(
53
+ 'place_isolated_order',
54
+ placeOrderPayload.payload,
55
+ )),
56
+ orderParams: placeOrderPayload.orderParams,
57
+ };
58
+ }
59
+
60
+ async cancelOrders(
61
+ params: EngineExecuteRequestParamsByType['cancel_orders'],
62
+ ) {
63
+ return this.execute(
64
+ 'cancel_orders',
65
+ await this.payloadBuilder.buildCancelOrdersPayload(params),
66
+ );
67
+ }
68
+
69
+ async cancelAndPlace(
70
+ params: EngineExecuteRequestParamsByType['cancel_and_place'],
71
+ ) {
72
+ const cancelOrdersPayload =
73
+ await this.payloadBuilder.buildCancelOrdersPayload(params.cancelOrders);
74
+ const placeOrderPayload = await this.payloadBuilder.buildPlaceOrderPayload(
75
+ params.placeOrder,
76
+ );
77
+ return this.execute('cancel_and_place', {
78
+ cancel_tx: cancelOrdersPayload.tx,
79
+ cancel_signature: cancelOrdersPayload.signature,
80
+ place_order: placeOrderPayload.payload,
81
+ });
82
+ }
83
+
84
+ async cancelProductOrders(
85
+ params: EngineExecuteRequestParamsByType['cancel_product_orders'],
86
+ ) {
87
+ return this.execute(
88
+ 'cancel_product_orders',
89
+ await this.payloadBuilder.buildCancelProductOrdersPayload(params),
90
+ );
91
+ }
92
+
93
+ async linkSigner(params: EngineExecuteRequestParamsByType['link_signer']) {
94
+ return this.execute(
95
+ 'link_signer',
96
+ await this.payloadBuilder.buildLinkSignerPayload(params),
97
+ );
98
+ }
99
+
100
+ async transferQuote(
101
+ params: EngineExecuteRequestParamsByType['transfer_quote'],
102
+ ) {
103
+ return this.execute(
104
+ 'transfer_quote',
105
+ await this.payloadBuilder.buildTransferQuotePayload(params),
106
+ );
107
+ }
108
+
109
+ async mintVlp(params: EngineExecuteRequestParamsByType['mint_vlp']) {
110
+ return this.execute(
111
+ 'mint_vlp',
112
+ await this.payloadBuilder.buildMintVlpPayload(params),
113
+ );
114
+ }
115
+
116
+ async burnVlp(params: EngineExecuteRequestParamsByType['burn_vlp']) {
117
+ return this.execute(
118
+ 'burn_vlp',
119
+ await this.payloadBuilder.buildBurnVlpPayload(params),
120
+ );
121
+ }
122
+ }
@@ -0,0 +1,553 @@
1
+ import {
2
+ encodeSignedOrder,
3
+ MarketWithProduct,
4
+ subaccountToHex,
5
+ } from '@nadohq/contracts';
6
+ import {
7
+ addDecimals,
8
+ BigDecimal,
9
+ mapValues,
10
+ removeDecimals,
11
+ toBigDecimal,
12
+ toIntegerString,
13
+ } from '@nadohq/utils';
14
+ import { EngineBaseClient } from './EngineBaseClient';
15
+ import {
16
+ EngineServerStatusResponse,
17
+ EngineServerSubaccountInfoQueryParams,
18
+ EngineSymbolsResponse,
19
+ GetEngineAllMarketsResponse,
20
+ GetEngineContractsResponse,
21
+ GetEngineEstimatedSubaccountSummaryParams,
22
+ GetEngineHealthGroupsResponse,
23
+ GetEngineInsuranceResponse,
24
+ GetEngineIsolatedPositionsParams,
25
+ GetEngineIsolatedPositionsResponse,
26
+ GetEngineLinkedSignerParams,
27
+ GetEngineLinkedSignerResponse,
28
+ GetEngineMarketLiquidityParams,
29
+ GetEngineMarketLiquidityResponse,
30
+ GetEngineMarketPriceParams,
31
+ GetEngineMarketPriceResponse,
32
+ GetEngineMarketPricesParams,
33
+ GetEngineMarketPricesResponse,
34
+ GetEngineMaxMintVlpAmountParams,
35
+ GetEngineMaxMintVlpAmountResponse,
36
+ GetEngineMaxOrderSizeParams,
37
+ GetEngineMaxOrderSizeResponse,
38
+ GetEngineMaxWithdrawableParams,
39
+ GetEngineMaxWithdrawableResponse,
40
+ GetEngineMinDepositRatesResponse,
41
+ GetEngineOrderParams,
42
+ GetEngineOrderResponse,
43
+ GetEngineSubaccountFeeRatesParams,
44
+ GetEngineSubaccountFeeRatesResponse,
45
+ GetEngineSubaccountOrdersParams,
46
+ GetEngineSubaccountOrdersResponse,
47
+ GetEngineSubaccountProductOrdersParams,
48
+ GetEngineSubaccountProductOrdersResponse,
49
+ GetEngineSubaccountSummaryParams,
50
+ GetEngineSubaccountSummaryResponse,
51
+ GetEngineSymbolsParams,
52
+ SubaccountOrderFeeRates,
53
+ ValidateEngineOrderParams,
54
+ ValidateEngineOrderResponse,
55
+ ValidateSignedEngineOrderParams,
56
+ } from './types';
57
+ import { mapProductEngineType } from './utils/productEngineTypeMappers';
58
+ import {
59
+ mapEngineMarketPrice,
60
+ mapEngineServerIsolatedPositions,
61
+ mapEngineServerOrder,
62
+ mapEngineServerPerpProduct,
63
+ mapEngineServerSpotProduct,
64
+ mapEngineServerSymbols,
65
+ mapEngineServerTickLiquidity,
66
+ mapSubaccountSummary,
67
+ } from './utils/queryDataMappers';
68
+
69
+ export class EngineQueryClient extends EngineBaseClient {
70
+ /**
71
+ * Retrieves the set of contracts that the engine is interfacing with
72
+ */
73
+ async getContracts(): Promise<GetEngineContractsResponse> {
74
+ const baseResponse = await this.query('contracts', {});
75
+ return {
76
+ chainId: Number(baseResponse.chain_id),
77
+ endpointAddr: baseResponse.endpoint_addr,
78
+ orderbookAddrs: baseResponse.book_addrs,
79
+ };
80
+ }
81
+
82
+ /**
83
+ * Retrieves current engine status
84
+ */
85
+ async getStatus(): Promise<EngineServerStatusResponse> {
86
+ return this.query('status', {});
87
+ }
88
+
89
+ /**
90
+ * Retrieves a subaccount summary reflective of the state within the offchain engine. This adheres to the
91
+ * same return interface as the contract version
92
+ *
93
+ * @param params
94
+ */
95
+ async getSubaccountSummary(
96
+ params: GetEngineSubaccountSummaryParams,
97
+ ): Promise<GetEngineSubaccountSummaryResponse> {
98
+ const subaccount = subaccountToHex({
99
+ subaccountOwner: params.subaccountOwner,
100
+ subaccountName: params.subaccountName,
101
+ });
102
+ const baseResponse = await this.query('subaccount_info', {
103
+ subaccount,
104
+ });
105
+
106
+ return mapSubaccountSummary(baseResponse);
107
+ }
108
+
109
+ /**
110
+ * Retrieves a list of isolated positions
111
+ *
112
+ * @param params
113
+ */
114
+ async getIsolatedPositions(
115
+ params: GetEngineIsolatedPositionsParams,
116
+ ): Promise<GetEngineIsolatedPositionsResponse> {
117
+ const subaccount = subaccountToHex({
118
+ subaccountOwner: params.subaccountOwner,
119
+ subaccountName: params.subaccountName,
120
+ });
121
+ const baseResponse = await this.query('isolated_positions', {
122
+ subaccount,
123
+ });
124
+
125
+ return mapEngineServerIsolatedPositions(baseResponse);
126
+ }
127
+
128
+ /**
129
+ * Retrieves an estimated subaccount summary with the applied transactions
130
+ *
131
+ * @param params
132
+ */
133
+ async getEstimatedSubaccountSummary(
134
+ params: GetEngineEstimatedSubaccountSummaryParams,
135
+ ): Promise<GetEngineSubaccountSummaryResponse> {
136
+ const subaccount = subaccountToHex({
137
+ subaccountOwner: params.subaccountOwner,
138
+ subaccountName: params.subaccountName,
139
+ });
140
+ const queryParams: EngineServerSubaccountInfoQueryParams = {
141
+ subaccount: subaccount,
142
+ txns: params.txs.map(
143
+ (
144
+ tx,
145
+ ): NonNullable<
146
+ EngineServerSubaccountInfoQueryParams['txns']
147
+ >[number] => {
148
+ switch (tx.type) {
149
+ case 'apply_delta':
150
+ return {
151
+ apply_delta: {
152
+ product_id: tx.tx.productId,
153
+ subaccount,
154
+ amount_delta: toIntegerString(tx.tx.amountDelta),
155
+ v_quote_delta: toIntegerString(tx.tx.vQuoteDelta),
156
+ },
157
+ };
158
+ }
159
+ },
160
+ ),
161
+ };
162
+ const baseResponse = await this.query('subaccount_info', {
163
+ subaccount: queryParams.subaccount,
164
+ txns: JSON.stringify(queryParams.txns),
165
+ });
166
+
167
+ return mapSubaccountSummary(baseResponse);
168
+ }
169
+
170
+ /**
171
+ * Retrieves symbols and product info
172
+ *
173
+ * @param params
174
+ */
175
+ async getSymbols(
176
+ params: GetEngineSymbolsParams,
177
+ ): Promise<EngineSymbolsResponse> {
178
+ const baseResponse = await this.query('symbols', {
179
+ product_ids: params.productIds,
180
+ product_type:
181
+ params.productType != null
182
+ ? mapProductEngineType(params.productType)
183
+ : undefined,
184
+ });
185
+ return mapEngineServerSymbols(baseResponse);
186
+ }
187
+
188
+ /**
189
+ * Retrieves all market states as per the offchain engine. Same return interface as contracts
190
+ */
191
+ async getAllMarkets(): Promise<GetEngineAllMarketsResponse> {
192
+ const markets: MarketWithProduct[] = [];
193
+
194
+ const baseResponse = await this.query('all_products', {});
195
+ baseResponse.spot_products.forEach((spotProduct) => {
196
+ markets.push(mapEngineServerSpotProduct(spotProduct));
197
+ });
198
+ baseResponse.perp_products.forEach((perpProduct) => {
199
+ markets.push(mapEngineServerPerpProduct(perpProduct));
200
+ });
201
+
202
+ return markets;
203
+ }
204
+
205
+ /**
206
+ * Retrieves all markets by chain id.
207
+ */
208
+ async getEdgeAllMarkets(): Promise<Record<number, MarketWithProduct[]>> {
209
+ const baseResponse = await this.query('edge_all_products', {});
210
+
211
+ return mapValues(baseResponse.edge_all_products, (allProducts) => {
212
+ const markets: MarketWithProduct[] = [];
213
+
214
+ allProducts.spot_products.forEach((spotProduct) => {
215
+ markets.push(mapEngineServerSpotProduct(spotProduct));
216
+ });
217
+
218
+ allProducts.perp_products.forEach((perpProduct) => {
219
+ markets.push(mapEngineServerPerpProduct(perpProduct));
220
+ });
221
+
222
+ return markets;
223
+ });
224
+ }
225
+
226
+ /**
227
+ * Retrieves all health groups (linked spot & perp products) from the engine
228
+ */
229
+ async getHealthGroups(): Promise<GetEngineHealthGroupsResponse> {
230
+ const baseResponse = await this.query('health_groups', {});
231
+
232
+ return {
233
+ healthGroups: baseResponse.health_groups.map(
234
+ ([spotProductId, perpProductId]) => {
235
+ return {
236
+ spotProductId,
237
+ perpProductId,
238
+ };
239
+ },
240
+ ),
241
+ };
242
+ }
243
+
244
+ /**
245
+ * Retrieves min deposit rates for all spot products from the engine
246
+ */
247
+ async getMinDepositRates(): Promise<GetEngineMinDepositRatesResponse> {
248
+ const baseResponse = await this.query('min_deposit_rates', {});
249
+
250
+ return {
251
+ minDepositRates: mapValues(baseResponse.min_deposit_rates, (m) => {
252
+ return {
253
+ productId: m.product_id,
254
+ minDepositRate: removeDecimals(m.min_deposit_rate_x18),
255
+ };
256
+ }),
257
+ };
258
+ }
259
+
260
+ /**
261
+ * Retrieves an order from the offchain engine
262
+ *
263
+ * @param params
264
+ */
265
+ async getOrder(
266
+ params: GetEngineOrderParams,
267
+ ): Promise<GetEngineOrderResponse> {
268
+ const baseResponse = await this.query('order', {
269
+ digest: params.digest,
270
+ product_id: params.productId,
271
+ });
272
+
273
+ return mapEngineServerOrder(baseResponse);
274
+ }
275
+
276
+ /**
277
+ * Signs and validates with the engine that the order is valid to be submitted (i.e. does not violate health reqs)
278
+ *
279
+ * @param params
280
+ */
281
+ async validateOrderParams(
282
+ params: ValidateEngineOrderParams,
283
+ ): Promise<ValidateEngineOrderResponse> {
284
+ const signedOrder = {
285
+ order: params.order,
286
+ signature: await this.sign(
287
+ 'place_order',
288
+ params.orderbookAddr,
289
+ params.chainId,
290
+ params.order,
291
+ ),
292
+ };
293
+ return this.validateSignedOrderParams({
294
+ signedOrder,
295
+ productId: params.productId,
296
+ });
297
+ }
298
+
299
+ /**
300
+ * Validates an existing signed order with the engine as a pre-check for health
301
+ *
302
+ * @param params
303
+ */
304
+ async validateSignedOrderParams(
305
+ params: ValidateSignedEngineOrderParams,
306
+ ): Promise<ValidateEngineOrderResponse> {
307
+ const baseResponse = await this.query('validate_order', {
308
+ product_id: params.productId,
309
+ order: encodeSignedOrder(params.signedOrder),
310
+ });
311
+
312
+ return {
313
+ productId: baseResponse.product_id,
314
+ valid: baseResponse.valid,
315
+ };
316
+ }
317
+
318
+ /**
319
+ * Get all subaccount orders from the engine, per product ID
320
+ * @param params
321
+ */
322
+ async getSubaccountOrders(
323
+ params: GetEngineSubaccountOrdersParams,
324
+ ): Promise<GetEngineSubaccountOrdersResponse> {
325
+ const baseResponse = await this.query('subaccount_orders', {
326
+ sender: subaccountToHex({
327
+ subaccountOwner: params.subaccountOwner,
328
+ subaccountName: params.subaccountName,
329
+ }),
330
+ product_id: params.productId,
331
+ });
332
+
333
+ return {
334
+ orders: baseResponse.orders.map(mapEngineServerOrder),
335
+ productId: params.productId,
336
+ };
337
+ }
338
+
339
+ /**
340
+ * Get all subaccount orders from the engine, for multiple products
341
+ * @param params
342
+ */
343
+ async getSubaccountMultiProductOrders(
344
+ params: GetEngineSubaccountProductOrdersParams,
345
+ ): Promise<GetEngineSubaccountProductOrdersResponse> {
346
+ const baseResponse = await this.query('orders', {
347
+ sender: subaccountToHex({
348
+ subaccountOwner: params.subaccountOwner,
349
+ subaccountName: params.subaccountName,
350
+ }),
351
+ product_ids: params.productIds,
352
+ });
353
+
354
+ return {
355
+ productOrders: baseResponse.product_orders.map((orders) => {
356
+ return {
357
+ orders: orders.orders.map(mapEngineServerOrder),
358
+ productId: orders.product_id,
359
+ };
360
+ }),
361
+ };
362
+ }
363
+
364
+ /**
365
+ * Gets maker & taker fee rates for order fees
366
+ * @param params
367
+ */
368
+ async getSubaccountFeeRates(
369
+ params: GetEngineSubaccountFeeRatesParams,
370
+ ): Promise<GetEngineSubaccountFeeRatesResponse> {
371
+ const baseResponse = await this.query('fee_rates', {
372
+ sender: subaccountToHex({
373
+ subaccountOwner: params.subaccountOwner,
374
+ subaccountName: params.subaccountName,
375
+ }),
376
+ });
377
+
378
+ return {
379
+ healthCheckSequencerFee: toBigDecimal(
380
+ baseResponse.health_check_sequencer_fee,
381
+ ),
382
+ liquidationSequencerFee: toBigDecimal(
383
+ baseResponse.liquidation_sequencer_fee,
384
+ ),
385
+ takerSequencerFee: toBigDecimal(baseResponse.taker_sequencer_fee),
386
+ orders: baseResponse.taker_fee_rates_x18.reduce(
387
+ (acc, takerRateX18, currIndex) => {
388
+ acc[currIndex] = {
389
+ taker: removeDecimals(takerRateX18),
390
+ maker: removeDecimals(baseResponse.maker_fee_rates_x18[currIndex]),
391
+ };
392
+ return acc;
393
+ },
394
+ {} as Record<number, SubaccountOrderFeeRates>,
395
+ ),
396
+ withdrawal: baseResponse.withdraw_sequencer_fees.reduce(
397
+ (acc, productFee, currIndex) => {
398
+ acc[currIndex] = toBigDecimal(productFee);
399
+ return acc;
400
+ },
401
+ {} as Record<number, BigDecimal>,
402
+ ),
403
+ };
404
+ }
405
+
406
+ /**
407
+ * Gets "price ticks" for a given market, useful for constructing liquidity levels at each price
408
+ * @param params
409
+ */
410
+ async getMarketLiquidity(
411
+ params: GetEngineMarketLiquidityParams,
412
+ ): Promise<GetEngineMarketLiquidityResponse> {
413
+ const baseResponse = await this.query('market_liquidity', {
414
+ product_id: params.productId,
415
+ depth: params.depth,
416
+ });
417
+ return {
418
+ asks: baseResponse.asks.map(mapEngineServerTickLiquidity),
419
+ bids: baseResponse.bids.map(mapEngineServerTickLiquidity),
420
+ };
421
+ }
422
+
423
+ /**
424
+ * Retrieves the latest price for a given market
425
+ * @param params
426
+ */
427
+ async getMarketPrice(
428
+ params: GetEngineMarketPriceParams,
429
+ ): Promise<GetEngineMarketPriceResponse> {
430
+ const baseResponse = await this.query('market_price', {
431
+ product_id: params.productId,
432
+ });
433
+ return mapEngineMarketPrice(baseResponse);
434
+ }
435
+
436
+ /**
437
+ * Retrieves the latest prices for provided markets
438
+ * @param params
439
+ */
440
+ async getMarketPrices(
441
+ params: GetEngineMarketPricesParams,
442
+ ): Promise<GetEngineMarketPricesResponse> {
443
+ const baseResponse = await this.query('market_prices', {
444
+ product_ids: params.productIds,
445
+ });
446
+ return {
447
+ marketPrices: baseResponse.market_prices.map(mapEngineMarketPrice),
448
+ };
449
+ }
450
+
451
+ /**
452
+ * Retrieves the estimated max order size for a product
453
+ * @param params
454
+ */
455
+ async getMaxOrderSize(
456
+ params: GetEngineMaxOrderSizeParams,
457
+ ): Promise<GetEngineMaxOrderSizeResponse> {
458
+ const baseResponse = await this.query('max_order_size', {
459
+ direction: params.side,
460
+ price_x18: toIntegerString(addDecimals(params.price)),
461
+ product_id: params.productId,
462
+ sender: subaccountToHex({
463
+ subaccountOwner: params.subaccountOwner,
464
+ subaccountName: params.subaccountName,
465
+ }),
466
+ spot_leverage:
467
+ params.spotLeverage != null ? String(params.spotLeverage) : null,
468
+ reduce_only: params.reduceOnly != null ? String(params.reduceOnly) : null,
469
+ });
470
+
471
+ return toBigDecimal(baseResponse.max_order_size);
472
+ }
473
+
474
+ /**
475
+ * Retrieves the estimated max withdrawal size for a product
476
+ * @param params
477
+ */
478
+ async getMaxWithdrawable(
479
+ params: GetEngineMaxWithdrawableParams,
480
+ ): Promise<GetEngineMaxWithdrawableResponse> {
481
+ const baseResponse = await this.query('max_withdrawable', {
482
+ product_id: params.productId,
483
+ sender: subaccountToHex({
484
+ subaccountOwner: params.subaccountOwner,
485
+ subaccountName: params.subaccountName,
486
+ }),
487
+ spot_leverage:
488
+ params.spotLeverage != null ? String(params.spotLeverage) : null,
489
+ });
490
+
491
+ return toBigDecimal(baseResponse.max_withdrawable);
492
+ }
493
+
494
+ /**
495
+ * Retrieves the estimated max quote amount for minting VLP.
496
+ *
497
+ * @param params
498
+ */
499
+ async getMaxMintVlpAmount(
500
+ params: GetEngineMaxMintVlpAmountParams,
501
+ ): Promise<GetEngineMaxMintVlpAmountResponse> {
502
+ const baseResponse = await this.query('max_vlp_mintable', {
503
+ sender: subaccountToHex({
504
+ subaccountOwner: params.subaccountOwner,
505
+ subaccountName: params.subaccountName,
506
+ }),
507
+ spot_leverage:
508
+ params.spotLeverage != null ? String(params.spotLeverage) : null,
509
+ });
510
+
511
+ return toBigDecimal(baseResponse.max_quote_amount);
512
+ }
513
+
514
+ /**
515
+ * Gets the currently linked signer for the subaccount
516
+ * @param params
517
+ * @returns
518
+ */
519
+ public async getLinkedSigner(
520
+ params: GetEngineLinkedSignerParams,
521
+ ): Promise<GetEngineLinkedSignerResponse> {
522
+ const baseResponse = await this.query('linked_signer', {
523
+ subaccount: subaccountToHex({
524
+ subaccountOwner: params.subaccountOwner,
525
+ subaccountName: params.subaccountName,
526
+ }),
527
+ });
528
+
529
+ return {
530
+ signer: baseResponse.linked_signer,
531
+ };
532
+ }
533
+
534
+ /**
535
+ * Gets the insurance funds in USDC.
536
+ * @returns
537
+ */
538
+ public async getInsurance(): Promise<GetEngineInsuranceResponse> {
539
+ const baseResponse = await this.query('insurance', {});
540
+
541
+ return toBigDecimal(baseResponse.insurance);
542
+ }
543
+
544
+ /**
545
+ * Gets the orderbook contract address for a given product
546
+ * @param productId
547
+ * @returns
548
+ */
549
+ public async getOrderbookAddress(productId: number): Promise<string> {
550
+ const contracts = await this.getContracts();
551
+ return contracts.orderbookAddrs[productId];
552
+ }
553
+ }