@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
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@nadohq/engine-client",
3
+ "version": "0.1.0-alpha.1",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "description": "> TODO: description",
7
+ "author": "Frank Jia <frank@inkfnd.com>",
8
+ "homepage": "",
9
+ "license": "ISC",
10
+ "source": "./src/index.ts",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "repository": "https://github.com/nadohq/nado-typescript-sdk",
15
+ "scripts": {
16
+ "clean": "rm -rf dist && rm -f tsconfig.tsbuildinfo",
17
+ "build": "tsup",
18
+ "dev": "tsc -w",
19
+ "lint": "eslint --cache './**/*.{ts,tsx}'",
20
+ "lint:fix": "eslint --cache --fix './**/*.{ts,tsx}'",
21
+ "typecheck": "tsc --noEmit"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "src"
26
+ ],
27
+ "exports": {
28
+ ".": {
29
+ "import": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ },
33
+ "require": {
34
+ "types": "./dist/index.d.cts",
35
+ "default": "./dist/index.cjs"
36
+ }
37
+ }
38
+ },
39
+ "dependencies": {
40
+ "@nadohq/contracts": "^0.1.0-alpha.1",
41
+ "@nadohq/utils": "^0.1.0-alpha.1",
42
+ "axios": "*",
43
+ "ts-mixer": "*"
44
+ },
45
+ "peerDependencies": {
46
+ "viem": "*"
47
+ },
48
+ "devDependencies": {
49
+ "viem": "*"
50
+ },
51
+ "gitHead": "80100d38c43806d1bb57c9139d9577329467d5db"
52
+ }
@@ -0,0 +1,223 @@
1
+ import {
2
+ getSignedTransactionRequest,
3
+ SignableRequestType,
4
+ SignableRequestTypeToParams,
5
+ WalletClientWithAccount,
6
+ } from '@nadohq/contracts';
7
+ import { WalletNotProvidedError } from '@nadohq/utils';
8
+ import axios, { AxiosInstance, AxiosResponse } from 'axios';
9
+ import {
10
+ EngineServerExecuteRequestByType,
11
+ EngineServerExecuteRequestType,
12
+ EngineServerExecuteResult,
13
+ EngineServerExecuteSuccessResult,
14
+ EngineServerQueryRequest,
15
+ EngineServerQueryRequestByType,
16
+ EngineServerQueryRequestType,
17
+ EngineServerQueryResponse,
18
+ EngineServerQueryResponseByType,
19
+ EngineServerQuerySuccessResponse,
20
+ GetEngineNoncesParams,
21
+ GetEngineNoncesResponse,
22
+ } from './types';
23
+ import { EngineServerFailureError } from './types/EngineServerFailureError';
24
+
25
+ export interface EngineClientOpts {
26
+ // Server URL
27
+ url: string;
28
+ // Wallet client for EIP712 signing
29
+ walletClient?: WalletClientWithAccount;
30
+ // Linked signer registered through the engine, if provided, execute requests will use this signer
31
+ linkedSignerWalletClient?: WalletClientWithAccount;
32
+ }
33
+
34
+ // Only 1 key can be defined per execute request
35
+ type EngineExecuteRequestBody = Partial<EngineServerExecuteRequestByType>;
36
+
37
+ type EngineQueryRequestResponse<
38
+ T extends EngineServerQueryRequestType = EngineServerQueryRequestType,
39
+ > = EngineServerQueryResponse<T>;
40
+
41
+ /**
42
+ * Base client for all engine requests
43
+ */
44
+ export class EngineBaseClient {
45
+ readonly opts: EngineClientOpts;
46
+ readonly axiosInstance: AxiosInstance;
47
+
48
+ constructor(opts: EngineClientOpts) {
49
+ this.opts = opts;
50
+ this.axiosInstance = axios.create({
51
+ withCredentials: true,
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Sets the linked signer for execute requests
57
+ *
58
+ * @param linkedSignerWalletClient The linkedSigner to use for all signatures. Set to null to revert to the chain signer
59
+ */
60
+ public setLinkedSigner(
61
+ linkedSignerWalletClient: WalletClientWithAccount | null,
62
+ ) {
63
+ this.opts.linkedSignerWalletClient = linkedSignerWalletClient ?? undefined;
64
+ }
65
+
66
+ public async getTxNonce(address?: string): Promise<string> {
67
+ const addr = address ?? this.opts.walletClient?.account.address;
68
+
69
+ if (!addr) {
70
+ throw new WalletNotProvidedError();
71
+ }
72
+
73
+ return (
74
+ await this.getNonces({
75
+ address: addr,
76
+ })
77
+ ).txNonce;
78
+ }
79
+
80
+ public async getNonces(
81
+ params: GetEngineNoncesParams,
82
+ ): Promise<GetEngineNoncesResponse> {
83
+ const baseResp = await this.query('nonces', params);
84
+
85
+ return {
86
+ orderNonce: baseResp.order_nonce,
87
+ txNonce: baseResp.tx_nonce,
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Queries the engine, all query params are stringified into the query string
93
+ *
94
+ * @param requestType
95
+ * @param params
96
+ * @public
97
+ */
98
+ public async query<TRequestType extends EngineServerQueryRequestType>(
99
+ requestType: TRequestType,
100
+ params: EngineServerQueryRequestByType[TRequestType],
101
+ ): Promise<EngineServerQueryResponseByType[TRequestType]> {
102
+ const request = this.getQueryRequest(requestType, params);
103
+ const response = await this.axiosInstance.post<EngineQueryRequestResponse>(
104
+ `${this.opts.url}/query`,
105
+ request,
106
+ );
107
+
108
+ this.checkResponseStatus(response);
109
+ this.checkServerStatus(response);
110
+
111
+ // checkServerStatus throws on failure responses so the cast to the success response is acceptable here
112
+ const successResponse = response as AxiosResponse<
113
+ EngineServerQuerySuccessResponse<TRequestType>
114
+ >;
115
+
116
+ return successResponse.data.data;
117
+ }
118
+
119
+ /**
120
+ * A simple, typechecked fn for constructing a query request in the format expected by the server.
121
+ *
122
+ * @param requestType
123
+ * @param params
124
+ */
125
+ public getQueryRequest<TRequestType extends EngineServerQueryRequestType>(
126
+ requestType: TRequestType,
127
+ params: EngineServerQueryRequestByType[TRequestType],
128
+ ): EngineServerQueryRequest<TRequestType> {
129
+ return {
130
+ type: requestType,
131
+ ...params,
132
+ };
133
+ }
134
+
135
+ /**
136
+ * POSTs an execute message to the engine and returns the successful response. Throws the failure response wrapped
137
+ * in an EngineServerFailureError on failure.
138
+ *
139
+ * @param requestType
140
+ * @param params
141
+ * @public
142
+ */
143
+ public async execute<TRequestType extends EngineServerExecuteRequestType>(
144
+ requestType: TRequestType,
145
+ params: EngineServerExecuteRequestByType[TRequestType],
146
+ ): Promise<EngineServerExecuteSuccessResult<TRequestType>> {
147
+ const reqBody = this.getExecuteRequest(requestType, params);
148
+ const response = await this.axiosInstance.post<
149
+ EngineServerExecuteResult<TRequestType>
150
+ >(`${this.opts.url}/execute`, reqBody);
151
+
152
+ this.checkResponseStatus(response);
153
+ this.checkServerStatus(response);
154
+
155
+ // checkServerStatus catches the failure result and throws the error, so the cast to the success response is acceptable here
156
+ return response.data as EngineServerExecuteSuccessResult<TRequestType>;
157
+ }
158
+
159
+ /**
160
+ * A simple, typechecked fn for constructing an execute request in the format expected by the server.
161
+ *
162
+ * @param requestType
163
+ * @param params
164
+ */
165
+ public getExecuteRequest<TRequestType extends EngineServerExecuteRequestType>(
166
+ requestType: TRequestType,
167
+ params: EngineServerExecuteRequestByType[TRequestType],
168
+ ): EngineExecuteRequestBody {
169
+ return {
170
+ [requestType]: params,
171
+ };
172
+ }
173
+
174
+ /**
175
+ * Signs a given request with the signer provided to the engine
176
+ *
177
+ * @param requestType
178
+ * @param verifyingContract
179
+ * @param chainId
180
+ * @param params
181
+ * @public
182
+ */
183
+ public async sign<T extends SignableRequestType>(
184
+ requestType: T,
185
+ verifyingContract: string,
186
+ chainId: number,
187
+ params: SignableRequestTypeToParams[T],
188
+ ) {
189
+ // Use the linked signer if provided, otherwise use the default signer provided to the engine
190
+ const walletClient =
191
+ this.opts.linkedSignerWalletClient ?? this.opts.walletClient;
192
+
193
+ if (!walletClient) {
194
+ throw new WalletNotProvidedError();
195
+ }
196
+
197
+ return getSignedTransactionRequest({
198
+ chainId,
199
+ requestParams: params,
200
+ requestType,
201
+ walletClient,
202
+ verifyingContract,
203
+ });
204
+ }
205
+
206
+ private checkResponseStatus(response: AxiosResponse) {
207
+ if (response.status !== 200 || !response.data) {
208
+ throw Error(
209
+ `Unexpected response from server: ${response.status} ${response.statusText}`,
210
+ );
211
+ }
212
+ }
213
+
214
+ private checkServerStatus(
215
+ response: AxiosResponse<
216
+ EngineServerExecuteResult | EngineQueryRequestResponse
217
+ >,
218
+ ) {
219
+ if (response.data.status !== 'success') {
220
+ throw new EngineServerFailureError(response.data);
221
+ }
222
+ }
223
+ }
@@ -0,0 +1,13 @@
1
+ import { Mixin } from 'ts-mixer';
2
+ import { EngineExecuteClient } from './EngineExecuteClient';
3
+ import { EngineQueryClient } from './EngineQueryClient';
4
+ import { EngineWebClient } from './EngineWebClient';
5
+
6
+ /**
7
+ * Combined Engine client providing query, execution, and WebSocket functionality for off-chain matching engine communication
8
+ */
9
+ export class EngineClient extends Mixin(
10
+ EngineQueryClient,
11
+ EngineExecuteClient,
12
+ EngineWebClient,
13
+ ) {}
@@ -0,0 +1,381 @@
1
+ import {
2
+ EIP712IsolatedOrderParams,
3
+ EIP712OrderParams,
4
+ getNadoEIP712Values,
5
+ getOrderNonce,
6
+ SignableRequestType,
7
+ SignableRequestTypeToParams,
8
+ } from '@nadohq/contracts';
9
+ import { EngineBaseClient } from './EngineBaseClient';
10
+ import {
11
+ EngineExecuteRequestParamsByType,
12
+ EngineServerExecutePlaceIsolatedOrderPayload,
13
+ EngineServerExecutePlaceOrderPayload,
14
+ EngineServerExecuteRequestByType,
15
+ SignatureParams,
16
+ WithBaseEngineExecuteParams,
17
+ WithSignature,
18
+ } from './types';
19
+
20
+ /**
21
+ * Builds execute payloads as expected by the server.
22
+ * @param nonce A nonce is computed when one is not provided.
23
+ * @param signature A signature is computed when one is not provided.
24
+ */
25
+ export class EngineExecuteBuilder {
26
+ readonly engineClient: EngineBaseClient;
27
+
28
+ constructor(engineClient: EngineBaseClient) {
29
+ this.engineClient = engineClient;
30
+ }
31
+
32
+ /**
33
+ * Builds server payload for the `liquidate_subaccount` execute action.
34
+ * @param clientParams Client LiquidateSubaccount params.
35
+ * @returns `liquidate_subaccount` payload
36
+ */
37
+ async buildLiquidateSubaccountPayload(
38
+ clientParams: EngineExecuteRequestParamsByType['liquidate_subaccount'],
39
+ ): Promise<EngineServerExecuteRequestByType['liquidate_subaccount']> {
40
+ const nonce = await this.getTxNonceIfNeeded(clientParams);
41
+ const paramsWithNonce = { ...clientParams, nonce };
42
+
43
+ const tx = getNadoEIP712Values('liquidate_subaccount', paramsWithNonce);
44
+ const signature = await this.getSignatureIfNeeded(
45
+ 'liquidate_subaccount',
46
+ paramsWithNonce,
47
+ );
48
+
49
+ return {
50
+ signature,
51
+ tx,
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Builds server payload for the `withdraw_collateral` execute action.
57
+ * @param clientParams Client WithdrawCollateral params.
58
+ * @returns `liquidate_subaccount` payload
59
+ */
60
+ async buildWithdrawCollateralPayload(
61
+ clientParams: EngineExecuteRequestParamsByType['withdraw_collateral'],
62
+ ): Promise<EngineServerExecuteRequestByType['withdraw_collateral']> {
63
+ const nonce = await this.getTxNonceIfNeeded(clientParams);
64
+ const paramsWithNonce = { ...clientParams, nonce };
65
+
66
+ const signature = await this.getSignatureIfNeeded(
67
+ 'withdraw_collateral',
68
+ paramsWithNonce,
69
+ );
70
+
71
+ const tx = getNadoEIP712Values('withdraw_collateral', paramsWithNonce);
72
+ return {
73
+ signature,
74
+ tx,
75
+ spot_leverage: clientParams.spotLeverage ?? null,
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Builds server payload for the `place_order` execute action.
81
+ *
82
+ * @param clientParams Client PlaceOrder params.
83
+ * @returns `place_order` payload
84
+ */
85
+ async buildPlaceOrderPayload(
86
+ clientParams: EngineExecuteRequestParamsByType['place_order'],
87
+ ): Promise<EngineServerExecutePlaceOrderPayload> {
88
+ const nonce = this.getOrderNonceIfNeeded(clientParams);
89
+ const orderWithNonce = { ...clientParams.order, nonce };
90
+
91
+ const signature = await this.getSignatureIfNeeded('place_order', {
92
+ // Gets expected type
93
+ ...clientParams,
94
+ ...orderWithNonce,
95
+ });
96
+
97
+ return this.buildPlaceOrderPayloadSync({
98
+ ...clientParams,
99
+ order: orderWithNonce,
100
+ signature,
101
+ });
102
+ }
103
+
104
+ /**
105
+ * Synchronously builds server payload for the `place_order` execute action.
106
+ *
107
+ * @param clientParams Client PlaceOrder params.
108
+ * @returns `place_order` payload
109
+ */
110
+ buildPlaceOrderPayloadSync(
111
+ clientParams: WithSignature<
112
+ EngineExecuteRequestParamsByType['place_order'] & {
113
+ order: EIP712OrderParams;
114
+ }
115
+ >,
116
+ ): EngineServerExecutePlaceOrderPayload {
117
+ const orderEIP712Values = getNadoEIP712Values(
118
+ 'place_order',
119
+ clientParams.order,
120
+ );
121
+
122
+ return {
123
+ payload: {
124
+ id: clientParams.id ?? null,
125
+ product_id: clientParams.productId,
126
+ order: orderEIP712Values,
127
+ signature: clientParams.signature,
128
+ spot_leverage: clientParams.spotLeverage ?? null,
129
+ },
130
+ orderParams: clientParams.order,
131
+ };
132
+ }
133
+
134
+ /**
135
+ * Builds server payload for the `place_isolated_order` execute action.
136
+ *
137
+ * @param clientParams Client PlaceIsolatedOrder params.
138
+ * @returns `place_isolated_order` payload
139
+ */
140
+ async buildIsolatedPlaceOrderPayload(
141
+ clientParams: EngineExecuteRequestParamsByType['place_isolated_order'],
142
+ ): Promise<EngineServerExecutePlaceIsolatedOrderPayload> {
143
+ const nonce = this.getOrderNonceIfNeeded(clientParams);
144
+ const orderWithNonce = { ...clientParams.order, nonce };
145
+
146
+ const signature = await this.getSignatureIfNeeded('place_isolated_order', {
147
+ // Gets expected type
148
+ ...clientParams,
149
+ ...orderWithNonce,
150
+ });
151
+
152
+ return this.buildPlaceIsolatedOrderPayloadSync({
153
+ ...clientParams,
154
+ order: orderWithNonce,
155
+ signature,
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Synchronously builds server payload for the `place_isolated_order` execute action.
161
+ *
162
+ * @param clientParams Client PlaceIsolatedOrder params.
163
+ * @returns `place_isolated_order` payload
164
+ */
165
+ buildPlaceIsolatedOrderPayloadSync(
166
+ clientParams: WithSignature<
167
+ EngineExecuteRequestParamsByType['place_isolated_order'] & {
168
+ order: EIP712IsolatedOrderParams;
169
+ }
170
+ >,
171
+ ): EngineServerExecutePlaceIsolatedOrderPayload {
172
+ const isolatedOrderEIP712Values = getNadoEIP712Values(
173
+ 'place_isolated_order',
174
+ clientParams.order,
175
+ );
176
+
177
+ return {
178
+ payload: {
179
+ id: clientParams.id ?? null,
180
+ product_id: clientParams.productId,
181
+ isolated_order: isolatedOrderEIP712Values,
182
+ signature: clientParams.signature,
183
+ borrow_margin: clientParams.borrowMargin ?? null,
184
+ },
185
+ orderParams: clientParams.order,
186
+ };
187
+ }
188
+
189
+ /**
190
+ * Builds server payload for the `cancel_orders` execute action. As such, requires a signature to be given
191
+ *
192
+ * @param clientParams Client CancelOrders params.
193
+ * @returns `cancel_orders` payload
194
+ */
195
+ async buildCancelOrdersPayload(
196
+ clientParams: EngineExecuteRequestParamsByType['cancel_orders'],
197
+ ): Promise<EngineServerExecuteRequestByType['cancel_orders']> {
198
+ const nonce = this.getOrderNonceIfNeeded(clientParams);
199
+ const paramsWithNonce = { ...clientParams, nonce };
200
+ const signature = await this.getSignatureIfNeeded(
201
+ 'cancel_orders',
202
+ paramsWithNonce,
203
+ );
204
+
205
+ return this.buildCancelOrdersPayloadSync({
206
+ ...paramsWithNonce,
207
+ signature,
208
+ });
209
+ }
210
+
211
+ /**
212
+ * Synchronously builds server payload for the `cancel_orders` execute action.
213
+ *
214
+ * @param clientParams Client CancelOrders params.
215
+ * @returns `cancel_orders` payload
216
+ */
217
+ buildCancelOrdersPayloadSync(
218
+ clientParams: WithSignature<
219
+ EngineExecuteRequestParamsByType['cancel_orders'] & { nonce: string }
220
+ >,
221
+ ): EngineServerExecuteRequestByType['cancel_orders'] {
222
+ const tx = getNadoEIP712Values('cancel_orders', clientParams);
223
+
224
+ return {
225
+ tx,
226
+ signature: clientParams.signature,
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Builds server payload for the `cancel_product_orders` execute action.
232
+ * @param clientParams Client CancelProductOrders params.
233
+ * @returns `cancel_product_orders` payload
234
+ */
235
+ async buildCancelProductOrdersPayload(
236
+ clientParams: EngineExecuteRequestParamsByType['cancel_product_orders'],
237
+ ): Promise<EngineServerExecuteRequestByType['cancel_product_orders']> {
238
+ const nonce = this.getOrderNonceIfNeeded(clientParams);
239
+ const paramsWithNonce = { ...clientParams, nonce };
240
+
241
+ const tx = getNadoEIP712Values('cancel_product_orders', paramsWithNonce);
242
+ const signature = await this.getSignatureIfNeeded(
243
+ 'cancel_product_orders',
244
+ paramsWithNonce,
245
+ );
246
+
247
+ return {
248
+ tx,
249
+ signature,
250
+ };
251
+ }
252
+
253
+ /**
254
+ * Builds server payload for the `link_signer` execute action.
255
+ *
256
+ * @param clientParams Client LinkSigner params.
257
+ * @returns `link_signer` payload
258
+ */
259
+ async buildLinkSignerPayload(
260
+ clientParams: EngineExecuteRequestParamsByType['link_signer'],
261
+ ): Promise<EngineServerExecuteRequestByType['link_signer']> {
262
+ const nonce = await this.getTxNonceIfNeeded(clientParams);
263
+ const paramsWithNonce = { ...clientParams, nonce };
264
+
265
+ const tx = getNadoEIP712Values('link_signer', paramsWithNonce);
266
+ const signature = await this.getSignatureIfNeeded(
267
+ 'link_signer',
268
+ paramsWithNonce,
269
+ );
270
+
271
+ return {
272
+ tx,
273
+ signature,
274
+ };
275
+ }
276
+
277
+ /**
278
+ * Builds server payload for the `transfer_quote` execute action.
279
+ *
280
+ * @param clientParams Client TransferQuote params.
281
+ * @returns `transfer_quote` payload
282
+ */
283
+ async buildTransferQuotePayload(
284
+ clientParams: EngineExecuteRequestParamsByType['transfer_quote'],
285
+ ): Promise<EngineServerExecuteRequestByType['transfer_quote']> {
286
+ const nonce = await this.getTxNonceIfNeeded(clientParams);
287
+ const paramsWithNonce = { ...clientParams, nonce };
288
+
289
+ const tx = getNadoEIP712Values('transfer_quote', paramsWithNonce);
290
+ const signature = await this.getSignatureIfNeeded(
291
+ 'transfer_quote',
292
+ paramsWithNonce,
293
+ );
294
+
295
+ return {
296
+ tx,
297
+ signature,
298
+ };
299
+ }
300
+
301
+ /**
302
+ * Builds server payload for the `mint_vlp` execute action.
303
+ * @param clientParams Client MintVlp params.
304
+ * @returns `mint_vlp` payload
305
+ */
306
+ async buildMintVlpPayload(
307
+ clientParams: EngineExecuteRequestParamsByType['mint_vlp'],
308
+ ): Promise<EngineServerExecuteRequestByType['mint_vlp']> {
309
+ const nonce = await this.getTxNonceIfNeeded(clientParams);
310
+ const paramsWithNonce = { ...clientParams, nonce };
311
+
312
+ const tx = getNadoEIP712Values('mint_vlp', paramsWithNonce);
313
+ const signature = await this.getSignatureIfNeeded(
314
+ 'mint_vlp',
315
+ paramsWithNonce,
316
+ );
317
+
318
+ return {
319
+ signature,
320
+ tx,
321
+ spot_leverage: clientParams.spotLeverage ?? null,
322
+ };
323
+ }
324
+
325
+ /**
326
+ * Builds server payload for the `burn_vlp` execute action.
327
+ * @param clientParams Client BurnVlp params.
328
+ * @returns `burn_vlp` payload
329
+ */
330
+ async buildBurnVlpPayload(
331
+ clientParams: EngineExecuteRequestParamsByType['burn_vlp'],
332
+ ): Promise<EngineServerExecuteRequestByType['burn_vlp']> {
333
+ const nonce = await this.getTxNonceIfNeeded(clientParams);
334
+ const paramsWithNonce = { ...clientParams, nonce };
335
+
336
+ const tx = getNadoEIP712Values('burn_vlp', paramsWithNonce);
337
+ const signature = await this.getSignatureIfNeeded(
338
+ 'burn_vlp',
339
+ paramsWithNonce,
340
+ );
341
+
342
+ return {
343
+ signature,
344
+ tx,
345
+ };
346
+ }
347
+
348
+ protected async getSignatureIfNeeded<T extends SignableRequestType>(
349
+ requestType: T,
350
+ paramsWithNonce: SignatureParams & SignableRequestTypeToParams[T],
351
+ ) {
352
+ if ('signature' in paramsWithNonce) {
353
+ return paramsWithNonce.signature;
354
+ }
355
+
356
+ return await this.engineClient.sign(
357
+ requestType,
358
+ paramsWithNonce.verifyingAddr,
359
+ paramsWithNonce.chainId,
360
+ paramsWithNonce,
361
+ );
362
+ }
363
+
364
+ protected async getTxNonceIfNeeded(
365
+ params: WithBaseEngineExecuteParams<{ subaccountOwner: string }>,
366
+ ) {
367
+ if (params.nonce) {
368
+ return params.nonce;
369
+ }
370
+ return await this.engineClient.getTxNonce(params.subaccountOwner);
371
+ }
372
+
373
+ protected getOrderNonceIfNeeded(
374
+ params: WithBaseEngineExecuteParams<unknown>,
375
+ ) {
376
+ if (params.nonce) {
377
+ return params.nonce;
378
+ }
379
+ return getOrderNonce();
380
+ }
381
+ }