@n1xyz/nord-ts 0.0.22 → 0.1.0
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 +20 -16
- package/dist/gen/nord_pb.d.ts +100 -32
- package/dist/gen/nord_pb.js +62 -9
- package/dist/gen/openapi.d.ts +33 -8
- package/dist/nord/api/actions.d.ts +1 -0
- package/dist/nord/api/actions.js +33 -14
- package/dist/types.js +2 -2
- package/package.json +1 -1
- package/src/gen/nord_pb.ts +121 -36
- package/src/gen/openapi.ts +33 -8
- package/src/nord/api/actions.ts +47 -17
- package/src/types.ts +2 -2
package/src/gen/openapi.ts
CHANGED
|
@@ -112,11 +112,13 @@ export interface paths {
|
|
|
112
112
|
};
|
|
113
113
|
};
|
|
114
114
|
put?: never;
|
|
115
|
-
/** @description Send an action to nord to execute. */
|
|
115
|
+
/** @description Send an action to nord to execute. This doesn't use `Protobuf<T>` since we want to length-delimit this message. `body` - (length prefix of action, action data protobuf, and signature). signature has exact length, but depend on action kind. body is exact payload used via other transports and journalled for rexecution */
|
|
116
116
|
post: {
|
|
117
117
|
parameters: {
|
|
118
118
|
query?: never;
|
|
119
|
-
header
|
|
119
|
+
header: {
|
|
120
|
+
"content-type": string;
|
|
121
|
+
};
|
|
120
122
|
path?: never;
|
|
121
123
|
cookie?: never;
|
|
122
124
|
};
|
|
@@ -135,6 +137,19 @@ export interface paths {
|
|
|
135
137
|
"application/octet-stream": unknown;
|
|
136
138
|
};
|
|
137
139
|
};
|
|
140
|
+
415: {
|
|
141
|
+
headers: {
|
|
142
|
+
/**
|
|
143
|
+
* @description Expected request media type
|
|
144
|
+
* @example application/octet-stream
|
|
145
|
+
*/
|
|
146
|
+
accept: string;
|
|
147
|
+
[name: string]: unknown;
|
|
148
|
+
};
|
|
149
|
+
content: {
|
|
150
|
+
"application/json": components["schemas"]["AcceptedMediaType"];
|
|
151
|
+
};
|
|
152
|
+
};
|
|
138
153
|
};
|
|
139
154
|
};
|
|
140
155
|
delete?: never;
|
|
@@ -1893,6 +1908,9 @@ export interface components {
|
|
|
1893
1908
|
/** Format: uint16 */
|
|
1894
1909
|
weightBps: number;
|
|
1895
1910
|
};
|
|
1911
|
+
AcceptedMediaType: {
|
|
1912
|
+
expected: string;
|
|
1913
|
+
};
|
|
1896
1914
|
ActionsQuery: {
|
|
1897
1915
|
/** Format: uint64 */
|
|
1898
1916
|
from: number;
|
|
@@ -2224,8 +2242,6 @@ export interface components {
|
|
|
2224
2242
|
HistoryTriggerInfo: {
|
|
2225
2243
|
/** Format: uint32 */
|
|
2226
2244
|
accountId: number;
|
|
2227
|
-
/** Format: uint64 */
|
|
2228
|
-
actionId: number;
|
|
2229
2245
|
/** Format: uint32 */
|
|
2230
2246
|
marketId: number;
|
|
2231
2247
|
/** Format: uint64 */
|
|
@@ -2233,21 +2249,30 @@ export interface components {
|
|
|
2233
2249
|
side: components["schemas"]["Side"];
|
|
2234
2250
|
kind: components["schemas"]["TriggerKind"];
|
|
2235
2251
|
status: components["schemas"]["TriggerStatus"];
|
|
2252
|
+
/** Format: uint64 */
|
|
2253
|
+
createdAtActionId: number;
|
|
2254
|
+
/** Format: uint64 */
|
|
2255
|
+
finalizedAtActionId?: number | null;
|
|
2236
2256
|
createdAt: string;
|
|
2237
|
-
|
|
2257
|
+
finalizedAt: string;
|
|
2238
2258
|
};
|
|
2239
2259
|
/** @enum {string} */
|
|
2240
2260
|
TriggerKind: "stopLoss" | "takeProfit";
|
|
2241
2261
|
/** @enum {string} */
|
|
2242
|
-
TriggerStatus: "
|
|
2262
|
+
TriggerStatus: "active" | "success" | "cancel" | "fail" | "remove";
|
|
2243
2263
|
TriggerInfo: {
|
|
2244
2264
|
/** Format: uint32 */
|
|
2245
2265
|
marketId: number;
|
|
2246
|
-
/** Format: uint64 */
|
|
2247
|
-
price: number;
|
|
2248
2266
|
side: components["schemas"]["Side"];
|
|
2249
2267
|
kind: components["schemas"]["TriggerKind"];
|
|
2268
|
+
triggerPrice: components["schemas"]["PositivePriceMantissa"];
|
|
2269
|
+
limitPrice?: components["schemas"]["PositivePriceMantissa"] | null;
|
|
2250
2270
|
};
|
|
2271
|
+
/**
|
|
2272
|
+
* Format: uint64
|
|
2273
|
+
* @description 63 bit integer, which is always positive
|
|
2274
|
+
*/
|
|
2275
|
+
PositivePriceMantissa: number;
|
|
2251
2276
|
OrderNotFound: null;
|
|
2252
2277
|
PageResult_for_String_and_Trade: {
|
|
2253
2278
|
/** @description Set of items for requested by query. */
|
package/src/nord/api/actions.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import Decimal from "decimal.js";
|
|
2
2
|
import * as proto from "../../gen/nord_pb";
|
|
3
|
+
import { paths, components } from "../../gen/openapi";
|
|
4
|
+
import createClient from "openapi-fetch";
|
|
5
|
+
|
|
3
6
|
import { create } from "@bufbuild/protobuf";
|
|
4
7
|
import {
|
|
5
8
|
FillMode,
|
|
@@ -54,25 +57,23 @@ async function sendAction(
|
|
|
54
57
|
action: proto.Action,
|
|
55
58
|
actionErrorDesc: string,
|
|
56
59
|
): Promise<proto.Receipt> {
|
|
57
|
-
const
|
|
58
|
-
//
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const body = await makeSignedMessage(encoded);
|
|
66
|
-
|
|
67
|
-
// TODO: this should be changed to use openapi
|
|
68
|
-
const response = await checkedFetch(`${serverUrl}/action`, {
|
|
69
|
-
method: "POST",
|
|
70
|
-
headers: {
|
|
71
|
-
"Content-Type": "application/json",
|
|
60
|
+
const body = await prepareAction(action, makeSignedMessage);
|
|
61
|
+
// NOTE: restructure and reuse client as it is in Nord.ts
|
|
62
|
+
const client = createClient<paths>({ baseUrl: serverUrl });
|
|
63
|
+
const response = await client.POST("/action", {
|
|
64
|
+
params: {
|
|
65
|
+
header: {
|
|
66
|
+
"content-type": "application/octet-stream",
|
|
67
|
+
},
|
|
72
68
|
},
|
|
73
|
-
body,
|
|
69
|
+
body: body,
|
|
74
70
|
});
|
|
75
|
-
|
|
71
|
+
|
|
72
|
+
if (response.error) {
|
|
73
|
+
throw new Error(`Failed to ${actionErrorDesc}, HTTP status ${response}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const rawResp = new Uint8Array(await response.response.arrayBuffer());
|
|
76
77
|
|
|
77
78
|
const resp: proto.Receipt = decodeLengthDelimited(
|
|
78
79
|
rawResp,
|
|
@@ -88,6 +89,24 @@ async function sendAction(
|
|
|
88
89
|
return resp;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
// Given action and signature function, prepare the signed message to send to server as `body`.
|
|
93
|
+
// `makeSignedMessage` must include the original message and signature.
|
|
94
|
+
export async function prepareAction(
|
|
95
|
+
action: proto.Action,
|
|
96
|
+
makeSignedMessage: (message: Uint8Array) => Promise<Uint8Array>,
|
|
97
|
+
) {
|
|
98
|
+
const encoded = sizeDelimitedEncode(proto.ActionSchema, action);
|
|
99
|
+
// NOTE(agent): keep in sync with MAX_HTTP_REQUEST_BODY_SIZE in rust code
|
|
100
|
+
const MAX_HTTP_REQUEST_BODY_SIZE = 1024;
|
|
101
|
+
if (encoded.byteLength > MAX_HTTP_REQUEST_BODY_SIZE) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Encoded message size (${encoded.byteLength} bytes) is greater than max payload size (${MAX_HTTP_REQUEST_BODY_SIZE} bytes).`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
const body = await makeSignedMessage(encoded);
|
|
107
|
+
return body;
|
|
108
|
+
}
|
|
109
|
+
|
|
91
110
|
export async function createSession(
|
|
92
111
|
serverUrl: string,
|
|
93
112
|
walletSignFn: (message: string | Uint8Array) => Promise<Uint8Array>,
|
|
@@ -241,6 +260,11 @@ export async function placeOrder(
|
|
|
241
260
|
? params.quoteSize.toScaledU64(params.priceDecimals, params.sizeDecimals)
|
|
242
261
|
: undefined;
|
|
243
262
|
|
|
263
|
+
assert(
|
|
264
|
+
price > 0n || size > 0n || scaledQuote !== undefined,
|
|
265
|
+
"OrderLimit must include at least one of: size, price, or quoteSize",
|
|
266
|
+
);
|
|
267
|
+
|
|
244
268
|
const action = createAction(currentTimestamp, nonce, {
|
|
245
269
|
case: "placeOrder",
|
|
246
270
|
value: create(proto.Action_PlaceOrderSchema, {
|
|
@@ -431,6 +455,12 @@ export async function atomic(
|
|
|
431
455
|
? a.quoteSize.toScaledU64(a.priceDecimals, a.sizeDecimals)
|
|
432
456
|
: undefined;
|
|
433
457
|
|
|
458
|
+
// Require at least one limit to be set (non-zero size, non-zero price, or quoteSize)
|
|
459
|
+
assert(
|
|
460
|
+
price > 0n || size > 0n || scaledQuote !== undefined,
|
|
461
|
+
"OrderLimit must include at least one of: size, price, or quoteSize",
|
|
462
|
+
);
|
|
463
|
+
|
|
434
464
|
const tradeOrPlace: proto.TradeOrPlace = create(
|
|
435
465
|
proto.TradeOrPlaceSchema,
|
|
436
466
|
{
|
package/src/types.ts
CHANGED
|
@@ -310,8 +310,8 @@ export class QuoteSize {
|
|
|
310
310
|
constructor(quotePrice: Decimal.Value, quoteSize: Decimal.Value) {
|
|
311
311
|
const p = new Decimal(quotePrice);
|
|
312
312
|
const s = new Decimal(quoteSize);
|
|
313
|
-
if (p.
|
|
314
|
-
throw new Error("quotePrice and quoteSize must be
|
|
313
|
+
if (!p.isPositive() || !s.isPositive()) {
|
|
314
|
+
throw new Error("quotePrice and quoteSize must be positive");
|
|
315
315
|
}
|
|
316
316
|
this.price = p;
|
|
317
317
|
this.size = s;
|