@nadohq/trigger-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.
- package/README.md +2 -0
- package/dist/TriggerClient.cjs +217 -0
- package/dist/TriggerClient.cjs.map +1 -0
- package/dist/TriggerClient.d.cts +45 -0
- package/dist/TriggerClient.d.ts +45 -0
- package/dist/TriggerClient.js +188 -0
- package/dist/TriggerClient.js.map +1 -0
- package/dist/dataMappers.cjs +134 -0
- package/dist/dataMappers.cjs.map +1 -0
- package/dist/dataMappers.d.cts +13 -0
- package/dist/dataMappers.d.ts +13 -0
- package/dist/dataMappers.js +111 -0
- package/dist/dataMappers.js.map +1 -0
- package/dist/endpoints.cjs +35 -0
- package/dist/endpoints.cjs.map +1 -0
- package/dist/endpoints.d.cts +5 -0
- package/dist/endpoints.d.ts +5 -0
- package/dist/endpoints.js +10 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/index.cjs +29 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/types/TriggerServerFailureError.cjs +36 -0
- package/dist/types/TriggerServerFailureError.cjs.map +1 -0
- package/dist/types/TriggerServerFailureError.d.cts +11 -0
- package/dist/types/TriggerServerFailureError.d.ts +11 -0
- package/dist/types/TriggerServerFailureError.js +11 -0
- package/dist/types/TriggerServerFailureError.js.map +1 -0
- package/dist/types/clientTypes.cjs +19 -0
- package/dist/types/clientTypes.cjs.map +1 -0
- package/dist/types/clientTypes.d.cts +75 -0
- package/dist/types/clientTypes.d.ts +75 -0
- package/dist/types/clientTypes.js +1 -0
- package/dist/types/clientTypes.js.map +1 -0
- package/dist/types/index.cjs +31 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +7 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/serverExecuteTypes.cjs +19 -0
- package/dist/types/serverExecuteTypes.cjs.map +1 -0
- package/dist/types/serverExecuteTypes.d.cts +37 -0
- package/dist/types/serverExecuteTypes.d.ts +37 -0
- package/dist/types/serverExecuteTypes.js +1 -0
- package/dist/types/serverExecuteTypes.js.map +1 -0
- package/dist/types/serverQueryTypes.cjs +19 -0
- package/dist/types/serverQueryTypes.cjs.map +1 -0
- package/dist/types/serverQueryTypes.d.cts +54 -0
- package/dist/types/serverQueryTypes.d.ts +54 -0
- package/dist/types/serverQueryTypes.js +1 -0
- package/dist/types/serverQueryTypes.js.map +1 -0
- package/package.json +53 -0
- package/src/TriggerClient.ts +284 -0
- package/src/dataMappers.ts +124 -0
- package/src/endpoints.ts +7 -0
- package/src/index.ts +3 -0
- package/src/types/TriggerServerFailureError.ts +12 -0
- package/src/types/clientTypes.ts +109 -0
- package/src/types/index.ts +4 -0
- package/src/types/serverExecuteTypes.ts +63 -0
- package/src/types/serverQueryTypes.ts +83 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EIP712CancelOrdersParams,
|
|
3
|
+
EIP712CancelProductOrdersParams,
|
|
4
|
+
EIP712ListTriggerOrdersParams,
|
|
5
|
+
EIP712OrderParams,
|
|
6
|
+
getDefaultRecvTime,
|
|
7
|
+
getNadoEIP712Values,
|
|
8
|
+
getOrderNonce,
|
|
9
|
+
getSignedTransactionRequest,
|
|
10
|
+
getTriggerOrderNonce,
|
|
11
|
+
SignableRequestType,
|
|
12
|
+
SignableRequestTypeToParams,
|
|
13
|
+
WalletClientWithAccount,
|
|
14
|
+
} from '@nadohq/contracts';
|
|
15
|
+
import { toIntegerString, WalletNotProvidedError } from '@nadohq/utils';
|
|
16
|
+
import axios, { AxiosInstance, AxiosResponse } from 'axios';
|
|
17
|
+
import { mapServerOrderInfo, mapTriggerCriteria } from './dataMappers';
|
|
18
|
+
import {
|
|
19
|
+
TriggerCancelOrdersParams,
|
|
20
|
+
TriggerCancelProductOrdersParams,
|
|
21
|
+
TriggerListOrdersParams,
|
|
22
|
+
TriggerListOrdersResponse,
|
|
23
|
+
TriggerOrderInfo,
|
|
24
|
+
TriggerPlaceOrderParams,
|
|
25
|
+
TriggerServerExecuteRequestByType,
|
|
26
|
+
TriggerServerExecuteRequestType,
|
|
27
|
+
TriggerServerExecuteResult,
|
|
28
|
+
TriggerServerExecuteSuccessResult,
|
|
29
|
+
TriggerServerQueryRequestByType,
|
|
30
|
+
TriggerServerQueryRequestType,
|
|
31
|
+
TriggerServerQueryResponse,
|
|
32
|
+
TriggerServerQueryResponseByType,
|
|
33
|
+
TriggerServerQuerySuccessResponse,
|
|
34
|
+
} from './types';
|
|
35
|
+
import { TriggerServerFailureError } from './types/TriggerServerFailureError';
|
|
36
|
+
|
|
37
|
+
export interface TriggerClientOpts {
|
|
38
|
+
// Server URL
|
|
39
|
+
url: string;
|
|
40
|
+
// Wallet client for EIP712 signing
|
|
41
|
+
walletClient?: WalletClientWithAccount;
|
|
42
|
+
// Linked signer registered through the engine, if provided, execute requests will use this signer
|
|
43
|
+
linkedSignerWalletClient?: WalletClientWithAccount;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Client for all trigger service requests
|
|
48
|
+
*/
|
|
49
|
+
export class TriggerClient {
|
|
50
|
+
readonly opts: TriggerClientOpts;
|
|
51
|
+
readonly axiosInstance: AxiosInstance;
|
|
52
|
+
|
|
53
|
+
constructor(opts: TriggerClientOpts) {
|
|
54
|
+
this.opts = opts;
|
|
55
|
+
this.axiosInstance = axios.create({ withCredentials: true });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Sets the linked signer for requests
|
|
60
|
+
*
|
|
61
|
+
* @param linkedSignerWalletClient The linkedSigner to use for all signatures. Set to null to revert to the chain signer
|
|
62
|
+
*/
|
|
63
|
+
public setLinkedSigner(
|
|
64
|
+
linkedSignerWalletClient: WalletClientWithAccount | null,
|
|
65
|
+
) {
|
|
66
|
+
this.opts.linkedSignerWalletClient = linkedSignerWalletClient ?? undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
Executes
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
async placeTriggerOrder(params: TriggerPlaceOrderParams) {
|
|
74
|
+
const orderParams: EIP712OrderParams = {
|
|
75
|
+
amount: params.order.amount,
|
|
76
|
+
expiration: params.order.expiration,
|
|
77
|
+
price: params.order.price,
|
|
78
|
+
subaccountName: params.order.subaccountName,
|
|
79
|
+
subaccountOwner: params.order.subaccountOwner,
|
|
80
|
+
nonce: params.nonce ?? getTriggerOrderNonce(),
|
|
81
|
+
};
|
|
82
|
+
const signature = await this.sign(
|
|
83
|
+
'place_order',
|
|
84
|
+
params.verifyingAddr,
|
|
85
|
+
params.chainId,
|
|
86
|
+
orderParams,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const executeParams: TriggerServerExecuteRequestByType['place_order'] = {
|
|
90
|
+
id: params.id ?? null,
|
|
91
|
+
order: getNadoEIP712Values('place_order', orderParams),
|
|
92
|
+
trigger: mapTriggerCriteria(params.triggerCriteria),
|
|
93
|
+
signature,
|
|
94
|
+
product_id: params.productId,
|
|
95
|
+
spot_leverage: params.spotLeverage ?? null,
|
|
96
|
+
digest: params.digest ?? null,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return this.execute('place_order', executeParams);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async cancelTriggerOrders(params: TriggerCancelOrdersParams) {
|
|
103
|
+
const cancelOrdersParams: EIP712CancelOrdersParams = {
|
|
104
|
+
digests: params.digests,
|
|
105
|
+
nonce: params.nonce ?? getOrderNonce(),
|
|
106
|
+
productIds: params.productIds,
|
|
107
|
+
subaccountName: params.subaccountName,
|
|
108
|
+
subaccountOwner: params.subaccountOwner,
|
|
109
|
+
};
|
|
110
|
+
const tx = getNadoEIP712Values('cancel_orders', cancelOrdersParams);
|
|
111
|
+
|
|
112
|
+
const executeParams: TriggerServerExecuteRequestByType['cancel_orders'] = {
|
|
113
|
+
signature: await this.sign(
|
|
114
|
+
'cancel_orders',
|
|
115
|
+
params.verifyingAddr,
|
|
116
|
+
params.chainId,
|
|
117
|
+
cancelOrdersParams,
|
|
118
|
+
),
|
|
119
|
+
tx,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return this.execute('cancel_orders', executeParams);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async cancelProductOrders(params: TriggerCancelProductOrdersParams) {
|
|
126
|
+
const cancelProductOrdersParams: EIP712CancelProductOrdersParams = {
|
|
127
|
+
nonce: params.nonce ?? getOrderNonce(),
|
|
128
|
+
productIds: params.productIds,
|
|
129
|
+
subaccountName: params.subaccountName,
|
|
130
|
+
subaccountOwner: params.subaccountOwner,
|
|
131
|
+
};
|
|
132
|
+
const tx = getNadoEIP712Values(
|
|
133
|
+
'cancel_product_orders',
|
|
134
|
+
cancelProductOrdersParams,
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const executeParams: TriggerServerExecuteRequestByType['cancel_product_orders'] =
|
|
138
|
+
{
|
|
139
|
+
signature: await this.sign(
|
|
140
|
+
'cancel_product_orders',
|
|
141
|
+
params.verifyingAddr,
|
|
142
|
+
params.chainId,
|
|
143
|
+
cancelProductOrdersParams,
|
|
144
|
+
),
|
|
145
|
+
tx,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return this.execute('cancel_product_orders', executeParams);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/*
|
|
152
|
+
Queries
|
|
153
|
+
*/
|
|
154
|
+
async listOrders(
|
|
155
|
+
params: TriggerListOrdersParams,
|
|
156
|
+
): Promise<TriggerListOrdersResponse> {
|
|
157
|
+
const signatureParams: EIP712ListTriggerOrdersParams = {
|
|
158
|
+
// Default to 90 seconds from now if no recvTime is provided
|
|
159
|
+
recvTime: toIntegerString(params.recvTime ?? getDefaultRecvTime()),
|
|
160
|
+
subaccountName: params.subaccountName,
|
|
161
|
+
subaccountOwner: params.subaccountOwner,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const tx = getNadoEIP712Values('list_trigger_orders', signatureParams);
|
|
165
|
+
const signature = await this.sign(
|
|
166
|
+
'list_trigger_orders',
|
|
167
|
+
params.verifyingAddr,
|
|
168
|
+
params.chainId,
|
|
169
|
+
signatureParams,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const queryParams: TriggerServerQueryRequestByType['list_trigger_orders'] =
|
|
173
|
+
{
|
|
174
|
+
limit: params.limit,
|
|
175
|
+
max_update_time: params.maxUpdateTimeInclusive,
|
|
176
|
+
pending: params.pending,
|
|
177
|
+
product_id: params.productId,
|
|
178
|
+
digests: params.digests,
|
|
179
|
+
signature,
|
|
180
|
+
tx,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const baseResponse = await this.query('list_trigger_orders', queryParams);
|
|
184
|
+
|
|
185
|
+
const orders: TriggerOrderInfo[] =
|
|
186
|
+
baseResponse.orders.map(mapServerOrderInfo);
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
orders,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/*
|
|
194
|
+
Base Fns
|
|
195
|
+
*/
|
|
196
|
+
protected async sign<T extends SignableRequestType>(
|
|
197
|
+
requestType: T,
|
|
198
|
+
verifyingContract: string,
|
|
199
|
+
chainId: number,
|
|
200
|
+
params: SignableRequestTypeToParams[T],
|
|
201
|
+
) {
|
|
202
|
+
// Use the linked signer if provided, otherwise use the default signer provided to the engine
|
|
203
|
+
const walletClient =
|
|
204
|
+
this.opts.linkedSignerWalletClient ?? this.opts.walletClient;
|
|
205
|
+
|
|
206
|
+
if (walletClient == null) {
|
|
207
|
+
throw new WalletNotProvidedError();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return getSignedTransactionRequest({
|
|
211
|
+
chainId,
|
|
212
|
+
requestParams: params,
|
|
213
|
+
requestType,
|
|
214
|
+
walletClient,
|
|
215
|
+
verifyingContract,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* POSTs an execute message to the trigger service and returns the successful response. Throws the failure response wrapped
|
|
221
|
+
* in an TriggerServerFailureError on failure.
|
|
222
|
+
*
|
|
223
|
+
* @param requestType
|
|
224
|
+
* @param params
|
|
225
|
+
*/
|
|
226
|
+
protected async execute<TRequestType extends TriggerServerExecuteRequestType>(
|
|
227
|
+
requestType: TRequestType,
|
|
228
|
+
params: TriggerServerExecuteRequestByType[TRequestType],
|
|
229
|
+
): Promise<TriggerServerExecuteSuccessResult<TRequestType>> {
|
|
230
|
+
const reqBody = {
|
|
231
|
+
[requestType]: params,
|
|
232
|
+
};
|
|
233
|
+
const response = await this.axiosInstance.post<
|
|
234
|
+
TriggerServerExecuteResult<TRequestType>
|
|
235
|
+
>(`${this.opts.url}/execute`, reqBody);
|
|
236
|
+
|
|
237
|
+
this.checkResponseStatus(response);
|
|
238
|
+
this.checkServerStatus(response);
|
|
239
|
+
|
|
240
|
+
// checkServerStatus catches the failure result and throws the error, so the cast to the success response is acceptable here
|
|
241
|
+
return response.data as TriggerServerExecuteSuccessResult<TRequestType>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
protected async query<TRequestType extends TriggerServerQueryRequestType>(
|
|
245
|
+
requestType: TRequestType,
|
|
246
|
+
params: TriggerServerQueryRequestByType[TRequestType],
|
|
247
|
+
): Promise<TriggerServerQueryResponseByType[TRequestType]> {
|
|
248
|
+
const reqBody = {
|
|
249
|
+
type: requestType,
|
|
250
|
+
...params,
|
|
251
|
+
};
|
|
252
|
+
const response = await this.axiosInstance.post<
|
|
253
|
+
TriggerServerQueryResponse<TRequestType>
|
|
254
|
+
>(`${this.opts.url}/query`, reqBody);
|
|
255
|
+
|
|
256
|
+
this.checkResponseStatus(response);
|
|
257
|
+
this.checkServerStatus(response);
|
|
258
|
+
|
|
259
|
+
// checkServerStatus throws on failure responses so the cast to the success response is acceptable here
|
|
260
|
+
const successResponse = response as AxiosResponse<
|
|
261
|
+
TriggerServerQuerySuccessResponse<TRequestType>
|
|
262
|
+
>;
|
|
263
|
+
|
|
264
|
+
return successResponse.data.data;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private checkResponseStatus(response: AxiosResponse) {
|
|
268
|
+
if (response.status !== 200 || !response.data) {
|
|
269
|
+
throw Error(
|
|
270
|
+
`Unexpected response from server: ${response.status} ${response.statusText}`,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private checkServerStatus(
|
|
276
|
+
response: AxiosResponse<
|
|
277
|
+
TriggerServerExecuteResult | TriggerServerQueryResponse
|
|
278
|
+
>,
|
|
279
|
+
) {
|
|
280
|
+
if (response.data.status !== 'success') {
|
|
281
|
+
throw new TriggerServerFailureError(response.data);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addDecimals,
|
|
3
|
+
removeDecimals,
|
|
4
|
+
toBigDecimal,
|
|
5
|
+
toIntegerString,
|
|
6
|
+
} from '@nadohq/utils';
|
|
7
|
+
import {
|
|
8
|
+
TriggerCriteria,
|
|
9
|
+
TriggerOrder,
|
|
10
|
+
TriggerOrderInfo,
|
|
11
|
+
TriggerOrderStatus,
|
|
12
|
+
TriggerServerOrderInfo,
|
|
13
|
+
TriggerServerOrderStatus,
|
|
14
|
+
TriggerServerTriggerCriteria,
|
|
15
|
+
} from './types';
|
|
16
|
+
|
|
17
|
+
export function mapTriggerServerOrderStatus(
|
|
18
|
+
status: TriggerServerOrderStatus,
|
|
19
|
+
): TriggerOrderStatus {
|
|
20
|
+
if (status === 'pending') {
|
|
21
|
+
return {
|
|
22
|
+
type: 'pending',
|
|
23
|
+
};
|
|
24
|
+
} else if ('cancelled' in status) {
|
|
25
|
+
return {
|
|
26
|
+
type: 'cancelled',
|
|
27
|
+
reason: status.cancelled,
|
|
28
|
+
};
|
|
29
|
+
} else if ('internal_error' in status) {
|
|
30
|
+
return {
|
|
31
|
+
type: 'internal_error',
|
|
32
|
+
error: status.internal_error,
|
|
33
|
+
};
|
|
34
|
+
} else if ('triggered' in status) {
|
|
35
|
+
return {
|
|
36
|
+
type: 'triggered',
|
|
37
|
+
result: status.triggered,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
throw Error(`Unknown trigger order status: ${JSON.stringify(status)}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function mapTriggerCriteria(
|
|
44
|
+
criteria: TriggerCriteria,
|
|
45
|
+
): TriggerServerTriggerCriteria {
|
|
46
|
+
const priceValue = toIntegerString(addDecimals(criteria.triggerPrice));
|
|
47
|
+
switch (criteria.type) {
|
|
48
|
+
case 'oracle_price_above':
|
|
49
|
+
return { price_above: priceValue };
|
|
50
|
+
case 'oracle_price_below':
|
|
51
|
+
return { price_below: priceValue };
|
|
52
|
+
case 'last_price_above':
|
|
53
|
+
return { last_price_above: priceValue };
|
|
54
|
+
case 'last_price_below':
|
|
55
|
+
return { last_price_below: priceValue };
|
|
56
|
+
case 'mid_price_above':
|
|
57
|
+
return { mid_price_above: priceValue };
|
|
58
|
+
case 'mid_price_below':
|
|
59
|
+
return { mid_price_below: priceValue };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function mapServerTriggerCriteria(
|
|
64
|
+
criteria: TriggerServerTriggerCriteria,
|
|
65
|
+
): TriggerCriteria {
|
|
66
|
+
if ('price_above' in criteria) {
|
|
67
|
+
return {
|
|
68
|
+
type: 'oracle_price_above',
|
|
69
|
+
triggerPrice: removeDecimals(criteria.price_above),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if ('price_below' in criteria) {
|
|
73
|
+
return {
|
|
74
|
+
type: 'oracle_price_below',
|
|
75
|
+
triggerPrice: removeDecimals(criteria.price_below),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if ('last_price_above' in criteria) {
|
|
79
|
+
return {
|
|
80
|
+
type: 'last_price_above',
|
|
81
|
+
triggerPrice: removeDecimals(criteria.last_price_above),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if ('last_price_below' in criteria) {
|
|
85
|
+
return {
|
|
86
|
+
type: 'last_price_below',
|
|
87
|
+
triggerPrice: removeDecimals(criteria.last_price_below),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if ('mid_price_above' in criteria) {
|
|
91
|
+
return {
|
|
92
|
+
type: 'mid_price_above',
|
|
93
|
+
triggerPrice: removeDecimals(criteria.mid_price_above),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if ('mid_price_below' in criteria) {
|
|
97
|
+
return {
|
|
98
|
+
type: 'mid_price_below',
|
|
99
|
+
triggerPrice: removeDecimals(criteria.mid_price_below),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`Unknown trigger criteria: ${JSON.stringify(criteria)}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function mapServerOrderInfo(
|
|
106
|
+
info: TriggerServerOrderInfo,
|
|
107
|
+
): TriggerOrderInfo {
|
|
108
|
+
const { order: serverOrder, status, updated_at } = info;
|
|
109
|
+
const order: TriggerOrder = {
|
|
110
|
+
amount: toBigDecimal(serverOrder.order.amount),
|
|
111
|
+
expiration: toBigDecimal(serverOrder.order.expiration),
|
|
112
|
+
nonce: serverOrder.order.nonce,
|
|
113
|
+
price: removeDecimals(toBigDecimal(serverOrder.order.priceX18)),
|
|
114
|
+
digest: serverOrder.digest,
|
|
115
|
+
productId: serverOrder.product_id,
|
|
116
|
+
triggerCriteria: mapServerTriggerCriteria(serverOrder.trigger),
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
serverOrder,
|
|
120
|
+
order,
|
|
121
|
+
status: mapTriggerServerOrderStatus(status),
|
|
122
|
+
updatedAt: updated_at,
|
|
123
|
+
};
|
|
124
|
+
}
|
package/src/endpoints.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ChainEnv } from '@nadohq/contracts';
|
|
2
|
+
|
|
3
|
+
export const TRIGGER_CLIENT_ENDPOINTS: Record<ChainEnv, string> = {
|
|
4
|
+
local: 'http://localhost:80/trigger',
|
|
5
|
+
arbitrumTestnet: 'https://trigger.sepolia-test.vertexprotocol.com/v1',
|
|
6
|
+
arbitrum: 'https://trigger.prod.vertexprotocol.com/v1',
|
|
7
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TriggerServerQueryFailureResponse } from './serverQueryTypes';
|
|
2
|
+
import { EngineServerExecuteFailureResult } from '@nadohq/engine-client';
|
|
3
|
+
|
|
4
|
+
export class TriggerServerFailureError extends Error {
|
|
5
|
+
constructor(
|
|
6
|
+
readonly responseData:
|
|
7
|
+
| TriggerServerQueryFailureResponse
|
|
8
|
+
| EngineServerExecuteFailureResult,
|
|
9
|
+
) {
|
|
10
|
+
super();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EIP712CancelOrdersParams,
|
|
3
|
+
EIP712CancelProductOrdersParams,
|
|
4
|
+
Subaccount,
|
|
5
|
+
} from '@nadohq/contracts';
|
|
6
|
+
import {
|
|
7
|
+
EngineOrderParams,
|
|
8
|
+
EngineServerExecuteResult,
|
|
9
|
+
} from '@nadohq/engine-client';
|
|
10
|
+
import { BigDecimal, BigDecimalish } from '@nadohq/utils';
|
|
11
|
+
import { TriggerServerOrder } from './serverQueryTypes';
|
|
12
|
+
|
|
13
|
+
type WithOptionalNonce<T> = Omit<T, 'nonce'> & { nonce?: string };
|
|
14
|
+
|
|
15
|
+
export type TriggerCriteriaType =
|
|
16
|
+
| 'oracle_price_above'
|
|
17
|
+
| 'oracle_price_below'
|
|
18
|
+
| 'last_price_above'
|
|
19
|
+
| 'last_price_below'
|
|
20
|
+
| 'mid_price_above'
|
|
21
|
+
| 'mid_price_below';
|
|
22
|
+
|
|
23
|
+
export type TriggerCriteria = {
|
|
24
|
+
type: TriggerCriteriaType;
|
|
25
|
+
triggerPrice: BigDecimalish;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type TriggerOrderStatus =
|
|
29
|
+
| {
|
|
30
|
+
type: 'pending';
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
type: 'cancelled';
|
|
34
|
+
reason: string;
|
|
35
|
+
}
|
|
36
|
+
| {
|
|
37
|
+
type: 'triggered';
|
|
38
|
+
result: EngineServerExecuteResult;
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
type: 'internal_error';
|
|
42
|
+
error: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
interface SignatureParams {
|
|
46
|
+
// Orderbook address for placement, endpoint address for cancellation & listing
|
|
47
|
+
verifyingAddr: string;
|
|
48
|
+
chainId: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Executes
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
export interface TriggerPlaceOrderParams extends SignatureParams {
|
|
56
|
+
id?: number;
|
|
57
|
+
productId: number;
|
|
58
|
+
order: EngineOrderParams;
|
|
59
|
+
triggerCriteria: TriggerCriteria;
|
|
60
|
+
// If not given, engine defaults to true (leverage/borrow enabled)
|
|
61
|
+
spotLeverage?: boolean;
|
|
62
|
+
digest?: string;
|
|
63
|
+
nonce?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type TriggerCancelOrdersParams = SignatureParams &
|
|
67
|
+
WithOptionalNonce<EIP712CancelOrdersParams>;
|
|
68
|
+
|
|
69
|
+
export type TriggerCancelProductOrdersParams = SignatureParams &
|
|
70
|
+
WithOptionalNonce<EIP712CancelProductOrdersParams>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Queries
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
export interface TriggerListOrdersParams extends Subaccount, SignatureParams {
|
|
77
|
+
// In millis, defaults to 90s in the future
|
|
78
|
+
recvTime?: BigDecimal;
|
|
79
|
+
// If not given, defaults to all products
|
|
80
|
+
productId?: number;
|
|
81
|
+
// Pending trigger orders only, ignores cancelled & triggered orders
|
|
82
|
+
pending: boolean;
|
|
83
|
+
// In seconds
|
|
84
|
+
maxUpdateTimeInclusive?: number;
|
|
85
|
+
// When provided, the associated trigger orders are returned regardless of other filters
|
|
86
|
+
digests?: string[];
|
|
87
|
+
limit?: number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface TriggerOrder {
|
|
91
|
+
productId: number;
|
|
92
|
+
triggerCriteria: TriggerCriteria;
|
|
93
|
+
price: BigDecimal;
|
|
94
|
+
amount: BigDecimal;
|
|
95
|
+
expiration: BigDecimal;
|
|
96
|
+
nonce: string;
|
|
97
|
+
digest: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface TriggerOrderInfo {
|
|
101
|
+
order: TriggerOrder;
|
|
102
|
+
serverOrder: TriggerServerOrder;
|
|
103
|
+
status: TriggerOrderStatus;
|
|
104
|
+
updatedAt: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface TriggerListOrdersResponse {
|
|
108
|
+
orders: TriggerOrderInfo[];
|
|
109
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EIP712OrderValues } from '@nadohq/contracts';
|
|
2
|
+
import {
|
|
3
|
+
EngineServerExecuteFailureResult,
|
|
4
|
+
EngineServerExecuteRequestByType,
|
|
5
|
+
EngineServerExecuteSuccessResult,
|
|
6
|
+
} from '@nadohq/engine-client';
|
|
7
|
+
|
|
8
|
+
export type TriggerServerTriggerCriteria =
|
|
9
|
+
// These trigger on fast oracle price
|
|
10
|
+
| {
|
|
11
|
+
price_above: string;
|
|
12
|
+
}
|
|
13
|
+
| {
|
|
14
|
+
price_below: string;
|
|
15
|
+
}
|
|
16
|
+
// These trigger on last trade price
|
|
17
|
+
| {
|
|
18
|
+
last_price_above: string;
|
|
19
|
+
}
|
|
20
|
+
| {
|
|
21
|
+
last_price_below: string;
|
|
22
|
+
}
|
|
23
|
+
// These trigger on mid-book price
|
|
24
|
+
| {
|
|
25
|
+
mid_price_above: string;
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
mid_price_below: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface TriggerServerPlaceOrderParams {
|
|
32
|
+
id: number | null;
|
|
33
|
+
product_id: number;
|
|
34
|
+
order: EIP712OrderValues;
|
|
35
|
+
trigger: TriggerServerTriggerCriteria;
|
|
36
|
+
signature: string;
|
|
37
|
+
digest: string | null;
|
|
38
|
+
// Trigger service defaults this to true
|
|
39
|
+
spot_leverage: boolean | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type TriggerServerCancelOrdersParams =
|
|
43
|
+
EngineServerExecuteRequestByType['cancel_orders'];
|
|
44
|
+
|
|
45
|
+
export type TriggerServerCancelProductOrdersParams =
|
|
46
|
+
EngineServerExecuteRequestByType['cancel_product_orders'];
|
|
47
|
+
|
|
48
|
+
export interface TriggerServerExecuteRequestByType {
|
|
49
|
+
place_order: TriggerServerPlaceOrderParams;
|
|
50
|
+
cancel_orders: TriggerServerCancelOrdersParams;
|
|
51
|
+
cancel_product_orders: TriggerServerCancelProductOrdersParams;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type TriggerServerExecuteRequestType =
|
|
55
|
+
keyof TriggerServerExecuteRequestByType;
|
|
56
|
+
|
|
57
|
+
export type TriggerServerExecuteSuccessResult<
|
|
58
|
+
T extends TriggerServerExecuteRequestType = TriggerServerExecuteRequestType,
|
|
59
|
+
> = EngineServerExecuteSuccessResult<T>;
|
|
60
|
+
|
|
61
|
+
export type TriggerServerExecuteResult<
|
|
62
|
+
T extends TriggerServerExecuteRequestType = TriggerServerExecuteRequestType,
|
|
63
|
+
> = TriggerServerExecuteSuccessResult<T> | EngineServerExecuteFailureResult;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { EIP712ListTriggerOrdersValues, SignedTx } from '@nadohq/contracts';
|
|
2
|
+
import { EngineServerExecuteResult } from '@nadohq/engine-client';
|
|
3
|
+
import { TriggerServerPlaceOrderParams } from './serverExecuteTypes';
|
|
4
|
+
|
|
5
|
+
export type TriggerServerOrderStatus =
|
|
6
|
+
| 'pending'
|
|
7
|
+
| {
|
|
8
|
+
// Result from sending to engine
|
|
9
|
+
triggered: EngineServerExecuteResult;
|
|
10
|
+
}
|
|
11
|
+
| {
|
|
12
|
+
// Reason string
|
|
13
|
+
cancelled: string;
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
// Error message
|
|
17
|
+
internal_error: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Request types
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export interface TriggerServerListTriggerOrdersParams
|
|
25
|
+
extends SignedTx<EIP712ListTriggerOrdersValues> {
|
|
26
|
+
pending: boolean;
|
|
27
|
+
// If not given, defaults to all products
|
|
28
|
+
product_id?: number;
|
|
29
|
+
max_update_time?: number;
|
|
30
|
+
digests?: string[];
|
|
31
|
+
limit?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface TriggerServerQueryRequestByType {
|
|
35
|
+
list_trigger_orders: TriggerServerListTriggerOrdersParams;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type TriggerServerQueryRequestType =
|
|
39
|
+
keyof TriggerServerQueryRequestByType;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Response types
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
export type TriggerServerOrder = TriggerServerPlaceOrderParams & {
|
|
46
|
+
// Digest is always populated here
|
|
47
|
+
digest: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export interface TriggerServerOrderInfo {
|
|
51
|
+
order: TriggerServerOrder;
|
|
52
|
+
status: TriggerServerOrderStatus;
|
|
53
|
+
updated_at: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface TriggerServerListTriggerOrdersResponse {
|
|
57
|
+
orders: TriggerServerOrderInfo[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface TriggerServerQueryResponseByType {
|
|
61
|
+
list_trigger_orders: TriggerServerListTriggerOrdersResponse;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface TriggerServerQuerySuccessResponse<
|
|
65
|
+
TQueryType extends
|
|
66
|
+
keyof TriggerServerQueryResponseByType = TriggerServerQueryRequestType,
|
|
67
|
+
> {
|
|
68
|
+
status: 'success';
|
|
69
|
+
data: TriggerServerQueryResponseByType[TQueryType];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface TriggerServerQueryFailureResponse {
|
|
73
|
+
status: 'failure';
|
|
74
|
+
error: string;
|
|
75
|
+
error_code: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type TriggerServerQueryResponse<
|
|
79
|
+
TQueryType extends
|
|
80
|
+
keyof TriggerServerQueryResponseByType = TriggerServerQueryRequestType,
|
|
81
|
+
> =
|
|
82
|
+
| TriggerServerQuerySuccessResponse<TQueryType>
|
|
83
|
+
| TriggerServerQueryFailureResponse;
|