@n1xyz/nord-ts 0.1.10 → 0.2.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/dist/actions.d.ts +3 -4
- package/dist/actions.js +4 -6
- package/dist/client/Nord.d.ts +28 -3
- package/dist/client/Nord.js +52 -1
- package/dist/client/NordAdmin.js +2 -2
- package/dist/client/NordUser.d.ts +27 -12
- package/dist/client/NordUser.js +70 -43
- package/dist/gen/nord_pb.d.ts +8 -0
- package/dist/gen/nord_pb.js +8 -0
- package/dist/gen/openapi.d.ts +222 -33
- package/dist/types.d.ts +27 -13
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +4 -1
- package/dist/websocket/NordWebSocketClient.js +3 -3
- package/dist/websocket/Subscriber.d.ts +2 -2
- package/package.json +2 -2
package/dist/actions.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { paths } from "./gen/openapi";
|
|
|
4
4
|
import { Client } from "openapi-fetch";
|
|
5
5
|
import { FillMode, Side, QuoteSize } from "./types";
|
|
6
6
|
import { BigIntValue } from "./utils";
|
|
7
|
-
import { PublicKey
|
|
7
|
+
import { PublicKey } from "@solana/web3.js";
|
|
8
8
|
type ReceiptKind = NonNullable<proto.Receipt["kind"]>;
|
|
9
9
|
type ExtractReceiptKind<K extends ReceiptKind["case"]> = Extract<ReceiptKind, {
|
|
10
10
|
case: K;
|
|
@@ -16,7 +16,7 @@ export declare function expectReceiptKind<K extends ReceiptKind["case"]>(receipt
|
|
|
16
16
|
export declare function createAction(currentTimestamp: bigint, nonce: number, kind: proto.Action["kind"]): proto.Action;
|
|
17
17
|
export declare function sendAction(client: Client<paths>, makeSignedMessage: (message: Uint8Array) => Promise<Uint8Array>, action: proto.Action): Promise<proto.Receipt>;
|
|
18
18
|
export declare function prepareAction(action: proto.Action, makeSignedMessage: (message: Uint8Array) => Promise<Uint8Array>): Promise<Uint8Array<ArrayBufferLike>>;
|
|
19
|
-
export declare function createSession(client: Client<paths>,
|
|
19
|
+
export declare function createSession(client: Client<paths>, signMessage: (_: Uint8Array) => Promise<Uint8Array>, currentTimestamp: bigint, nonce: number, params: {
|
|
20
20
|
userPubkey: PublicKey;
|
|
21
21
|
sessionPubkey: PublicKey;
|
|
22
22
|
expiryTimestamp?: bigint;
|
|
@@ -24,9 +24,8 @@ export declare function createSession(client: Client<paths>, signTransaction: (t
|
|
|
24
24
|
actionId: bigint;
|
|
25
25
|
sessionId: bigint;
|
|
26
26
|
}>;
|
|
27
|
-
export declare function revokeSession(client: Client<paths>,
|
|
27
|
+
export declare function revokeSession(client: Client<paths>, signMessage: (_: Uint8Array) => Promise<Uint8Array>, currentTimestamp: bigint, nonce: number, params: {
|
|
28
28
|
sessionId: BigIntValue;
|
|
29
|
-
userPubkey: PublicKey;
|
|
30
29
|
}): Promise<{
|
|
31
30
|
actionId: bigint;
|
|
32
31
|
}>;
|
package/dist/actions.js
CHANGED
|
@@ -70,7 +70,7 @@ export async function prepareAction(action, makeSignedMessage) {
|
|
|
70
70
|
}
|
|
71
71
|
return body;
|
|
72
72
|
}
|
|
73
|
-
export async function createSession(client,
|
|
73
|
+
export async function createSession(client, signMessage, currentTimestamp, nonce, params) {
|
|
74
74
|
let expiry = 0n;
|
|
75
75
|
if (params.expiryTimestamp !== undefined) {
|
|
76
76
|
expiry = params.expiryTimestamp;
|
|
@@ -92,8 +92,7 @@ export async function createSession(client, signTransaction, currentTimestamp, n
|
|
|
92
92
|
...payload,
|
|
93
93
|
...(await signUserPayload({
|
|
94
94
|
payload,
|
|
95
|
-
|
|
96
|
-
signTransaction,
|
|
95
|
+
signMessage,
|
|
97
96
|
})),
|
|
98
97
|
]);
|
|
99
98
|
}, action);
|
|
@@ -107,7 +106,7 @@ export async function createSession(client, signTransaction, currentTimestamp, n
|
|
|
107
106
|
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
|
-
export async function revokeSession(client,
|
|
109
|
+
export async function revokeSession(client, signMessage, currentTimestamp, nonce, params) {
|
|
111
110
|
const action = createAction(currentTimestamp, nonce, {
|
|
112
111
|
case: "revokeSession",
|
|
113
112
|
value: create(proto.Action_RevokeSessionSchema, {
|
|
@@ -119,8 +118,7 @@ export async function revokeSession(client, signTransaction, currentTimestamp, n
|
|
|
119
118
|
...payload,
|
|
120
119
|
...(await signUserPayload({
|
|
121
120
|
payload,
|
|
122
|
-
|
|
123
|
-
signTransaction,
|
|
121
|
+
signMessage,
|
|
124
122
|
})),
|
|
125
123
|
]);
|
|
126
124
|
}, action);
|
package/dist/client/Nord.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Connection, PublicKey } from "@solana/web3.js";
|
|
|
3
3
|
import { EventEmitter } from "events";
|
|
4
4
|
import { Client } from "openapi-fetch";
|
|
5
5
|
import type { paths } from "../gen/openapi.ts";
|
|
6
|
-
import { Account,
|
|
6
|
+
import { Account, AccountPnlInfoPage, PagedQuery, ActionResponse, MarketsInfo, Market, MarketStats, NordConfig, OrderbookQuery, OrderbookResponse, FeeTierConfig, Token, TradesResponse, User, AccountTriggerInfo, TriggerHistoryPage, WithdrawalHistoryPage, FeeTierId, AccountFeeTierPage, PageResultStringOrderInfo, PageResultStringTrade, OrderInfoFromApi, TokenStats, FillRole, AdminInfo, AccountVolumeInfo, GetAccountVolumeQuery, PreviousMarketPrice } from "../types";
|
|
7
7
|
import { NordWebSocketClient } from "../websocket/index";
|
|
8
8
|
import { OrderbookSubscription, TradeSubscription } from "../websocket/Subscriber";
|
|
9
9
|
/**
|
|
@@ -302,7 +302,7 @@ export declare class Nord {
|
|
|
302
302
|
* @returns Page of PnL entries ordered from latest to oldest
|
|
303
303
|
* @throws {NordError} If the request fails
|
|
304
304
|
*/
|
|
305
|
-
getAccountPnl(accountId: number, { since, until, startInclusive, pageSize, }?: Readonly<Partial<
|
|
305
|
+
getAccountPnl(accountId: number, { since, until, startInclusive, pageSize, }?: Readonly<Partial<PagedQuery>>): Promise<AccountPnlInfoPage>;
|
|
306
306
|
/**
|
|
307
307
|
* Get market statistics (alias for marketsStats for backward compatibility)
|
|
308
308
|
*
|
|
@@ -328,6 +328,18 @@ export declare class Nord {
|
|
|
328
328
|
feeKind: FillRole;
|
|
329
329
|
accountId: number;
|
|
330
330
|
}>): Promise<number>;
|
|
331
|
+
/**
|
|
332
|
+
* Fetch the latest available market price at or before the given timestamp.
|
|
333
|
+
*
|
|
334
|
+
* @param marketId - Market identifier
|
|
335
|
+
* @param atOrBefore - RFC3339 timestamp to look back from (returns the latest price at or before this time)
|
|
336
|
+
* @returns Previous market price record; price is `null` if no trades exist at or before `at`
|
|
337
|
+
* @throws {NordError} If the request fails
|
|
338
|
+
*/
|
|
339
|
+
getPrevMarketPrice({ marketId, atOrBefore, }: Readonly<{
|
|
340
|
+
marketId: number;
|
|
341
|
+
atOrBefore: string;
|
|
342
|
+
}>): Promise<PreviousMarketPrice>;
|
|
331
343
|
/**
|
|
332
344
|
* Fetch token statistics such as index price and oracle metadata.
|
|
333
345
|
*
|
|
@@ -384,7 +396,20 @@ export declare class Nord {
|
|
|
384
396
|
* @param startInclusive - Pagination cursor to resume from
|
|
385
397
|
* @throws {NordError} If no account can be resolved or the request fails.
|
|
386
398
|
*/
|
|
387
|
-
getAccountTriggerHistory({ accountId, since, until, pageSize, startInclusive, }: Readonly<
|
|
399
|
+
getAccountTriggerHistory({ accountId, since, until, pageSize, startInclusive, }: Readonly<PagedQuery & {
|
|
388
400
|
accountId?: number;
|
|
389
401
|
}>): Promise<TriggerHistoryPage>;
|
|
402
|
+
/**
|
|
403
|
+
* Fetch withdrawal history for an account.
|
|
404
|
+
*
|
|
405
|
+
* @param accountId - Account identifier owning the withdrawals
|
|
406
|
+
* @param since - RFC3339 timestamp to start from (inclusive)
|
|
407
|
+
* @param until - RFC3339 timestamp to end at (exclusive)
|
|
408
|
+
* @param pageSize - Maximum number of entries to return
|
|
409
|
+
* @param startInclusive - Pagination cursor to resume from
|
|
410
|
+
* @throws {NordError} If no account can be resolved or the request fails.
|
|
411
|
+
*/
|
|
412
|
+
getAccountWithdrawalHistory({ accountId, since, until, pageSize, startInclusive, }: Readonly<PagedQuery & {
|
|
413
|
+
accountId?: number;
|
|
414
|
+
}>): Promise<WithdrawalHistoryPage>;
|
|
390
415
|
}
|
package/dist/client/Nord.js
CHANGED
|
@@ -265,7 +265,7 @@ export class Nord {
|
|
|
265
265
|
deltas: [symbol],
|
|
266
266
|
});
|
|
267
267
|
const handleDelta = (update) => {
|
|
268
|
-
if (update.
|
|
268
|
+
if (update.market_symbol !== symbol) {
|
|
269
269
|
return;
|
|
270
270
|
}
|
|
271
271
|
subscription.emit("message", update);
|
|
@@ -592,6 +592,24 @@ export class Nord {
|
|
|
592
592
|
},
|
|
593
593
|
});
|
|
594
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* Fetch the latest available market price at or before the given timestamp.
|
|
597
|
+
*
|
|
598
|
+
* @param marketId - Market identifier
|
|
599
|
+
* @param atOrBefore - RFC3339 timestamp to look back from (returns the latest price at or before this time)
|
|
600
|
+
* @returns Previous market price record; price is `null` if no trades exist at or before `at`
|
|
601
|
+
* @throws {NordError} If the request fails
|
|
602
|
+
*/
|
|
603
|
+
async getPrevMarketPrice({ marketId, atOrBefore, }) {
|
|
604
|
+
return await this.GET("/market/{market_id}/price/prev", {
|
|
605
|
+
params: {
|
|
606
|
+
path: { market_id: marketId },
|
|
607
|
+
query: {
|
|
608
|
+
atOrBefore,
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
}
|
|
595
613
|
/**
|
|
596
614
|
* Fetch token statistics such as index price and oracle metadata.
|
|
597
615
|
*
|
|
@@ -705,4 +723,37 @@ export class Nord {
|
|
|
705
723
|
});
|
|
706
724
|
}
|
|
707
725
|
}
|
|
726
|
+
/**
|
|
727
|
+
* Fetch withdrawal history for an account.
|
|
728
|
+
*
|
|
729
|
+
* @param accountId - Account identifier owning the withdrawals
|
|
730
|
+
* @param since - RFC3339 timestamp to start from (inclusive)
|
|
731
|
+
* @param until - RFC3339 timestamp to end at (exclusive)
|
|
732
|
+
* @param pageSize - Maximum number of entries to return
|
|
733
|
+
* @param startInclusive - Pagination cursor to resume from
|
|
734
|
+
* @throws {NordError} If no account can be resolved or the request fails.
|
|
735
|
+
*/
|
|
736
|
+
async getAccountWithdrawalHistory({ accountId, since, until, pageSize, startInclusive, }) {
|
|
737
|
+
if (accountId == null) {
|
|
738
|
+
throw new NordError("Account ID is undefined. Make sure to call updateAccountId() before requesting withdrawal history.");
|
|
739
|
+
}
|
|
740
|
+
try {
|
|
741
|
+
return await this.GET("/account/{account_id}/history/withdrawal", {
|
|
742
|
+
params: {
|
|
743
|
+
path: { account_id: accountId },
|
|
744
|
+
query: {
|
|
745
|
+
since,
|
|
746
|
+
until,
|
|
747
|
+
pageSize,
|
|
748
|
+
startInclusive,
|
|
749
|
+
},
|
|
750
|
+
},
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
catch (error) {
|
|
754
|
+
throw new NordError("Failed to fetch account withdrawal history", {
|
|
755
|
+
cause: error,
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
}
|
|
708
759
|
}
|
package/dist/client/NordAdmin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { create } from "@bufbuild/protobuf";
|
|
2
2
|
import * as proto from "../gen/nord_pb";
|
|
3
|
-
import { decodeHex,
|
|
3
|
+
import { decodeHex, signAdminPayload } from "../utils";
|
|
4
4
|
import { createAction, sendAction, expectReceiptKind } from "../actions";
|
|
5
5
|
import { NordError } from "../error";
|
|
6
6
|
// NOTE: keep in sync with `acl.rs`.
|
|
@@ -49,7 +49,7 @@ export class NordAdmin {
|
|
|
49
49
|
const timestamp = await this.nord.getTimestamp();
|
|
50
50
|
const action = createAction(timestamp, 0, kind);
|
|
51
51
|
return sendAction(this.nord.httpClient, async (xs) => {
|
|
52
|
-
const signature = await
|
|
52
|
+
const signature = await signAdminPayload({
|
|
53
53
|
payload: xs,
|
|
54
54
|
user: this.admin,
|
|
55
55
|
signTransaction: this.signFn,
|
|
@@ -33,9 +33,10 @@ export interface UserAtomicSubaction {
|
|
|
33
33
|
* User class for interacting with the Nord protocol
|
|
34
34
|
*/
|
|
35
35
|
export declare class NordUser {
|
|
36
|
+
private readonly signSessionMessage;
|
|
37
|
+
private readonly signMessage;
|
|
38
|
+
private readonly signTransaction;
|
|
36
39
|
readonly nord: Nord;
|
|
37
|
-
readonly sessionSignFn: (message: Uint8Array) => Promise<Uint8Array>;
|
|
38
|
-
readonly transactionSignFn: (tx: Transaction) => Promise<Transaction>;
|
|
39
40
|
sessionId?: bigint;
|
|
40
41
|
sessionPubKey: PublicKey;
|
|
41
42
|
publicKey: PublicKey;
|
|
@@ -49,6 +50,17 @@ export declare class NordUser {
|
|
|
49
50
|
symbol: string;
|
|
50
51
|
}[];
|
|
51
52
|
};
|
|
53
|
+
orders: {
|
|
54
|
+
[key: string]: {
|
|
55
|
+
orderId: string;
|
|
56
|
+
marketId: number;
|
|
57
|
+
side: "ask" | "bid";
|
|
58
|
+
size: number;
|
|
59
|
+
price: number;
|
|
60
|
+
originalOrderSize: number;
|
|
61
|
+
clientOrderId: number | null;
|
|
62
|
+
}[];
|
|
63
|
+
};
|
|
52
64
|
/** User positions by account ID */
|
|
53
65
|
positions: {
|
|
54
66
|
[key: string]: {
|
|
@@ -82,25 +94,28 @@ export declare class NordUser {
|
|
|
82
94
|
accountIds?: number[];
|
|
83
95
|
/** SPL token information */
|
|
84
96
|
splTokenInfos: SPLTokenInfo[];
|
|
97
|
+
private constructor();
|
|
85
98
|
/**
|
|
86
99
|
* Create a new NordUser instance
|
|
87
100
|
*
|
|
88
101
|
* @param nord - Nord client instance
|
|
89
|
-
* @param
|
|
90
|
-
* @param transactionSignFn - Function to sign transactions with the user's wallet (optional)
|
|
91
|
-
* @param sessionId - Existing session identifier
|
|
102
|
+
* @param walletPubkey - Wallet public key
|
|
92
103
|
* @param sessionPubKey - Session public key
|
|
93
|
-
* @param
|
|
104
|
+
* @param sessionId - Existing session identifier, if known. Otherwise, pass nothing and call `refreshSession` to fetch a new session.
|
|
105
|
+
* @param signMessageFn - Function to sign the given UTF-8 string with the user's wallet. Typically just your wallet's `signMessage` method.
|
|
106
|
+
* @param signTransactionFn - Function to sign transactions with the user's wallet. Typically just your wallet's `signTransaction` method.
|
|
107
|
+
* @param signSessionFn - Function to sign messages with the provided `sessionPubKey`
|
|
94
108
|
* @throws {NordError} If required parameters are missing
|
|
95
109
|
*/
|
|
96
|
-
|
|
110
|
+
static new({ nord, walletPubkey, sessionPubkey, sessionId, signMessageFn, signTransactionFn, signSessionFn, }: Readonly<{
|
|
97
111
|
nord: Nord;
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
signSessionFn: (rawMessage: Uint8Array) => Promise<Uint8Array>;
|
|
113
|
+
signMessageFn: (utf8Message: Uint8Array) => Promise<Uint8Array>;
|
|
114
|
+
signTransactionFn: (tx: Transaction) => Promise<Transaction>;
|
|
100
115
|
sessionId?: bigint;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}>)
|
|
116
|
+
sessionPubkey: Uint8Array;
|
|
117
|
+
walletPubkey: PublicKey;
|
|
118
|
+
}>): Promise<NordUser>;
|
|
104
119
|
/**
|
|
105
120
|
* Create a NordUser from a private key
|
|
106
121
|
*
|
package/dist/client/NordUser.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, } from "@solana/spl-token";
|
|
2
|
-
import { PublicKey, Transaction } from "@solana/web3.js";
|
|
2
|
+
import { PublicKey, Keypair, Transaction } from "@solana/web3.js";
|
|
3
3
|
import * as ed from "@noble/ed25519";
|
|
4
4
|
import { floatToScaledBigIntLossy } from "@n1xyz/proton";
|
|
5
5
|
import { Side, TriggerKind, fillModeToProtoFillMode, } from "../types";
|
|
6
6
|
import * as proto from "../gen/nord_pb";
|
|
7
|
-
import {
|
|
7
|
+
import { assert, findMarket, findToken, optExpect, keypairFromPrivateKey, toScaledU64, } from "../utils";
|
|
8
8
|
import { create } from "@bufbuild/protobuf";
|
|
9
9
|
import { createSession, revokeSession, atomic, expectReceiptKind, createAction, sendAction, } from "../actions";
|
|
10
10
|
import { NordError } from "../error";
|
|
@@ -12,9 +12,10 @@ import { NordError } from "../error";
|
|
|
12
12
|
* User class for interacting with the Nord protocol
|
|
13
13
|
*/
|
|
14
14
|
export class NordUser {
|
|
15
|
+
signSessionMessage;
|
|
16
|
+
signMessage;
|
|
17
|
+
signTransaction;
|
|
15
18
|
nord;
|
|
16
|
-
sessionSignFn;
|
|
17
|
-
transactionSignFn;
|
|
18
19
|
sessionId;
|
|
19
20
|
sessionPubKey;
|
|
20
21
|
publicKey;
|
|
@@ -22,6 +23,7 @@ export class NordUser {
|
|
|
22
23
|
nonce = 0;
|
|
23
24
|
/** User balances by token symbol */
|
|
24
25
|
balances = {};
|
|
26
|
+
orders = {};
|
|
25
27
|
/** User positions by account ID */
|
|
26
28
|
positions = {};
|
|
27
29
|
/** User margins by account ID */
|
|
@@ -30,24 +32,14 @@ export class NordUser {
|
|
|
30
32
|
accountIds;
|
|
31
33
|
/** SPL token information */
|
|
32
34
|
splTokenInfos = [];
|
|
33
|
-
|
|
34
|
-
* Create a new NordUser instance
|
|
35
|
-
*
|
|
36
|
-
* @param nord - Nord client instance
|
|
37
|
-
* @param sessionSignFn - Function to sign messages with the user's session key
|
|
38
|
-
* @param transactionSignFn - Function to sign transactions with the user's wallet (optional)
|
|
39
|
-
* @param sessionId - Existing session identifier
|
|
40
|
-
* @param sessionPubKey - Session public key
|
|
41
|
-
* @param publicKey - Wallet public key
|
|
42
|
-
* @throws {NordError} If required parameters are missing
|
|
43
|
-
*/
|
|
44
|
-
constructor({ nord, sessionSignFn, transactionSignFn, sessionId, sessionPubKey, publicKey, }) {
|
|
35
|
+
constructor({ nord, walletPubkey, sessionPubkey, sessionId, signMessageFn, signTransactionFn, signSessionFn, }) {
|
|
45
36
|
this.nord = nord;
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
37
|
+
this.signSessionMessage = signSessionFn;
|
|
38
|
+
this.signMessage = signMessageFn;
|
|
39
|
+
this.signTransaction = signTransactionFn;
|
|
48
40
|
this.sessionId = sessionId;
|
|
49
|
-
this.sessionPubKey = new PublicKey(
|
|
50
|
-
this.publicKey =
|
|
41
|
+
this.sessionPubKey = new PublicKey(sessionPubkey);
|
|
42
|
+
this.publicKey = walletPubkey;
|
|
51
43
|
// Convert tokens from info endpoint to SPLTokenInfo
|
|
52
44
|
if (this.nord.tokens && this.nord.tokens.length > 0) {
|
|
53
45
|
this.splTokenInfos = this.nord.tokens.map((token) => ({
|
|
@@ -58,6 +50,29 @@ export class NordUser {
|
|
|
58
50
|
}));
|
|
59
51
|
}
|
|
60
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a new NordUser instance
|
|
55
|
+
*
|
|
56
|
+
* @param nord - Nord client instance
|
|
57
|
+
* @param walletPubkey - Wallet public key
|
|
58
|
+
* @param sessionPubKey - Session public key
|
|
59
|
+
* @param sessionId - Existing session identifier, if known. Otherwise, pass nothing and call `refreshSession` to fetch a new session.
|
|
60
|
+
* @param signMessageFn - Function to sign the given UTF-8 string with the user's wallet. Typically just your wallet's `signMessage` method.
|
|
61
|
+
* @param signTransactionFn - Function to sign transactions with the user's wallet. Typically just your wallet's `signTransaction` method.
|
|
62
|
+
* @param signSessionFn - Function to sign messages with the provided `sessionPubKey`
|
|
63
|
+
* @throws {NordError} If required parameters are missing
|
|
64
|
+
*/
|
|
65
|
+
static async new({ nord, walletPubkey, sessionPubkey, sessionId, signMessageFn, signTransactionFn, signSessionFn, }) {
|
|
66
|
+
return new NordUser({
|
|
67
|
+
nord,
|
|
68
|
+
walletPubkey,
|
|
69
|
+
sessionPubkey,
|
|
70
|
+
sessionId,
|
|
71
|
+
signMessageFn,
|
|
72
|
+
signTransactionFn,
|
|
73
|
+
signSessionFn,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
61
76
|
/**
|
|
62
77
|
* Create a NordUser from a private key
|
|
63
78
|
*
|
|
@@ -68,22 +83,22 @@ export class NordUser {
|
|
|
68
83
|
*/
|
|
69
84
|
static fromPrivateKey(nord, privateKey) {
|
|
70
85
|
try {
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const sessionSignFn = async (message) => {
|
|
74
|
-
// Use ed25519 to sign the message
|
|
75
|
-
return ed.sign(message, keypair.secretKey.slice(0, 32));
|
|
76
|
-
};
|
|
77
|
-
const transactionSignFn = async (tx) => {
|
|
78
|
-
tx.sign(keypair);
|
|
79
|
-
return tx;
|
|
80
|
-
};
|
|
86
|
+
const wallet = keypairFromPrivateKey(privateKey);
|
|
87
|
+
const sessionKey = Keypair.generate();
|
|
81
88
|
return new NordUser({
|
|
82
89
|
nord,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
walletPubkey: wallet.publicKey,
|
|
91
|
+
sessionPubkey: sessionKey.publicKey.toBytes(),
|
|
92
|
+
signTransactionFn: async (tx) => {
|
|
93
|
+
tx.sign(wallet);
|
|
94
|
+
return tx;
|
|
95
|
+
},
|
|
96
|
+
signMessageFn: async (xs) => {
|
|
97
|
+
return await ed.signAsync(xs, wallet.secretKey.slice(0, 32));
|
|
98
|
+
},
|
|
99
|
+
signSessionFn: async (xs) => {
|
|
100
|
+
return await ed.signAsync(xs, sessionKey.secretKey.slice(0, 32));
|
|
101
|
+
},
|
|
87
102
|
});
|
|
88
103
|
}
|
|
89
104
|
catch (error) {
|
|
@@ -171,7 +186,7 @@ export class NordUser {
|
|
|
171
186
|
tx.add(ix);
|
|
172
187
|
tx.recentBlockhash = blockhash;
|
|
173
188
|
tx.feePayer = payer;
|
|
174
|
-
const signedTx = await this.
|
|
189
|
+
const signedTx = await this.signTransaction(tx);
|
|
175
190
|
signedTx.partialSign(extraSigner);
|
|
176
191
|
const signature = await this.nord.solanaConnection.sendRawTransaction(signedTx.serialize(), sendOptions);
|
|
177
192
|
return {
|
|
@@ -193,7 +208,7 @@ export class NordUser {
|
|
|
193
208
|
}
|
|
194
209
|
async submitSessionAction(kind) {
|
|
195
210
|
return this.submitSignedAction(kind, async (message) => {
|
|
196
|
-
const signature = await this.
|
|
211
|
+
const signature = await this.signSessionMessage(message);
|
|
197
212
|
const signed = new Uint8Array(message.length + signature.length);
|
|
198
213
|
signed.set(message);
|
|
199
214
|
signed.set(signature, message.length);
|
|
@@ -230,8 +245,7 @@ export class NordUser {
|
|
|
230
245
|
async fetchInfo() {
|
|
231
246
|
if (this.accountIds !== undefined) {
|
|
232
247
|
const accountsData = await Promise.all(this.accountIds.map(async (accountId) => {
|
|
233
|
-
const
|
|
234
|
-
const accountData = (await response.json());
|
|
248
|
+
const accountData = await this.nord.getAccount(accountId);
|
|
235
249
|
// Ensure we have the correct accountId
|
|
236
250
|
return {
|
|
237
251
|
...accountData,
|
|
@@ -239,6 +253,15 @@ export class NordUser {
|
|
|
239
253
|
};
|
|
240
254
|
}));
|
|
241
255
|
for (const accountData of accountsData) {
|
|
256
|
+
this.orders[accountData.accountId] = accountData.orders.map((o) => ({
|
|
257
|
+
orderId: o.orderId,
|
|
258
|
+
marketId: o.marketId,
|
|
259
|
+
side: o.side,
|
|
260
|
+
size: o.size,
|
|
261
|
+
price: o.price,
|
|
262
|
+
originalOrderSize: o.originalOrderSize,
|
|
263
|
+
clientOrderId: o.clientOrderId ?? null,
|
|
264
|
+
}));
|
|
242
265
|
// Process balances
|
|
243
266
|
this.balances[accountData.accountId] = [];
|
|
244
267
|
for (const balance of accountData.balances) {
|
|
@@ -249,7 +272,12 @@ export class NordUser {
|
|
|
249
272
|
});
|
|
250
273
|
}
|
|
251
274
|
// Process positions
|
|
252
|
-
this.positions[accountData.accountId] = accountData.positions
|
|
275
|
+
this.positions[accountData.accountId] = accountData.positions.map((p) => ({
|
|
276
|
+
marketId: p.marketId,
|
|
277
|
+
openOrders: p.openOrders,
|
|
278
|
+
actionId: p.actionId,
|
|
279
|
+
...(p.perp != null ? { perp: p.perp } : {}),
|
|
280
|
+
}));
|
|
253
281
|
// Process margins
|
|
254
282
|
this.margins[accountData.accountId] = accountData.margins;
|
|
255
283
|
}
|
|
@@ -261,7 +289,7 @@ export class NordUser {
|
|
|
261
289
|
* @throws {NordError} If the operation fails
|
|
262
290
|
*/
|
|
263
291
|
async refreshSession() {
|
|
264
|
-
const result = await createSession(this.nord.httpClient, this.
|
|
292
|
+
const result = await createSession(this.nord.httpClient, this.signMessage, await this.nord.getTimestamp(), this.getNonce(), {
|
|
265
293
|
userPubkey: this.publicKey,
|
|
266
294
|
sessionPubkey: this.sessionPubKey,
|
|
267
295
|
});
|
|
@@ -275,8 +303,7 @@ export class NordUser {
|
|
|
275
303
|
*/
|
|
276
304
|
async revokeSession(sessionId) {
|
|
277
305
|
try {
|
|
278
|
-
await revokeSession(this.nord.httpClient, this.
|
|
279
|
-
userPubkey: this.publicKey,
|
|
306
|
+
await revokeSession(this.nord.httpClient, this.signMessage, await this.nord.getTimestamp(), this.getNonce(), {
|
|
280
307
|
sessionId,
|
|
281
308
|
});
|
|
282
309
|
}
|
|
@@ -600,7 +627,7 @@ export class NordUser {
|
|
|
600
627
|
orderId: act.orderId,
|
|
601
628
|
};
|
|
602
629
|
});
|
|
603
|
-
const result = await atomic(this.nord.httpClient, this.
|
|
630
|
+
const result = await atomic(this.nord.httpClient, this.signSessionMessage, await this.nord.getTimestamp(), this.getNonce(), {
|
|
604
631
|
sessionId: optExpect(this.sessionId, "No session"),
|
|
605
632
|
accountId: accountId,
|
|
606
633
|
actions: apiActions,
|
package/dist/gen/nord_pb.d.ts
CHANGED
|
@@ -4238,6 +4238,9 @@ export declare enum Error {
|
|
|
4238
4238
|
POSITION_STATE_ORDER_SIDE = 205,
|
|
4239
4239
|
/**
|
|
4240
4240
|
* 1100_1110
|
|
4241
|
+
* Maximuma size of single position exceeded.
|
|
4242
|
+
* See `POSITION_SIZE_LIMIT` constant default limit for exacat value and
|
|
4243
|
+
* details.
|
|
4241
4244
|
*
|
|
4242
4245
|
* @generated from enum value: POSITION_SIZE_LIMIT = 206;
|
|
4243
4246
|
*/
|
|
@@ -4270,6 +4273,9 @@ export declare enum Error {
|
|
|
4270
4273
|
SIGNATURE_VERIFICATION_INVALID_LENGTH = 219,
|
|
4271
4274
|
/**
|
|
4272
4275
|
* 11011_000
|
|
4276
|
+
* Error prefix which indicates that some actions cannot to be executed,
|
|
4277
|
+
* if they move account into unhealthy(liquidatable) state
|
|
4278
|
+
* or if liquidaiton handling action as parameterized cannot be executed
|
|
4273
4279
|
*
|
|
4274
4280
|
* @generated from enum value: RISK = 224;
|
|
4275
4281
|
*/
|
|
@@ -4287,6 +4293,8 @@ export declare enum Error {
|
|
|
4287
4293
|
*/
|
|
4288
4294
|
RISK_OMF_LESS_THAN_OR_EQUAL_CMF = 227,
|
|
4289
4295
|
/**
|
|
4296
|
+
* See `OMF < CMF` rule in MARKETS.md.
|
|
4297
|
+
*
|
|
4290
4298
|
* @generated from enum value: RISK_TRADE_OMF_LESS_THAN_OR_EQUAL_CMF = 229;
|
|
4291
4299
|
*/
|
|
4292
4300
|
RISK_TRADE_OMF_LESS_THAN_OR_EQUAL_CMF = 229,
|
package/dist/gen/nord_pb.js
CHANGED
|
@@ -873,6 +873,9 @@ export var Error;
|
|
|
873
873
|
Error[Error["POSITION_STATE_ORDER_SIDE"] = 205] = "POSITION_STATE_ORDER_SIDE";
|
|
874
874
|
/**
|
|
875
875
|
* 1100_1110
|
|
876
|
+
* Maximuma size of single position exceeded.
|
|
877
|
+
* See `POSITION_SIZE_LIMIT` constant default limit for exacat value and
|
|
878
|
+
* details.
|
|
876
879
|
*
|
|
877
880
|
* @generated from enum value: POSITION_SIZE_LIMIT = 206;
|
|
878
881
|
*/
|
|
@@ -905,6 +908,9 @@ export var Error;
|
|
|
905
908
|
Error[Error["SIGNATURE_VERIFICATION_INVALID_LENGTH"] = 219] = "SIGNATURE_VERIFICATION_INVALID_LENGTH";
|
|
906
909
|
/**
|
|
907
910
|
* 11011_000
|
|
911
|
+
* Error prefix which indicates that some actions cannot to be executed,
|
|
912
|
+
* if they move account into unhealthy(liquidatable) state
|
|
913
|
+
* or if liquidaiton handling action as parameterized cannot be executed
|
|
908
914
|
*
|
|
909
915
|
* @generated from enum value: RISK = 224;
|
|
910
916
|
*/
|
|
@@ -922,6 +928,8 @@ export var Error;
|
|
|
922
928
|
*/
|
|
923
929
|
Error[Error["RISK_OMF_LESS_THAN_OR_EQUAL_CMF"] = 227] = "RISK_OMF_LESS_THAN_OR_EQUAL_CMF";
|
|
924
930
|
/**
|
|
931
|
+
* See `OMF < CMF` rule in MARKETS.md.
|
|
932
|
+
*
|
|
925
933
|
* @generated from enum value: RISK_TRADE_OMF_LESS_THAN_OR_EQUAL_CMF = 229;
|
|
926
934
|
*/
|
|
927
935
|
Error[Error["RISK_TRADE_OMF_LESS_THAN_OR_EQUAL_CMF"] = 229] = "RISK_TRADE_OMF_LESS_THAN_OR_EQUAL_CMF";
|
package/dist/gen/openapi.d.ts
CHANGED
|
@@ -725,7 +725,44 @@ export interface paths {
|
|
|
725
725
|
[name: string]: unknown;
|
|
726
726
|
};
|
|
727
727
|
content: {
|
|
728
|
-
"application/json": components["schemas"]["
|
|
728
|
+
"application/json": components["schemas"]["PageResult_for_uint64_and_AccountPnlInfo"];
|
|
729
|
+
};
|
|
730
|
+
};
|
|
731
|
+
};
|
|
732
|
+
};
|
|
733
|
+
put?: never;
|
|
734
|
+
post?: never;
|
|
735
|
+
delete?: never;
|
|
736
|
+
options?: never;
|
|
737
|
+
head?: never;
|
|
738
|
+
patch?: never;
|
|
739
|
+
trace?: never;
|
|
740
|
+
};
|
|
741
|
+
"/account/{account_id}/pnl/history/PT1H": {
|
|
742
|
+
parameters: {
|
|
743
|
+
query?: never;
|
|
744
|
+
header?: never;
|
|
745
|
+
path?: never;
|
|
746
|
+
cookie?: never;
|
|
747
|
+
};
|
|
748
|
+
get: {
|
|
749
|
+
parameters: {
|
|
750
|
+
query?: never;
|
|
751
|
+
header?: never;
|
|
752
|
+
path: {
|
|
753
|
+
/** @description Account for which to retrieve PnL history */
|
|
754
|
+
account_id: number;
|
|
755
|
+
};
|
|
756
|
+
cookie?: never;
|
|
757
|
+
};
|
|
758
|
+
requestBody?: never;
|
|
759
|
+
responses: {
|
|
760
|
+
200: {
|
|
761
|
+
headers: {
|
|
762
|
+
[name: string]: unknown;
|
|
763
|
+
};
|
|
764
|
+
content: {
|
|
765
|
+
"application/json": components["schemas"]["AccountPnlHistInfo"][];
|
|
729
766
|
};
|
|
730
767
|
};
|
|
731
768
|
};
|
|
@@ -770,7 +807,7 @@ export interface paths {
|
|
|
770
807
|
[name: string]: unknown;
|
|
771
808
|
};
|
|
772
809
|
content: {
|
|
773
|
-
"application/json": components["schemas"]["
|
|
810
|
+
"application/json": components["schemas"]["PageResult_for_uint64_and_Trigger"];
|
|
774
811
|
};
|
|
775
812
|
};
|
|
776
813
|
};
|
|
@@ -1320,6 +1357,108 @@ export interface paths {
|
|
|
1320
1357
|
patch?: never;
|
|
1321
1358
|
trace?: never;
|
|
1322
1359
|
};
|
|
1360
|
+
"/market/{market_id}/price/prev": {
|
|
1361
|
+
parameters: {
|
|
1362
|
+
query?: never;
|
|
1363
|
+
header?: never;
|
|
1364
|
+
path?: never;
|
|
1365
|
+
cookie?: never;
|
|
1366
|
+
};
|
|
1367
|
+
/** @description Fetch the latest price for a market at or before a timestamp. */
|
|
1368
|
+
get: {
|
|
1369
|
+
parameters: {
|
|
1370
|
+
query: {
|
|
1371
|
+
atOrBefore: string;
|
|
1372
|
+
};
|
|
1373
|
+
header?: never;
|
|
1374
|
+
path: {
|
|
1375
|
+
market_id: number;
|
|
1376
|
+
};
|
|
1377
|
+
cookie?: never;
|
|
1378
|
+
};
|
|
1379
|
+
requestBody?: never;
|
|
1380
|
+
responses: {
|
|
1381
|
+
200: {
|
|
1382
|
+
headers: {
|
|
1383
|
+
[name: string]: unknown;
|
|
1384
|
+
};
|
|
1385
|
+
content: {
|
|
1386
|
+
"application/json": components["schemas"]["PreviousMarketPrice"];
|
|
1387
|
+
};
|
|
1388
|
+
};
|
|
1389
|
+
404: {
|
|
1390
|
+
headers: {
|
|
1391
|
+
[name: string]: unknown;
|
|
1392
|
+
};
|
|
1393
|
+
content: {
|
|
1394
|
+
"application/json": components["schemas"]["MarketNotFound"];
|
|
1395
|
+
};
|
|
1396
|
+
};
|
|
1397
|
+
};
|
|
1398
|
+
};
|
|
1399
|
+
put?: never;
|
|
1400
|
+
post?: never;
|
|
1401
|
+
delete?: never;
|
|
1402
|
+
options?: never;
|
|
1403
|
+
head?: never;
|
|
1404
|
+
patch?: never;
|
|
1405
|
+
trace?: never;
|
|
1406
|
+
};
|
|
1407
|
+
"/account/{account_id}/history/withdrawal": {
|
|
1408
|
+
parameters: {
|
|
1409
|
+
query?: never;
|
|
1410
|
+
header?: never;
|
|
1411
|
+
path?: never;
|
|
1412
|
+
cookie?: never;
|
|
1413
|
+
};
|
|
1414
|
+
/** @description Fetch full history of withdrawals for an account. */
|
|
1415
|
+
get: {
|
|
1416
|
+
parameters: {
|
|
1417
|
+
query?: {
|
|
1418
|
+
/** @description start with this timestamp (RFC3339); defaults to UNIX epoch start */
|
|
1419
|
+
since?: string;
|
|
1420
|
+
/** @description end with this timestamp (RFC3339); defaults to current date-time */
|
|
1421
|
+
until?: string;
|
|
1422
|
+
/** @description fetch results starting with this page; query starts with first entry if page isn't specified */
|
|
1423
|
+
startInclusive?: number | null;
|
|
1424
|
+
/** @description Query returns up to 50 trades in one go. */
|
|
1425
|
+
pageSize?: number | null;
|
|
1426
|
+
};
|
|
1427
|
+
header?: never;
|
|
1428
|
+
path: {
|
|
1429
|
+
/** @description Account ID for which to fetch withdrawal history. */
|
|
1430
|
+
account_id: number;
|
|
1431
|
+
};
|
|
1432
|
+
cookie?: never;
|
|
1433
|
+
};
|
|
1434
|
+
requestBody?: never;
|
|
1435
|
+
responses: {
|
|
1436
|
+
200: {
|
|
1437
|
+
headers: {
|
|
1438
|
+
[name: string]: unknown;
|
|
1439
|
+
};
|
|
1440
|
+
content: {
|
|
1441
|
+
"application/json": components["schemas"]["PageResult_for_uint64_and_Withdrawal"];
|
|
1442
|
+
};
|
|
1443
|
+
};
|
|
1444
|
+
404: {
|
|
1445
|
+
headers: {
|
|
1446
|
+
[name: string]: unknown;
|
|
1447
|
+
};
|
|
1448
|
+
content: {
|
|
1449
|
+
"application/json": components["schemas"]["UserNotFound"];
|
|
1450
|
+
};
|
|
1451
|
+
};
|
|
1452
|
+
};
|
|
1453
|
+
};
|
|
1454
|
+
put?: never;
|
|
1455
|
+
post?: never;
|
|
1456
|
+
delete?: never;
|
|
1457
|
+
options?: never;
|
|
1458
|
+
head?: never;
|
|
1459
|
+
patch?: never;
|
|
1460
|
+
trace?: never;
|
|
1461
|
+
};
|
|
1323
1462
|
"/tv": {
|
|
1324
1463
|
parameters: {
|
|
1325
1464
|
query?: never;
|
|
@@ -2331,7 +2470,9 @@ export interface components {
|
|
|
2331
2470
|
/** Format: double */
|
|
2332
2471
|
low24h: number;
|
|
2333
2472
|
/** Format: double */
|
|
2334
|
-
|
|
2473
|
+
close24h: number;
|
|
2474
|
+
/** Format: double */
|
|
2475
|
+
prevClose24h?: number | null;
|
|
2335
2476
|
perpStats?: components["schemas"]["PerpMarketStats"] | null;
|
|
2336
2477
|
};
|
|
2337
2478
|
PerpMarketStats: {
|
|
@@ -2529,7 +2670,7 @@ export interface components {
|
|
|
2529
2670
|
/** @description See `bankruptcy` in MARKETS.md. In general happens if account does not have enough weighted tokens to covert his debt and negative PnL. */
|
|
2530
2671
|
bankruptcy: boolean;
|
|
2531
2672
|
};
|
|
2532
|
-
|
|
2673
|
+
PagedQuery: {
|
|
2533
2674
|
/**
|
|
2534
2675
|
* @description start with this timestamp (RFC3339); defaults to UNIX epoch start
|
|
2535
2676
|
* @default null
|
|
@@ -2552,63 +2693,78 @@ export interface components {
|
|
|
2552
2693
|
*/
|
|
2553
2694
|
pageSize: number | null;
|
|
2554
2695
|
};
|
|
2555
|
-
|
|
2696
|
+
PageResult_for_uint64_and_AccountPnlInfo: {
|
|
2556
2697
|
/** @description Set of items for requested by query. */
|
|
2557
|
-
items: components["schemas"]["
|
|
2698
|
+
items: components["schemas"]["AccountPnlInfo"][];
|
|
2558
2699
|
/**
|
|
2559
2700
|
* Format: uint64
|
|
2560
2701
|
* @description If request contains more data, this is the id is set with which next request should be performed to get next page. If no more data, then it is undefined.
|
|
2561
2702
|
*/
|
|
2562
2703
|
nextStartInclusive?: number | null;
|
|
2563
2704
|
};
|
|
2564
|
-
|
|
2705
|
+
AccountPnlInfo: {
|
|
2565
2706
|
time: string;
|
|
2566
2707
|
/** Format: uint64 */
|
|
2567
2708
|
actionId: number;
|
|
2568
2709
|
/** Format: uint32 */
|
|
2569
2710
|
accountId: number;
|
|
2570
2711
|
/** Format: double */
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2712
|
+
pricePnlDelta: number;
|
|
2713
|
+
/** Format: double */
|
|
2714
|
+
fundingPnlDelta: number;
|
|
2574
2715
|
/**
|
|
2575
|
-
*
|
|
2576
|
-
* @
|
|
2716
|
+
* Format: double
|
|
2717
|
+
* @description Total PnL update
|
|
2577
2718
|
*/
|
|
2578
|
-
|
|
2719
|
+
pnl: number;
|
|
2720
|
+
};
|
|
2721
|
+
AccountPnlHistInfo: {
|
|
2722
|
+
/** @description Same time when funding is applied */
|
|
2723
|
+
time: string;
|
|
2724
|
+
/** Format: double */
|
|
2725
|
+
fundingPnl: number;
|
|
2579
2726
|
/**
|
|
2580
|
-
*
|
|
2581
|
-
* @
|
|
2727
|
+
* Format: double
|
|
2728
|
+
* @description in USDC, PnL from position price and price and trade price difference
|
|
2582
2729
|
*/
|
|
2583
|
-
|
|
2730
|
+
tradedPnl: number;
|
|
2584
2731
|
/**
|
|
2585
|
-
* Format:
|
|
2586
|
-
* @description
|
|
2732
|
+
* Format: double
|
|
2733
|
+
* @description Funding rate used to calculate this funding payment
|
|
2587
2734
|
*/
|
|
2588
|
-
|
|
2735
|
+
fundingRate: number;
|
|
2589
2736
|
/**
|
|
2590
|
-
* Format:
|
|
2591
|
-
* @description
|
|
2592
|
-
* @default null
|
|
2737
|
+
* Format: double
|
|
2738
|
+
* @description Size used to calculated funding payment
|
|
2593
2739
|
*/
|
|
2594
|
-
|
|
2740
|
+
fundingSize: number;
|
|
2741
|
+
/** @description Side on time of funding application. */
|
|
2742
|
+
side?: components["schemas"]["Side"] | null;
|
|
2743
|
+
/** Format: double */
|
|
2744
|
+
positionSizeTraded: number;
|
|
2745
|
+
market: components["schemas"]["MarketIdInfo"];
|
|
2746
|
+
};
|
|
2747
|
+
MarketIdInfo: {
|
|
2748
|
+
/** Format: uint32 */
|
|
2749
|
+
market_id: number;
|
|
2750
|
+
market_symbol: string;
|
|
2595
2751
|
};
|
|
2596
|
-
|
|
2752
|
+
PageResult_for_uint64_and_Trigger: {
|
|
2597
2753
|
/** @description Set of items for requested by query. */
|
|
2598
|
-
items: components["schemas"]["
|
|
2754
|
+
items: components["schemas"]["Trigger"][];
|
|
2599
2755
|
/**
|
|
2600
2756
|
* Format: uint64
|
|
2601
2757
|
* @description If request contains more data, this is the id is set with which next request should be performed to get next page. If no more data, then it is undefined.
|
|
2602
2758
|
*/
|
|
2603
2759
|
nextStartInclusive?: number | null;
|
|
2604
2760
|
};
|
|
2605
|
-
|
|
2761
|
+
Trigger: {
|
|
2606
2762
|
/** Format: uint32 */
|
|
2607
2763
|
accountId: number;
|
|
2608
2764
|
/** Format: uint32 */
|
|
2609
2765
|
marketId: number;
|
|
2610
|
-
|
|
2611
|
-
|
|
2766
|
+
triggerPrice: components["schemas"]["PositivePriceMantissa"];
|
|
2767
|
+
limitPrice?: components["schemas"]["PositivePriceMantissa"] | null;
|
|
2612
2768
|
side: components["schemas"]["Side"];
|
|
2613
2769
|
kind: components["schemas"]["TriggerKind"];
|
|
2614
2770
|
status: components["schemas"]["TriggerStatus"];
|
|
@@ -2619,6 +2775,11 @@ export interface components {
|
|
|
2619
2775
|
createdAt: string;
|
|
2620
2776
|
finalizedAt: string;
|
|
2621
2777
|
};
|
|
2778
|
+
/**
|
|
2779
|
+
* Format: uint64
|
|
2780
|
+
* @description 63 bit integer, which is always positive
|
|
2781
|
+
*/
|
|
2782
|
+
PositivePriceMantissa: number;
|
|
2622
2783
|
/** @enum {string} */
|
|
2623
2784
|
TriggerKind: "stopLoss" | "takeProfit";
|
|
2624
2785
|
/** @enum {string} */
|
|
@@ -2640,11 +2801,6 @@ export interface components {
|
|
|
2640
2801
|
trigger: components["schemas"]["PositivePriceMantissa"];
|
|
2641
2802
|
settlement?: components["schemas"]["PositivePriceMantissa"] | null;
|
|
2642
2803
|
};
|
|
2643
|
-
/**
|
|
2644
|
-
* Format: uint64
|
|
2645
|
-
* @description 63 bit integer, which is always positive
|
|
2646
|
-
*/
|
|
2647
|
-
PositivePriceMantissa: number;
|
|
2648
2804
|
OrderNotFound: null;
|
|
2649
2805
|
PageResult_for_String_and_Trade: {
|
|
2650
2806
|
/** @description Set of items for requested by query. */
|
|
@@ -2805,6 +2961,39 @@ export interface components {
|
|
|
2805
2961
|
/** Format: double */
|
|
2806
2962
|
volume: number;
|
|
2807
2963
|
};
|
|
2964
|
+
GetPrevMarketPriceQuery: {
|
|
2965
|
+
atOrBefore: string;
|
|
2966
|
+
};
|
|
2967
|
+
PreviousMarketPrice: {
|
|
2968
|
+
/** Format: uint32 */
|
|
2969
|
+
marketId: number;
|
|
2970
|
+
/** Format: double */
|
|
2971
|
+
price?: number | null;
|
|
2972
|
+
};
|
|
2973
|
+
PageResult_for_uint64_and_Withdrawal: {
|
|
2974
|
+
/** @description Set of items for requested by query. */
|
|
2975
|
+
items: components["schemas"]["Withdrawal"][];
|
|
2976
|
+
/**
|
|
2977
|
+
* Format: uint64
|
|
2978
|
+
* @description If request contains more data, this is the id is set with which next request should be performed to get next page. If no more data, then it is undefined.
|
|
2979
|
+
*/
|
|
2980
|
+
nextStartInclusive?: number | null;
|
|
2981
|
+
};
|
|
2982
|
+
Withdrawal: {
|
|
2983
|
+
time: string;
|
|
2984
|
+
/** Format: uint64 */
|
|
2985
|
+
actionId: number;
|
|
2986
|
+
/** Format: uint32 */
|
|
2987
|
+
accountId: number;
|
|
2988
|
+
/** Format: uint32 */
|
|
2989
|
+
tokenId: number;
|
|
2990
|
+
/** Format: uint64 */
|
|
2991
|
+
amount: number;
|
|
2992
|
+
/** Format: int64 */
|
|
2993
|
+
balance: number;
|
|
2994
|
+
/** Format: int64 */
|
|
2995
|
+
fee: number;
|
|
2996
|
+
};
|
|
2808
2997
|
/** @description TV config query response https://www.tradingview.com/charting-library-docs/latest/connecting_data/UDF/#data-feed-configuration-data */
|
|
2809
2998
|
TvConfigResponse: {
|
|
2810
2999
|
supported_resolutions: components["schemas"]["Resolution"][];
|
package/dist/types.d.ts
CHANGED
|
@@ -59,12 +59,12 @@ export type SideFromApi = components["schemas"]["Side"];
|
|
|
59
59
|
export type FillModeFromApi = components["schemas"]["FillMode"];
|
|
60
60
|
export type PlacementOrigin = components["schemas"]["PlacementOrigin"];
|
|
61
61
|
export type FinalizationReason = components["schemas"]["FinalizationReason"];
|
|
62
|
-
export type
|
|
63
|
-
export type
|
|
64
|
-
export type
|
|
62
|
+
export type PagedQuery = components["schemas"]["PagedQuery"];
|
|
63
|
+
export type AccountPnlInfo = components["schemas"]["AccountPnlInfo"];
|
|
64
|
+
export type AccountPnlInfoPage = components["schemas"]["PageResult_for_uint64_and_AccountPnlInfo"];
|
|
65
65
|
export type AccountTriggerInfo = components["schemas"]["AccountTriggerInfo"];
|
|
66
|
-
export type TriggerHistoryPage = components["schemas"]["
|
|
67
|
-
export type
|
|
66
|
+
export type TriggerHistoryPage = components["schemas"]["PageResult_for_uint64_and_Trigger"];
|
|
67
|
+
export type WithdrawalHistoryPage = components["schemas"]["PageResult_for_uint64_and_Withdrawal"];
|
|
68
68
|
export type FeeTierConfig = components["schemas"]["FeeTierConfig"];
|
|
69
69
|
export type FeeTierId = components["schemas"]["FeeTierId"];
|
|
70
70
|
export type TokenStats = components["schemas"]["TokenStats"];
|
|
@@ -73,6 +73,9 @@ export type AccountFeeTierPage = components["schemas"]["PageResult_for_uint32_an
|
|
|
73
73
|
export type AdminInfo = components["schemas"]["AdminInfo"];
|
|
74
74
|
export type GetAccountVolumeQuery = components["schemas"]["GetAccountVolumeQuery"];
|
|
75
75
|
export type AccountVolumeInfo = components["schemas"]["AccountVolumeInfo"];
|
|
76
|
+
export type GetPrevMarketPriceQuery = components["schemas"]["GetPrevMarketPriceQuery"];
|
|
77
|
+
export type PreviousMarketPrice = components["schemas"]["PreviousMarketPrice"];
|
|
78
|
+
export type WithdrawalInfo = components["schemas"]["Withdrawal"];
|
|
76
79
|
/**
|
|
77
80
|
* Configuration options for the Nord client
|
|
78
81
|
*/
|
|
@@ -214,16 +217,27 @@ export interface WebSocketDeltaUpdate {
|
|
|
214
217
|
bids: OrderbookEntry[];
|
|
215
218
|
timestamp: number;
|
|
216
219
|
}
|
|
217
|
-
/**
|
|
218
|
-
* WebSocket user update message
|
|
219
|
-
*/
|
|
220
220
|
export interface WebSocketAccountUpdate {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
221
|
+
last_update_id: number;
|
|
222
|
+
update_id: number;
|
|
223
|
+
account_id: number;
|
|
224
|
+
fills: Record<string, unknown>;
|
|
225
|
+
places: Record<string, unknown>;
|
|
226
|
+
cancels: Record<string, {
|
|
227
|
+
side: "bid" | "ask";
|
|
228
|
+
current_size: number;
|
|
229
|
+
price: number;
|
|
230
|
+
market_id: number;
|
|
231
|
+
}>;
|
|
232
|
+
balances: Record<string, unknown>;
|
|
225
233
|
}
|
|
226
|
-
export type WebSocketMessage =
|
|
234
|
+
export type WebSocketMessage = {
|
|
235
|
+
trades: WebSocketTradeUpdate;
|
|
236
|
+
} | {
|
|
237
|
+
delta: WebSocketDeltaUpdate;
|
|
238
|
+
} | {
|
|
239
|
+
account: WebSocketAccountUpdate;
|
|
240
|
+
};
|
|
227
241
|
export interface SPLTokenInfo {
|
|
228
242
|
mint: string;
|
|
229
243
|
precision: number;
|
package/dist/utils.d.ts
CHANGED
|
@@ -75,8 +75,12 @@ export declare function decodeHex(value: string): Uint8Array;
|
|
|
75
75
|
export declare function findMarket(markets: Market[], marketId: number): Market;
|
|
76
76
|
export declare function findToken(tokens: Token[], tokenId: number): Token;
|
|
77
77
|
export declare function keypairFromPrivateKey(privateKey: string | Uint8Array): Keypair;
|
|
78
|
-
export declare function
|
|
78
|
+
export declare function signAdminPayload({ payload, user, signTransaction, }: Readonly<{
|
|
79
79
|
payload: Uint8Array;
|
|
80
80
|
user: solana.PublicKey;
|
|
81
81
|
signTransaction: (tx: solana.Transaction) => Promise<solana.Transaction>;
|
|
82
82
|
}>): Promise<Uint8Array>;
|
|
83
|
+
export declare function signUserPayload({ payload, signMessage, }: Readonly<{
|
|
84
|
+
payload: Uint8Array;
|
|
85
|
+
signMessage: (message: Uint8Array) => Promise<Uint8Array>;
|
|
86
|
+
}>): Promise<Uint8Array>;
|
package/dist/utils.js
CHANGED
|
@@ -167,7 +167,7 @@ export function keypairFromPrivateKey(privateKey) {
|
|
|
167
167
|
}
|
|
168
168
|
return Keypair.fromSecretKey(privateKey);
|
|
169
169
|
}
|
|
170
|
-
export async function
|
|
170
|
+
export async function signAdminPayload({ payload, user, signTransaction, }) {
|
|
171
171
|
const tx = new solana.Transaction({
|
|
172
172
|
blockhash: bs58.encode(new Uint8Array(32)),
|
|
173
173
|
lastValidBlockHeight: 0,
|
|
@@ -188,3 +188,6 @@ export async function signUserPayload({ payload, user, signTransaction, }) {
|
|
|
188
188
|
assert(sig.publicKey.equals(user), `signature is for ${sig.publicKey}, expected ${user}`);
|
|
189
189
|
return sig.signature;
|
|
190
190
|
}
|
|
191
|
+
export async function signUserPayload({ payload, signMessage, }) {
|
|
192
|
+
return await signMessage(new TextEncoder().encode(payload.toHex()));
|
|
193
|
+
}
|
|
@@ -212,15 +212,15 @@ export class NordWebSocketClient extends EventEmitter {
|
|
|
212
212
|
}
|
|
213
213
|
const hasOwn = (k) => Object.prototype.hasOwnProperty.call(message, k);
|
|
214
214
|
if (hasOwn("trades")) {
|
|
215
|
-
this.emit("trades", message);
|
|
215
|
+
this.emit("trades", message.trades);
|
|
216
216
|
return;
|
|
217
217
|
}
|
|
218
218
|
if (hasOwn("delta")) {
|
|
219
|
-
this.emit("delta", message);
|
|
219
|
+
this.emit("delta", message.delta);
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
222
222
|
if (hasOwn("account")) {
|
|
223
|
-
this.emit("account", message);
|
|
223
|
+
this.emit("account", message.account);
|
|
224
224
|
return;
|
|
225
225
|
}
|
|
226
226
|
this.emit("error", new Error(`Unexpected message type: ${message}`));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
|
-
import { Account, DeltaEvent,
|
|
2
|
+
import { Account, DeltaEvent, WebSocketDeltaUpdate, SubscriberConfig, StreamTrade, Trades } from "../types";
|
|
3
3
|
/**
|
|
4
4
|
* Subscriber class for handling WebSocket subscriptions
|
|
5
5
|
*/
|
|
@@ -21,7 +21,7 @@ export declare class Subscriber {
|
|
|
21
21
|
* Interface for orderbook subscription
|
|
22
22
|
*/
|
|
23
23
|
export interface OrderbookSubscription extends EventEmitter {
|
|
24
|
-
on(event: "message", listener: (data:
|
|
24
|
+
on(event: "message", listener: (data: WebSocketDeltaUpdate) => void): this;
|
|
25
25
|
on(event: "error", listener: (error: Error) => void): this;
|
|
26
26
|
close(): void;
|
|
27
27
|
removeAllListeners(event?: string): this;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n1xyz/nord-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Typescript for Nord",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@bufbuild/protobuf": "^2.6.3",
|
|
47
|
-
"@n1xyz/proton": "0.0
|
|
47
|
+
"@n1xyz/proton": "0.1.0",
|
|
48
48
|
"@noble/curves": "^1.9.6",
|
|
49
49
|
"@noble/ed25519": "^2.3.0",
|
|
50
50
|
"@noble/hashes": "^1.8.0",
|