@n1xyz/nord-ts 0.0.21 → 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/api/client.d.ts +14 -0
- package/dist/api/client.js +45 -0
- package/dist/bridge/client.d.ts +151 -0
- package/dist/bridge/client.js +434 -0
- package/dist/bridge/const.d.ts +23 -0
- package/dist/bridge/const.js +47 -0
- package/dist/bridge/index.d.ts +4 -0
- package/dist/bridge/index.js +23 -0
- package/dist/bridge/types.d.ts +120 -0
- package/dist/bridge/types.js +18 -0
- package/dist/bridge/utils.d.ts +64 -0
- package/dist/bridge/utils.js +131 -0
- package/dist/gen/common.d.ts +68 -0
- package/dist/gen/common.js +215 -0
- package/dist/gen/nord_pb.d.ts +3719 -0
- package/dist/gen/nord_pb.js +945 -0
- package/dist/gen/openapi.d.ts +268 -4
- package/dist/idl/bridge.d.ts +569 -0
- package/dist/idl/bridge.js +8 -0
- package/dist/idl/bridge.json +1506 -0
- package/dist/idl/index.d.ts +607 -0
- package/dist/idl/index.js +8 -0
- package/dist/nord/api/actions.d.ts +31 -72
- package/dist/nord/api/actions.js +199 -201
- package/dist/nord/api/market.d.ts +36 -0
- package/dist/nord/api/market.js +96 -0
- package/dist/nord/api/queries.d.ts +46 -0
- package/dist/nord/api/queries.js +109 -0
- package/dist/nord/client/Nord.js +3 -3
- package/dist/nord/client/NordUser.d.ts +26 -13
- package/dist/nord/client/NordUser.js +13 -10
- package/dist/types.d.ts +12 -1
- package/dist/types.js +29 -2
- package/dist/utils.d.ts +6 -20
- package/dist/utils.js +17 -35
- package/dist/websocket/NordWebSocketClient.js +2 -6
- package/package.json +26 -23
- package/src/gen/nord_pb.ts +4257 -0
- package/src/gen/openapi.ts +268 -4
- package/src/nord/api/actions.ts +278 -369
- package/src/nord/client/Nord.ts +3 -3
- package/src/nord/client/NordUser.ts +40 -19
- package/src/types.ts +32 -1
- package/src/utils.ts +24 -43
- package/src/websocket/NordWebSocketClient.ts +2 -8
package/src/nord/api/actions.ts
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import Decimal from "decimal.js";
|
|
2
|
-
import * as proto from "../../gen/
|
|
3
|
-
import {
|
|
2
|
+
import * as proto from "../../gen/nord_pb";
|
|
3
|
+
import { paths, components } from "../../gen/openapi";
|
|
4
|
+
import createClient from "openapi-fetch";
|
|
5
|
+
|
|
6
|
+
import { create } from "@bufbuild/protobuf";
|
|
7
|
+
import {
|
|
8
|
+
FillMode,
|
|
9
|
+
fillModeToProtoFillMode,
|
|
10
|
+
KeyType,
|
|
11
|
+
Side,
|
|
12
|
+
QuoteSize,
|
|
13
|
+
} from "../../types";
|
|
4
14
|
import {
|
|
5
15
|
assert,
|
|
6
16
|
BigIntValue,
|
|
7
17
|
checkedFetch,
|
|
8
18
|
checkPubKeyLength,
|
|
9
19
|
decodeLengthDelimited,
|
|
10
|
-
encodeLengthDelimited,
|
|
11
20
|
SESSION_TTL,
|
|
12
21
|
toScaledU64,
|
|
13
22
|
} from "../../utils";
|
|
23
|
+
import { sizeDelimitedEncode } from "@bufbuild/protobuf/wire";
|
|
14
24
|
|
|
15
25
|
async function sessionSign(
|
|
16
26
|
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
@@ -28,44 +38,77 @@ async function walletSign(
|
|
|
28
38
|
return new Uint8Array([...message, ...signature]);
|
|
29
39
|
}
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
43
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
44
|
-
};
|
|
41
|
+
// Helper to create an action with common fields
|
|
42
|
+
function createAction(
|
|
43
|
+
currentTimestamp: bigint,
|
|
44
|
+
nonce: number,
|
|
45
|
+
kind: proto.Action["kind"],
|
|
46
|
+
): proto.Action {
|
|
47
|
+
return create(proto.ActionSchema, {
|
|
48
|
+
currentTimestamp,
|
|
49
|
+
nonce,
|
|
50
|
+
kind,
|
|
51
|
+
});
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
async function sendAction(
|
|
48
|
-
|
|
55
|
+
serverUrl: string,
|
|
49
56
|
makeSignedMessage: (message: Uint8Array) => Promise<Uint8Array>,
|
|
50
57
|
action: proto.Action,
|
|
51
58
|
actionErrorDesc: string,
|
|
52
59
|
): Promise<proto.Receipt> {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
const
|
|
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
|
+
},
|
|
68
|
+
},
|
|
69
|
+
body: body,
|
|
70
|
+
});
|
|
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());
|
|
57
77
|
|
|
58
|
-
|
|
78
|
+
const resp: proto.Receipt = decodeLengthDelimited(
|
|
79
|
+
rawResp,
|
|
80
|
+
proto.ReceiptSchema,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (resp.kind?.case === "err") {
|
|
59
84
|
throw new Error(
|
|
60
|
-
`Could not ${actionErrorDesc}, reason: ${proto.
|
|
85
|
+
`Could not ${actionErrorDesc}, reason: ${proto.Error[resp.kind.value]}`,
|
|
61
86
|
);
|
|
62
87
|
}
|
|
63
88
|
|
|
64
89
|
return resp;
|
|
65
90
|
}
|
|
66
91
|
|
|
67
|
-
|
|
68
|
-
|
|
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
|
+
|
|
110
|
+
export async function createSession(
|
|
111
|
+
serverUrl: string,
|
|
69
112
|
walletSignFn: (message: string | Uint8Array) => Promise<Uint8Array>,
|
|
70
113
|
currentTimestamp: bigint,
|
|
71
114
|
nonce: number,
|
|
@@ -75,7 +118,7 @@ async function createSessionImpl(
|
|
|
75
118
|
// If not specified, set to current moment plus default session TTL
|
|
76
119
|
expiryTimestamp?: bigint;
|
|
77
120
|
},
|
|
78
|
-
): Promise<bigint> {
|
|
121
|
+
): Promise<{ actionId: bigint; sessionId: bigint }> {
|
|
79
122
|
checkPubKeyLength(KeyType.Ed25519, params.userPubkey.length);
|
|
80
123
|
checkPubKeyLength(KeyType.Ed25519, params.sessionPubkey.length);
|
|
81
124
|
|
|
@@ -91,102 +134,60 @@ async function createSessionImpl(
|
|
|
91
134
|
expiry = currentTimestamp + SESSION_TTL;
|
|
92
135
|
}
|
|
93
136
|
|
|
94
|
-
const action
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
expiryTimestamp: expiry,
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
};
|
|
137
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
138
|
+
case: "createSession",
|
|
139
|
+
value: create(proto.Action_CreateSessionSchema, {
|
|
140
|
+
userPubkey: params.userPubkey,
|
|
141
|
+
blstPubkey: params.sessionPubkey,
|
|
142
|
+
expiryTimestamp: expiry,
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
106
145
|
|
|
107
146
|
const resp = await sendAction(
|
|
108
|
-
|
|
147
|
+
serverUrl,
|
|
109
148
|
(m) => walletSign(walletSignFn, m),
|
|
110
149
|
action,
|
|
111
150
|
"create a new session",
|
|
112
151
|
);
|
|
113
152
|
|
|
114
|
-
if (resp.kind
|
|
115
|
-
return
|
|
153
|
+
if (resp.kind?.case === "createSessionResult") {
|
|
154
|
+
return {
|
|
155
|
+
actionId: resp.actionId,
|
|
156
|
+
sessionId: resp.kind.value.sessionId,
|
|
157
|
+
};
|
|
116
158
|
} else {
|
|
117
|
-
throw new Error(`Unexpected receipt kind ${resp.kind
|
|
159
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
118
160
|
}
|
|
119
161
|
}
|
|
120
162
|
|
|
121
|
-
export async function
|
|
163
|
+
export async function revokeSession(
|
|
122
164
|
serverUrl: string,
|
|
123
165
|
walletSignFn: (message: string | Uint8Array) => Promise<Uint8Array>,
|
|
124
166
|
currentTimestamp: bigint,
|
|
125
167
|
nonce: number,
|
|
126
|
-
params: {
|
|
127
|
-
userPubkey: Uint8Array;
|
|
128
|
-
sessionPubkey: Uint8Array;
|
|
129
|
-
// If not specified, set to current moment plus default session TTL
|
|
130
|
-
expiryTimestamp?: bigint;
|
|
131
|
-
},
|
|
132
|
-
): Promise<bigint> {
|
|
133
|
-
return createSessionImpl(
|
|
134
|
-
makeSendHttp(serverUrl),
|
|
135
|
-
walletSignFn,
|
|
136
|
-
currentTimestamp,
|
|
137
|
-
nonce,
|
|
138
|
-
params,
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async function revokeSessionImpl(
|
|
143
|
-
sendFn: (encoded: Uint8Array) => Promise<Uint8Array>,
|
|
144
|
-
walletSignFn: (message: string | Uint8Array) => Promise<Uint8Array>,
|
|
145
|
-
currentTimestamp: bigint,
|
|
146
|
-
nonce: number,
|
|
147
168
|
params: {
|
|
148
169
|
sessionId: BigIntValue;
|
|
149
170
|
},
|
|
150
|
-
): Promise<
|
|
151
|
-
const action
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
sessionId: BigInt(params.sessionId),
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
|
-
};
|
|
171
|
+
): Promise<{ actionId: bigint }> {
|
|
172
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
173
|
+
case: "revokeSession",
|
|
174
|
+
value: create(proto.Action_RevokeSessionSchema, {
|
|
175
|
+
sessionId: BigInt(params.sessionId),
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
161
178
|
|
|
162
|
-
await sendAction(
|
|
163
|
-
|
|
179
|
+
const resp = await sendAction(
|
|
180
|
+
serverUrl,
|
|
164
181
|
(m) => walletSign(walletSignFn, m),
|
|
165
182
|
action,
|
|
166
|
-
"
|
|
183
|
+
"revoke session",
|
|
167
184
|
);
|
|
168
|
-
}
|
|
169
185
|
|
|
170
|
-
|
|
171
|
-
serverUrl: string,
|
|
172
|
-
walletSignFn: (message: string | Uint8Array) => Promise<Uint8Array>,
|
|
173
|
-
currentTimestamp: bigint,
|
|
174
|
-
nonce: number,
|
|
175
|
-
params: {
|
|
176
|
-
sessionId: BigIntValue;
|
|
177
|
-
},
|
|
178
|
-
): Promise<void> {
|
|
179
|
-
return revokeSessionImpl(
|
|
180
|
-
makeSendHttp(serverUrl),
|
|
181
|
-
walletSignFn,
|
|
182
|
-
currentTimestamp,
|
|
183
|
-
nonce,
|
|
184
|
-
params,
|
|
185
|
-
);
|
|
186
|
+
return { actionId: resp.actionId };
|
|
186
187
|
}
|
|
187
188
|
|
|
188
|
-
async function
|
|
189
|
-
|
|
189
|
+
export async function withdraw(
|
|
190
|
+
serverUrl: string,
|
|
190
191
|
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
191
192
|
currentTimestamp: bigint,
|
|
192
193
|
nonce: number,
|
|
@@ -203,63 +204,37 @@ async function withdrawImpl(
|
|
|
203
204
|
throw new Error("Withdraw amount must be positive");
|
|
204
205
|
}
|
|
205
206
|
|
|
206
|
-
const action
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
amount,
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
};
|
|
207
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
208
|
+
case: "withdraw",
|
|
209
|
+
value: create(proto.Action_WithdrawSchema, {
|
|
210
|
+
sessionId: BigInt(params.sessionId),
|
|
211
|
+
tokenId: params.tokenId,
|
|
212
|
+
amount,
|
|
213
|
+
}),
|
|
214
|
+
});
|
|
218
215
|
|
|
219
216
|
const resp = await sendAction(
|
|
220
|
-
|
|
217
|
+
serverUrl,
|
|
221
218
|
(m) => sessionSign(signFn, m),
|
|
222
219
|
action,
|
|
223
220
|
"withdraw",
|
|
224
221
|
);
|
|
225
222
|
|
|
226
|
-
if (resp.kind
|
|
223
|
+
if (resp.kind?.case === "withdrawResult") {
|
|
227
224
|
return { actionId: resp.actionId, ...resp.kind.value };
|
|
228
225
|
} else {
|
|
229
|
-
throw new Error(`Unexpected receipt kind ${resp.kind
|
|
226
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
230
227
|
}
|
|
231
228
|
}
|
|
232
229
|
|
|
233
|
-
export async function
|
|
230
|
+
export async function placeOrder(
|
|
234
231
|
serverUrl: string,
|
|
235
232
|
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
236
233
|
currentTimestamp: bigint,
|
|
237
234
|
nonce: number,
|
|
238
|
-
params: {
|
|
239
|
-
sizeDecimals: number;
|
|
240
|
-
sessionId: BigIntValue;
|
|
241
|
-
tokenId: number;
|
|
242
|
-
amount: number;
|
|
243
|
-
},
|
|
244
|
-
): Promise<{ actionId: bigint } & proto.Receipt_WithdrawResult> {
|
|
245
|
-
return withdrawImpl(
|
|
246
|
-
makeSendHttp(serverUrl),
|
|
247
|
-
signFn,
|
|
248
|
-
currentTimestamp,
|
|
249
|
-
nonce,
|
|
250
|
-
params,
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
async function placeOrderImpl(
|
|
255
|
-
sendFn: (encoded: Uint8Array) => Promise<Uint8Array>,
|
|
256
|
-
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
257
|
-
currentTimestamp: bigint,
|
|
258
|
-
nonce: number,
|
|
259
235
|
params: {
|
|
260
236
|
sessionId: BigIntValue;
|
|
261
237
|
senderId?: number;
|
|
262
|
-
liquidateeId?: number;
|
|
263
238
|
sizeDecimals: number;
|
|
264
239
|
priceDecimals: number;
|
|
265
240
|
marketId: number;
|
|
@@ -269,154 +244,120 @@ async function placeOrderImpl(
|
|
|
269
244
|
// NOTE: if `size` equals 1.0, it will sell whole unit, for example 1.0 BTC
|
|
270
245
|
size?: Decimal.Value;
|
|
271
246
|
price?: Decimal.Value;
|
|
272
|
-
|
|
273
|
-
|
|
247
|
+
quoteSize?: QuoteSize;
|
|
248
|
+
liquidateeId?: number;
|
|
274
249
|
clientOrderId?: BigIntValue;
|
|
275
250
|
},
|
|
276
|
-
): Promise<
|
|
251
|
+
): Promise<{
|
|
252
|
+
actionId: bigint;
|
|
253
|
+
orderId?: bigint;
|
|
254
|
+
fills: proto.Receipt_Trade[];
|
|
255
|
+
}> {
|
|
277
256
|
const price = toScaledU64(params.price ?? 0, params.priceDecimals);
|
|
278
257
|
const size = toScaledU64(params.size ?? 0, params.sizeDecimals);
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
-
params.
|
|
282
|
-
|
|
258
|
+
|
|
259
|
+
const scaledQuote = params.quoteSize
|
|
260
|
+
? params.quoteSize.toScaledU64(params.priceDecimals, params.sizeDecimals)
|
|
261
|
+
: undefined;
|
|
262
|
+
|
|
263
|
+
assert(
|
|
264
|
+
price > 0n || size > 0n || scaledQuote !== undefined,
|
|
265
|
+
"OrderLimit must include at least one of: size, price, or quoteSize",
|
|
283
266
|
);
|
|
284
267
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
268
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
269
|
+
case: "placeOrder",
|
|
270
|
+
value: create(proto.Action_PlaceOrderSchema, {
|
|
271
|
+
sessionId: BigInt(params.sessionId),
|
|
272
|
+
senderAccountId: params.senderId,
|
|
273
|
+
marketId: params.marketId,
|
|
274
|
+
side: params.side === Side.Bid ? proto.Side.BID : proto.Side.ASK,
|
|
275
|
+
fillMode: fillModeToProtoFillMode(params.fillMode),
|
|
276
|
+
isReduceOnly: params.isReduceOnly,
|
|
277
|
+
price,
|
|
278
|
+
size,
|
|
279
|
+
quoteSize:
|
|
280
|
+
scaledQuote === undefined
|
|
281
|
+
? undefined
|
|
282
|
+
: create(proto.QuoteSizeSchema, {
|
|
283
|
+
size: scaledQuote.size,
|
|
284
|
+
price: scaledQuote.price,
|
|
285
|
+
}),
|
|
286
|
+
clientOrderId:
|
|
287
|
+
params.clientOrderId === undefined
|
|
288
|
+
? undefined
|
|
289
|
+
: BigInt(params.clientOrderId),
|
|
290
|
+
delegatorAccountId: params.liquidateeId,
|
|
291
|
+
}),
|
|
292
|
+
});
|
|
309
293
|
|
|
310
294
|
const resp = await sendAction(
|
|
311
|
-
|
|
295
|
+
serverUrl,
|
|
312
296
|
(m) => sessionSign(signFn, m),
|
|
313
297
|
action,
|
|
314
|
-
"place
|
|
298
|
+
"place order",
|
|
315
299
|
);
|
|
316
300
|
|
|
317
|
-
if (resp.kind
|
|
318
|
-
return
|
|
301
|
+
if (resp.kind?.case === "placeOrderResult") {
|
|
302
|
+
return {
|
|
303
|
+
actionId: resp.actionId,
|
|
304
|
+
orderId: resp.kind.value.posted?.orderId,
|
|
305
|
+
fills: resp.kind.value.fills,
|
|
306
|
+
};
|
|
319
307
|
} else {
|
|
320
|
-
throw new Error(`Unexpected receipt kind ${resp.kind
|
|
308
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
321
309
|
}
|
|
322
310
|
}
|
|
323
311
|
|
|
324
|
-
export async function
|
|
312
|
+
export async function cancelOrder(
|
|
325
313
|
serverUrl: string,
|
|
326
314
|
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
327
315
|
currentTimestamp: bigint,
|
|
328
316
|
nonce: number,
|
|
329
|
-
params: {
|
|
330
|
-
sessionId: BigIntValue;
|
|
331
|
-
senderId?: number;
|
|
332
|
-
sizeDecimals: number;
|
|
333
|
-
priceDecimals: number;
|
|
334
|
-
marketId: number;
|
|
335
|
-
side: Side;
|
|
336
|
-
fillMode: FillMode;
|
|
337
|
-
isReduceOnly: boolean;
|
|
338
|
-
size?: Decimal.Value;
|
|
339
|
-
price?: Decimal.Value;
|
|
340
|
-
quoteSize?: Decimal.Value;
|
|
341
|
-
liquidateeId?: number;
|
|
342
|
-
clientOrderId?: BigIntValue;
|
|
343
|
-
},
|
|
344
|
-
): Promise<bigint | undefined> {
|
|
345
|
-
return placeOrderImpl(
|
|
346
|
-
makeSendHttp(serverUrl),
|
|
347
|
-
signFn,
|
|
348
|
-
currentTimestamp,
|
|
349
|
-
nonce,
|
|
350
|
-
params,
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
async function cancelOrderImpl(
|
|
355
|
-
sendFn: (encoded: Uint8Array) => Promise<Uint8Array>,
|
|
356
|
-
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
357
|
-
currentTimestamp: bigint,
|
|
358
|
-
nonce: number,
|
|
359
317
|
params: {
|
|
360
318
|
sessionId: BigIntValue;
|
|
361
319
|
senderId?: number;
|
|
362
320
|
orderId: BigIntValue;
|
|
363
321
|
liquidateeId?: number;
|
|
364
322
|
},
|
|
365
|
-
): Promise<
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
},
|
|
378
|
-
};
|
|
323
|
+
): Promise<{
|
|
324
|
+
actionId: bigint;
|
|
325
|
+
orderId: bigint;
|
|
326
|
+
accountId: number;
|
|
327
|
+
}> {
|
|
328
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
329
|
+
case: "cancelOrderById",
|
|
330
|
+
value: create(proto.Action_CancelOrderByIdSchema, {
|
|
331
|
+
orderId: BigInt(params.orderId),
|
|
332
|
+
sessionId: BigInt(params.sessionId),
|
|
333
|
+
senderAccountId: params.senderId,
|
|
334
|
+
delegatorAccountId: params.liquidateeId,
|
|
335
|
+
}),
|
|
336
|
+
});
|
|
379
337
|
|
|
380
338
|
const resp = await sendAction(
|
|
381
|
-
|
|
339
|
+
serverUrl,
|
|
382
340
|
(m) => sessionSign(signFn, m),
|
|
383
341
|
action,
|
|
384
|
-
"cancel
|
|
342
|
+
"cancel order",
|
|
385
343
|
);
|
|
386
344
|
|
|
387
|
-
if (resp.kind
|
|
388
|
-
return
|
|
345
|
+
if (resp.kind?.case === "cancelOrderResult") {
|
|
346
|
+
return {
|
|
347
|
+
actionId: resp.actionId,
|
|
348
|
+
orderId: resp.kind.value.orderId,
|
|
349
|
+
accountId: resp.kind.value.accountId,
|
|
350
|
+
};
|
|
389
351
|
} else {
|
|
390
|
-
throw new Error(`Unexpected receipt kind ${resp.kind
|
|
352
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
391
353
|
}
|
|
392
354
|
}
|
|
393
355
|
|
|
394
|
-
export async function
|
|
356
|
+
export async function transfer(
|
|
395
357
|
serverUrl: string,
|
|
396
358
|
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
397
359
|
currentTimestamp: bigint,
|
|
398
360
|
nonce: number,
|
|
399
|
-
params: {
|
|
400
|
-
sessionId: BigIntValue;
|
|
401
|
-
senderId?: number;
|
|
402
|
-
orderId: BigIntValue;
|
|
403
|
-
liquidateeId?: number;
|
|
404
|
-
},
|
|
405
|
-
): Promise<bigint> {
|
|
406
|
-
return cancelOrderImpl(
|
|
407
|
-
makeSendHttp(serverUrl),
|
|
408
|
-
signFn,
|
|
409
|
-
currentTimestamp,
|
|
410
|
-
nonce,
|
|
411
|
-
params,
|
|
412
|
-
);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
async function transferImpl(
|
|
416
|
-
sendFn: (encoded: Uint8Array) => Promise<Uint8Array>,
|
|
417
|
-
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
418
|
-
currentTimestamp: bigint,
|
|
419
|
-
nonce: number,
|
|
420
361
|
params: {
|
|
421
362
|
sessionId: BigIntValue;
|
|
422
363
|
fromAccountId: number;
|
|
@@ -425,63 +366,46 @@ async function transferImpl(
|
|
|
425
366
|
tokenDecimals: number;
|
|
426
367
|
amount: Decimal.Value;
|
|
427
368
|
},
|
|
428
|
-
): Promise<
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
369
|
+
): Promise<{
|
|
370
|
+
actionId: bigint;
|
|
371
|
+
fromAccountId: number;
|
|
372
|
+
toAccountId?: number;
|
|
373
|
+
tokenId: number;
|
|
374
|
+
amount: bigint;
|
|
375
|
+
accountCreated: boolean;
|
|
376
|
+
}> {
|
|
377
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
378
|
+
case: "transfer",
|
|
379
|
+
value: create(proto.Action_TransferSchema, {
|
|
380
|
+
sessionId: BigInt(params.sessionId),
|
|
381
|
+
fromAccountId: params.fromAccountId,
|
|
382
|
+
toAccountId: params.toAccountId,
|
|
383
|
+
tokenId: params.tokenId,
|
|
384
|
+
amount: toScaledU64(params.amount ?? 0, params.tokenDecimals),
|
|
385
|
+
}),
|
|
386
|
+
});
|
|
443
387
|
|
|
444
388
|
const resp = await sendAction(
|
|
445
|
-
|
|
389
|
+
serverUrl,
|
|
446
390
|
(m) => sessionSign(signFn, m),
|
|
447
391
|
action,
|
|
448
|
-
"transfer
|
|
392
|
+
"transfer",
|
|
449
393
|
);
|
|
450
394
|
|
|
451
|
-
if (resp.kind
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
395
|
+
if (resp.kind?.case === "transferred") {
|
|
396
|
+
return {
|
|
397
|
+
actionId: resp.actionId,
|
|
398
|
+
fromAccountId: resp.kind.value.fromAccountId,
|
|
399
|
+
toAccountId: resp.kind.value.toUserAccount,
|
|
400
|
+
tokenId: resp.kind.value.tokenId,
|
|
401
|
+
amount: resp.kind.value.amount,
|
|
402
|
+
accountCreated: resp.kind.value.accountCreated,
|
|
403
|
+
};
|
|
457
404
|
} else {
|
|
458
|
-
throw new Error(`Unexpected receipt kind ${resp.kind
|
|
405
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
459
406
|
}
|
|
460
407
|
}
|
|
461
408
|
|
|
462
|
-
export async function transfer(
|
|
463
|
-
serverUrl: string,
|
|
464
|
-
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
465
|
-
currentTimestamp: bigint,
|
|
466
|
-
nonce: number,
|
|
467
|
-
params: {
|
|
468
|
-
sessionId: BigIntValue;
|
|
469
|
-
fromAccountId: number;
|
|
470
|
-
toAccountId?: number;
|
|
471
|
-
tokenId: number;
|
|
472
|
-
tokenDecimals: number;
|
|
473
|
-
amount: Decimal.Value;
|
|
474
|
-
},
|
|
475
|
-
): Promise<number | undefined> {
|
|
476
|
-
return transferImpl(
|
|
477
|
-
makeSendHttp(serverUrl),
|
|
478
|
-
signFn,
|
|
479
|
-
currentTimestamp,
|
|
480
|
-
nonce,
|
|
481
|
-
params,
|
|
482
|
-
);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
409
|
export type AtomicSubaction =
|
|
486
410
|
| {
|
|
487
411
|
kind: "place";
|
|
@@ -496,8 +420,7 @@ export type AtomicSubaction =
|
|
|
496
420
|
// at least one of the three has to be specified; 0 treated as "not set"
|
|
497
421
|
size?: Decimal.Value;
|
|
498
422
|
price?: Decimal.Value;
|
|
499
|
-
|
|
500
|
-
quoteSizePrice?: Decimal.Value;
|
|
423
|
+
quoteSize?: QuoteSize;
|
|
501
424
|
clientOrderId?: BigIntValue;
|
|
502
425
|
}
|
|
503
426
|
| {
|
|
@@ -505,8 +428,8 @@ export type AtomicSubaction =
|
|
|
505
428
|
orderId: BigIntValue;
|
|
506
429
|
};
|
|
507
430
|
|
|
508
|
-
async function
|
|
509
|
-
|
|
431
|
+
export async function atomic(
|
|
432
|
+
serverUrl: string,
|
|
510
433
|
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
511
434
|
currentTimestamp: bigint,
|
|
512
435
|
nonce: number,
|
|
@@ -515,7 +438,10 @@ async function atomicImpl(
|
|
|
515
438
|
accountId?: number;
|
|
516
439
|
actions: AtomicSubaction[];
|
|
517
440
|
},
|
|
518
|
-
): Promise<
|
|
441
|
+
): Promise<{
|
|
442
|
+
actionId: bigint;
|
|
443
|
+
results: proto.Receipt_AtomicSubactionResultKind[];
|
|
444
|
+
}> {
|
|
519
445
|
assert(
|
|
520
446
|
params.actions.length > 0 && params.actions.length <= 4,
|
|
521
447
|
"Atomic action must contain between 1 and 4 sub-actions",
|
|
@@ -525,89 +451,72 @@ async function atomicImpl(
|
|
|
525
451
|
if (a.kind === "place") {
|
|
526
452
|
const price = toScaledU64(a.price ?? 0, a.priceDecimals);
|
|
527
453
|
const size = toScaledU64(a.size ?? 0, a.sizeDecimals);
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
454
|
+
const scaledQuote = a.quoteSize
|
|
455
|
+
? a.quoteSize.toScaledU64(a.priceDecimals, a.sizeDecimals)
|
|
456
|
+
: undefined;
|
|
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",
|
|
532
462
|
);
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
463
|
+
|
|
464
|
+
const tradeOrPlace: proto.TradeOrPlace = create(
|
|
465
|
+
proto.TradeOrPlaceSchema,
|
|
466
|
+
{
|
|
467
|
+
marketId: a.marketId,
|
|
468
|
+
orderType: create(proto.OrderTypeSchema, {
|
|
469
|
+
side: a.side === Side.Bid ? proto.Side.BID : proto.Side.ASK,
|
|
470
|
+
fillMode: fillModeToProtoFillMode(a.fillMode),
|
|
471
|
+
isReduceOnly: a.isReduceOnly,
|
|
472
|
+
}),
|
|
473
|
+
limit: create(proto.OrderLimitSchema, {
|
|
474
|
+
price,
|
|
475
|
+
size,
|
|
476
|
+
quoteSize:
|
|
477
|
+
scaledQuote === undefined
|
|
478
|
+
? undefined
|
|
479
|
+
: create(proto.QuoteSizeSchema, {
|
|
480
|
+
size: scaledQuote.size,
|
|
481
|
+
price: scaledQuote.price,
|
|
482
|
+
}),
|
|
483
|
+
}),
|
|
484
|
+
clientOrderId:
|
|
485
|
+
a.clientOrderId === undefined ? undefined : BigInt(a.clientOrderId),
|
|
544
486
|
},
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
inner: { $case: "tradeOrPlace", value: tradeOrPlace },
|
|
550
|
-
} as proto.AtomicSubactionKind;
|
|
487
|
+
);
|
|
488
|
+
return create(proto.AtomicSubactionKindSchema, {
|
|
489
|
+
inner: { case: "tradeOrPlace", value: tradeOrPlace },
|
|
490
|
+
});
|
|
551
491
|
}
|
|
552
|
-
return {
|
|
553
|
-
inner: {
|
|
554
|
-
|
|
492
|
+
return create(proto.AtomicSubactionKindSchema, {
|
|
493
|
+
inner: {
|
|
494
|
+
case: "cancelOrder",
|
|
495
|
+
value: create(proto.CancelOrderSchema, { orderId: BigInt(a.orderId) }),
|
|
496
|
+
},
|
|
497
|
+
});
|
|
555
498
|
});
|
|
556
499
|
|
|
557
|
-
const action
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
actions: subactions,
|
|
566
|
-
},
|
|
567
|
-
},
|
|
568
|
-
};
|
|
500
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
501
|
+
case: "atomic",
|
|
502
|
+
value: create(proto.AtomicSchema, {
|
|
503
|
+
sessionId: BigInt(params.sessionId),
|
|
504
|
+
accountId: params.accountId, // optional
|
|
505
|
+
actions: subactions,
|
|
506
|
+
}),
|
|
507
|
+
});
|
|
569
508
|
|
|
570
509
|
const resp = await sendAction(
|
|
571
|
-
|
|
510
|
+
serverUrl,
|
|
572
511
|
(m) => sessionSign(signFn, m),
|
|
573
512
|
action,
|
|
574
513
|
"execute atomic action",
|
|
575
514
|
);
|
|
576
|
-
if (resp.kind
|
|
577
|
-
return
|
|
515
|
+
if (resp.kind?.case === "atomic") {
|
|
516
|
+
return {
|
|
517
|
+
actionId: resp.actionId,
|
|
518
|
+
results: resp.kind.value.results,
|
|
519
|
+
};
|
|
578
520
|
}
|
|
579
|
-
throw new Error(`Unexpected receipt kind ${resp.kind
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
export async function atomic(
|
|
583
|
-
serverUrl: string,
|
|
584
|
-
signFn: (message: Uint8Array) => Promise<Uint8Array>,
|
|
585
|
-
currentTimestamp: bigint,
|
|
586
|
-
nonce: number,
|
|
587
|
-
params: {
|
|
588
|
-
sessionId: BigIntValue;
|
|
589
|
-
accountId?: number;
|
|
590
|
-
actions: AtomicSubaction[];
|
|
591
|
-
},
|
|
592
|
-
): Promise<proto.Receipt_AtomicResult> {
|
|
593
|
-
return atomicImpl(
|
|
594
|
-
makeSendHttp(serverUrl),
|
|
595
|
-
signFn,
|
|
596
|
-
currentTimestamp,
|
|
597
|
-
nonce,
|
|
598
|
-
params,
|
|
599
|
-
);
|
|
521
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
600
522
|
}
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* For testing purposes
|
|
604
|
-
*/
|
|
605
|
-
export const _private = {
|
|
606
|
-
createSessionImpl,
|
|
607
|
-
revokeSessionImpl,
|
|
608
|
-
withdrawImpl,
|
|
609
|
-
placeOrderImpl,
|
|
610
|
-
cancelOrderImpl,
|
|
611
|
-
transferImpl,
|
|
612
|
-
atomicImpl,
|
|
613
|
-
};
|