@n1xyz/nord-ts 0.1.6 → 0.1.7
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 +57 -0
- package/dist/actions.js +229 -0
- package/dist/client/Nord.d.ts +379 -0
- package/dist/client/Nord.js +718 -0
- package/dist/client/NordAdmin.d.ts +225 -0
- package/dist/client/NordAdmin.js +394 -0
- package/dist/client/NordUser.d.ts +350 -0
- package/dist/client/NordUser.js +743 -0
- package/dist/error.d.ts +35 -0
- package/dist/error.js +49 -0
- package/dist/gen/openapi.d.ts +40 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +29 -1
- package/dist/nord/client/NordAdmin.js +2 -0
- package/dist/types.d.ts +4 -50
- package/dist/types.js +1 -24
- package/dist/utils.d.ts +8 -11
- package/dist/utils.js +54 -41
- package/dist/websocket/Subscriber.d.ts +37 -0
- package/dist/websocket/Subscriber.js +25 -0
- package/dist/websocket/index.d.ts +19 -2
- package/dist/websocket/index.js +82 -2
- package/package.json +1 -1
- package/src/actions.ts +333 -0
- package/src/{nord/client → client}/Nord.ts +207 -210
- package/src/{nord/client → client}/NordAdmin.ts +123 -153
- package/src/{nord/client → client}/NordUser.ts +216 -305
- package/src/gen/openapi.ts +40 -0
- package/src/index.ts +7 -1
- package/src/types.ts +4 -54
- package/src/utils.ts +44 -47
- package/src/{nord/models → websocket}/Subscriber.ts +2 -2
- package/src/websocket/index.ts +105 -2
- package/src/nord/api/actions.ts +0 -648
- package/src/nord/api/core.ts +0 -96
- package/src/nord/api/metrics.ts +0 -269
- package/src/nord/client/NordClient.ts +0 -79
- package/src/nord/index.ts +0 -25
- /package/src/{nord/utils/NordError.ts → error.ts} +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import Decimal from "decimal.js";
|
|
2
|
+
import * as proto from "./gen/nord_pb";
|
|
3
|
+
import { paths } from "./gen/openapi";
|
|
4
|
+
import { Client } from "openapi-fetch";
|
|
5
|
+
import { FillMode, Side, QuoteSize } from "./types";
|
|
6
|
+
import { BigIntValue } from "./utils";
|
|
7
|
+
import { PublicKey, Transaction } from "@solana/web3.js";
|
|
8
|
+
type ReceiptKind = NonNullable<proto.Receipt["kind"]>;
|
|
9
|
+
type ExtractReceiptKind<K extends ReceiptKind["case"]> = Extract<ReceiptKind, {
|
|
10
|
+
case: K;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function formatReceiptError(receipt: proto.Receipt): string;
|
|
13
|
+
export declare function expectReceiptKind<K extends ReceiptKind["case"]>(receipt: proto.Receipt, expected: K, action: string): asserts receipt is proto.Receipt & {
|
|
14
|
+
kind: ExtractReceiptKind<K>;
|
|
15
|
+
};
|
|
16
|
+
export declare function createAction(currentTimestamp: bigint, nonce: number, kind: proto.Action["kind"]): proto.Action;
|
|
17
|
+
export declare function sendAction(client: Client<paths>, makeSignedMessage: (message: Uint8Array) => Promise<Uint8Array>, action: proto.Action): Promise<proto.Receipt>;
|
|
18
|
+
export declare function prepareAction(action: proto.Action, makeSignedMessage: (message: Uint8Array) => Promise<Uint8Array>): Promise<Uint8Array<ArrayBufferLike>>;
|
|
19
|
+
export declare function createSession(client: Client<paths>, signTransaction: (tx: Transaction) => Promise<Transaction>, currentTimestamp: bigint, nonce: number, params: {
|
|
20
|
+
userPubkey: PublicKey;
|
|
21
|
+
sessionPubkey: PublicKey;
|
|
22
|
+
expiryTimestamp?: bigint;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
actionId: bigint;
|
|
25
|
+
sessionId: bigint;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function revokeSession(client: Client<paths>, signTransaction: (tx: Transaction) => Promise<Transaction>, currentTimestamp: bigint, nonce: number, params: {
|
|
28
|
+
sessionId: BigIntValue;
|
|
29
|
+
userPubkey: PublicKey;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
actionId: bigint;
|
|
32
|
+
}>;
|
|
33
|
+
export type AtomicSubaction = {
|
|
34
|
+
kind: "place";
|
|
35
|
+
marketId: number;
|
|
36
|
+
side: Side;
|
|
37
|
+
fillMode: FillMode;
|
|
38
|
+
isReduceOnly: boolean;
|
|
39
|
+
sizeDecimals: number;
|
|
40
|
+
priceDecimals: number;
|
|
41
|
+
size?: Decimal.Value;
|
|
42
|
+
price?: Decimal.Value;
|
|
43
|
+
quoteSize?: QuoteSize;
|
|
44
|
+
clientOrderId?: BigIntValue;
|
|
45
|
+
} | {
|
|
46
|
+
kind: "cancel";
|
|
47
|
+
orderId: BigIntValue;
|
|
48
|
+
};
|
|
49
|
+
export declare function atomic(client: Client<paths>, signFn: (message: Uint8Array) => Promise<Uint8Array>, currentTimestamp: bigint, nonce: number, params: {
|
|
50
|
+
sessionId: BigIntValue;
|
|
51
|
+
accountId?: number;
|
|
52
|
+
actions: AtomicSubaction[];
|
|
53
|
+
}): Promise<{
|
|
54
|
+
actionId: bigint;
|
|
55
|
+
results: proto.Receipt_AtomicSubactionResultKind[];
|
|
56
|
+
}>;
|
|
57
|
+
export {};
|
package/dist/actions.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.formatReceiptError = formatReceiptError;
|
|
37
|
+
exports.expectReceiptKind = expectReceiptKind;
|
|
38
|
+
exports.createAction = createAction;
|
|
39
|
+
exports.sendAction = sendAction;
|
|
40
|
+
exports.prepareAction = prepareAction;
|
|
41
|
+
exports.createSession = createSession;
|
|
42
|
+
exports.revokeSession = revokeSession;
|
|
43
|
+
exports.atomic = atomic;
|
|
44
|
+
const proto = __importStar(require("./gen/nord_pb"));
|
|
45
|
+
const protobuf_1 = require("@bufbuild/protobuf");
|
|
46
|
+
const types_1 = require("./types");
|
|
47
|
+
const utils_1 = require("./utils");
|
|
48
|
+
const wire_1 = require("@bufbuild/protobuf/wire");
|
|
49
|
+
const error_1 = require("./error");
|
|
50
|
+
function formatReceiptError(receipt) {
|
|
51
|
+
if (receipt.kind?.case === "err") {
|
|
52
|
+
const err = receipt.kind.value;
|
|
53
|
+
return proto.Error[err] ?? err.toString();
|
|
54
|
+
}
|
|
55
|
+
return receipt.kind?.case ?? "unknown";
|
|
56
|
+
}
|
|
57
|
+
function expectReceiptKind(receipt, expected, action) {
|
|
58
|
+
if (receipt.kind?.case !== expected) {
|
|
59
|
+
const label = formatReceiptError(receipt);
|
|
60
|
+
throw new error_1.NordError(`Failed to ${action}: ${label}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function sessionSign(signFn, message) {
|
|
64
|
+
const signature = await signFn(message);
|
|
65
|
+
return new Uint8Array([...message, ...signature]);
|
|
66
|
+
}
|
|
67
|
+
// Helper to create an action with common fields
|
|
68
|
+
function createAction(currentTimestamp, nonce, kind) {
|
|
69
|
+
return (0, protobuf_1.create)(proto.ActionSchema, {
|
|
70
|
+
currentTimestamp,
|
|
71
|
+
nonce,
|
|
72
|
+
kind,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async function sendAction(client, makeSignedMessage, action) {
|
|
76
|
+
const body = await prepareAction(action, makeSignedMessage);
|
|
77
|
+
const response = await client.POST("/action", {
|
|
78
|
+
params: {
|
|
79
|
+
header: {
|
|
80
|
+
"content-type": "application/octet-stream",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
body: body,
|
|
84
|
+
// NOTE: openapi-fetch ignores headers and types/const headers in schema, and always assume all things are JSON
|
|
85
|
+
// to handle multi type bodies, need these overrides and later adhoc parsing
|
|
86
|
+
bodySerializer: (body) => body,
|
|
87
|
+
parseAs: "stream",
|
|
88
|
+
});
|
|
89
|
+
if (response.error) {
|
|
90
|
+
throw new Error(`Failed to ${action.kind.case}, HTTP status ${JSON.stringify(response.error)}`);
|
|
91
|
+
}
|
|
92
|
+
const rawResp = new Uint8Array(await response.response.bytes());
|
|
93
|
+
const resp = (0, utils_1.decodeLengthDelimited)(rawResp, proto.ReceiptSchema);
|
|
94
|
+
if (resp.kind?.case === "err") {
|
|
95
|
+
throw new Error(`Could not execute ${action.kind.case}, reason: ${proto.Error[resp.kind.value]}`);
|
|
96
|
+
}
|
|
97
|
+
return resp;
|
|
98
|
+
}
|
|
99
|
+
// Given action and signature function, prepare the signed message to send to server as `body`.
|
|
100
|
+
// `makeSignedMessage` must include the original message and signature.
|
|
101
|
+
async function prepareAction(action, makeSignedMessage) {
|
|
102
|
+
const encoded = (0, wire_1.sizeDelimitedEncode)(proto.ActionSchema, action);
|
|
103
|
+
// NOTE(agent): keep in sync with MAX_ENCODED_ACTION_SIZE in Rust code
|
|
104
|
+
const MAX_ENCODED_ACTION_SIZE = 1024;
|
|
105
|
+
if (encoded.byteLength > MAX_ENCODED_ACTION_SIZE) {
|
|
106
|
+
console.warn("Encoded message:", encoded);
|
|
107
|
+
throw new Error(`Encoded message size (${encoded.byteLength} bytes) is greater than max payload size (${MAX_ENCODED_ACTION_SIZE} bytes).`);
|
|
108
|
+
}
|
|
109
|
+
const body = await makeSignedMessage(encoded);
|
|
110
|
+
if (body.byteLength > MAX_ENCODED_ACTION_SIZE) {
|
|
111
|
+
console.warn("Encoded length:", encoded.byteLength);
|
|
112
|
+
throw new Error(`Signed message size (${body.byteLength} bytes) is greater than max payload size (${MAX_ENCODED_ACTION_SIZE} bytes).`);
|
|
113
|
+
}
|
|
114
|
+
return body;
|
|
115
|
+
}
|
|
116
|
+
async function createSession(client, signTransaction, currentTimestamp, nonce, params) {
|
|
117
|
+
let expiry = 0n;
|
|
118
|
+
if (params.expiryTimestamp !== undefined) {
|
|
119
|
+
expiry = params.expiryTimestamp;
|
|
120
|
+
(0, utils_1.assert)(expiry > currentTimestamp, "Cannot set expiry timestamp in the past");
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
expiry = currentTimestamp + utils_1.SESSION_TTL;
|
|
124
|
+
}
|
|
125
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
126
|
+
case: "createSession",
|
|
127
|
+
value: (0, protobuf_1.create)(proto.Action_CreateSessionSchema, {
|
|
128
|
+
userPubkey: params.userPubkey.toBytes(),
|
|
129
|
+
blstPubkey: params.sessionPubkey.toBytes(),
|
|
130
|
+
expiryTimestamp: expiry,
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
const resp = await sendAction(client, async (payload) => {
|
|
134
|
+
return new Uint8Array([
|
|
135
|
+
...payload,
|
|
136
|
+
...(await (0, utils_1.signUserPayload)({
|
|
137
|
+
payload,
|
|
138
|
+
user: params.userPubkey,
|
|
139
|
+
signTransaction,
|
|
140
|
+
})),
|
|
141
|
+
]);
|
|
142
|
+
}, action);
|
|
143
|
+
if (resp.kind?.case === "createSessionResult") {
|
|
144
|
+
return {
|
|
145
|
+
actionId: resp.actionId,
|
|
146
|
+
sessionId: resp.kind.value.sessionId,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function revokeSession(client, signTransaction, currentTimestamp, nonce, params) {
|
|
154
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
155
|
+
case: "revokeSession",
|
|
156
|
+
value: (0, protobuf_1.create)(proto.Action_RevokeSessionSchema, {
|
|
157
|
+
sessionId: BigInt(params.sessionId),
|
|
158
|
+
}),
|
|
159
|
+
});
|
|
160
|
+
const resp = await sendAction(client, async (payload) => {
|
|
161
|
+
return new Uint8Array([
|
|
162
|
+
...payload,
|
|
163
|
+
...(await (0, utils_1.signUserPayload)({
|
|
164
|
+
payload,
|
|
165
|
+
user: params.userPubkey,
|
|
166
|
+
signTransaction,
|
|
167
|
+
})),
|
|
168
|
+
]);
|
|
169
|
+
}, action);
|
|
170
|
+
return { actionId: resp.actionId };
|
|
171
|
+
}
|
|
172
|
+
async function atomic(client, signFn, currentTimestamp, nonce, params) {
|
|
173
|
+
(0, utils_1.assert)(params.actions.length > 0 && params.actions.length <= 4, "Atomic action must contain between 1 and 4 sub-actions");
|
|
174
|
+
const subactions = params.actions.map((a) => {
|
|
175
|
+
if (a.kind === "place") {
|
|
176
|
+
const price = (0, utils_1.toScaledU64)(a.price ?? 0, a.priceDecimals);
|
|
177
|
+
const size = (0, utils_1.toScaledU64)(a.size ?? 0, a.sizeDecimals);
|
|
178
|
+
const scaledQuote = a.quoteSize
|
|
179
|
+
? a.quoteSize.toWire(a.priceDecimals, a.sizeDecimals)
|
|
180
|
+
: undefined;
|
|
181
|
+
// Require at least one limit to be set (non-zero size, non-zero price, or quoteSize)
|
|
182
|
+
(0, utils_1.assert)(price > 0n || size > 0n || scaledQuote !== undefined, "OrderLimit must include at least one of: size, price, or quoteSize");
|
|
183
|
+
const tradeOrPlace = (0, protobuf_1.create)(proto.TradeOrPlaceSchema, {
|
|
184
|
+
marketId: a.marketId,
|
|
185
|
+
orderType: (0, protobuf_1.create)(proto.OrderTypeSchema, {
|
|
186
|
+
side: a.side === types_1.Side.Bid ? proto.Side.BID : proto.Side.ASK,
|
|
187
|
+
fillMode: (0, types_1.fillModeToProtoFillMode)(a.fillMode),
|
|
188
|
+
isReduceOnly: a.isReduceOnly,
|
|
189
|
+
}),
|
|
190
|
+
limit: (0, protobuf_1.create)(proto.OrderLimitSchema, {
|
|
191
|
+
price,
|
|
192
|
+
size,
|
|
193
|
+
quoteSize: scaledQuote === undefined
|
|
194
|
+
? undefined
|
|
195
|
+
: (0, protobuf_1.create)(proto.QuoteSizeSchema, {
|
|
196
|
+
size: scaledQuote.size,
|
|
197
|
+
price: scaledQuote.price,
|
|
198
|
+
}),
|
|
199
|
+
}),
|
|
200
|
+
clientOrderId: a.clientOrderId === undefined ? undefined : BigInt(a.clientOrderId),
|
|
201
|
+
});
|
|
202
|
+
return (0, protobuf_1.create)(proto.AtomicSubactionKindSchema, {
|
|
203
|
+
inner: { case: "tradeOrPlace", value: tradeOrPlace },
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return (0, protobuf_1.create)(proto.AtomicSubactionKindSchema, {
|
|
207
|
+
inner: {
|
|
208
|
+
case: "cancelOrder",
|
|
209
|
+
value: (0, protobuf_1.create)(proto.CancelOrderSchema, { orderId: BigInt(a.orderId) }),
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
const action = createAction(currentTimestamp, nonce, {
|
|
214
|
+
case: "atomic",
|
|
215
|
+
value: (0, protobuf_1.create)(proto.AtomicSchema, {
|
|
216
|
+
sessionId: BigInt(params.sessionId),
|
|
217
|
+
accountId: params.accountId, // optional
|
|
218
|
+
actions: subactions,
|
|
219
|
+
}),
|
|
220
|
+
});
|
|
221
|
+
const resp = await sendAction(client, (m) => sessionSign(signFn, m), action);
|
|
222
|
+
if (resp.kind?.case === "atomic") {
|
|
223
|
+
return {
|
|
224
|
+
actionId: resp.actionId,
|
|
225
|
+
results: resp.kind.value.results,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
throw new Error(`Unexpected receipt kind ${resp.kind?.case}`);
|
|
229
|
+
}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { ProtonClient } from "@n1xyz/proton";
|
|
2
|
+
import { Connection, PublicKey } from "@solana/web3.js";
|
|
3
|
+
import { EventEmitter } from "events";
|
|
4
|
+
import { Client } from "openapi-fetch";
|
|
5
|
+
import type { paths } from "../gen/openapi.ts";
|
|
6
|
+
import { Account, AccountPnlPage, AccountPnlQuery, ActionResponse, MarketsInfo, Market, MarketStats, NordConfig, OrderbookQuery, OrderbookResponse, FeeTierConfig, Token, TradesResponse, User, AccountTriggerInfo, HistoryTriggerQuery, TriggerHistoryPage, FeeTierId, AccountFeeTierPage, PageResultStringOrderInfo, PageResultStringTrade, OrderInfoFromApi, TokenStats, FillRole } from "../types";
|
|
7
|
+
import { NordWebSocketClient } from "../websocket/index";
|
|
8
|
+
import { OrderbookSubscription, TradeSubscription } from "../websocket/Subscriber";
|
|
9
|
+
/**
|
|
10
|
+
* User subscription interface
|
|
11
|
+
*/
|
|
12
|
+
export interface UserSubscription extends EventEmitter {
|
|
13
|
+
close: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Main Nord client class for interacting with the Nord API
|
|
17
|
+
*/
|
|
18
|
+
export declare class Nord {
|
|
19
|
+
/** Base URL for the Nord web server */
|
|
20
|
+
readonly webServerUrl: string;
|
|
21
|
+
/** Solana RPC URL */
|
|
22
|
+
readonly solanaConnection: Connection;
|
|
23
|
+
/** Available markets */
|
|
24
|
+
markets: Market[];
|
|
25
|
+
/** Available tokens */
|
|
26
|
+
tokens: Token[];
|
|
27
|
+
/** Map of symbol to market_id */
|
|
28
|
+
private symbolToMarketId;
|
|
29
|
+
/** Proton client for proton related operations */
|
|
30
|
+
protonClient: ProtonClient;
|
|
31
|
+
/** HTTP client for Nord operations */
|
|
32
|
+
readonly httpClient: Client<paths>;
|
|
33
|
+
/**
|
|
34
|
+
* Create a new Nord client
|
|
35
|
+
*
|
|
36
|
+
* @param config - Configuration options for the Nord client
|
|
37
|
+
* @param config.webServerUrl - Base URL for the Nord web server
|
|
38
|
+
* @param config.solanaUrl - Solana cluster URL
|
|
39
|
+
* @throws {Error} If required configuration is missing
|
|
40
|
+
*/
|
|
41
|
+
private constructor();
|
|
42
|
+
/**
|
|
43
|
+
* Create a WebSocket client with specific subscriptions
|
|
44
|
+
*
|
|
45
|
+
* @param trades - Market symbols to subscribe to for trade updates
|
|
46
|
+
* @param deltas - Market symbols to subscribe to for orderbook delta updates
|
|
47
|
+
* @param accounts - Account IDs to subscribe to for account updates
|
|
48
|
+
* @returns A new WebSocket client with the requested subscriptions
|
|
49
|
+
* @throws {NordError} If invalid subscription options are provided
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // Create a client for trades and deltas from one market and an account
|
|
53
|
+
* const wsClient = nord.createWebSocketClient({
|
|
54
|
+
* trades: ["BTCUSDC"],
|
|
55
|
+
* deltas: ["BTCUSDC"],
|
|
56
|
+
* accounts: [123]
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Create a client for trades from multiple markets
|
|
61
|
+
* const tradesClient = nord.createWebSocketClient({
|
|
62
|
+
* trades: ["BTCUSDC", "ETHUSDC"]
|
|
63
|
+
* });
|
|
64
|
+
*/
|
|
65
|
+
createWebSocketClient({ trades, deltas, accounts, }: Readonly<{
|
|
66
|
+
trades?: string[];
|
|
67
|
+
deltas?: string[];
|
|
68
|
+
accounts?: number[];
|
|
69
|
+
}>): NordWebSocketClient;
|
|
70
|
+
private GET;
|
|
71
|
+
/**
|
|
72
|
+
* Get the current timestamp from the Nord server
|
|
73
|
+
*
|
|
74
|
+
* @returns Current timestamp as a bigint
|
|
75
|
+
* @throws {NordError} If the request fails
|
|
76
|
+
*/
|
|
77
|
+
getTimestamp(): Promise<bigint>;
|
|
78
|
+
/**
|
|
79
|
+
* Get the last event nonce from the Nord server
|
|
80
|
+
*
|
|
81
|
+
* @returns Next action nonce
|
|
82
|
+
* @throws {NordError} If the request fails
|
|
83
|
+
*/
|
|
84
|
+
getActionNonce(): Promise<number>;
|
|
85
|
+
/**
|
|
86
|
+
* Get the admin list from the Nord server
|
|
87
|
+
*
|
|
88
|
+
* @returns List of admin registration keys paired with their ACL role mask
|
|
89
|
+
* @throws {NordError} If the request fails
|
|
90
|
+
*/
|
|
91
|
+
getAdminList(): Promise<Array<[string, number]>>;
|
|
92
|
+
/**
|
|
93
|
+
* Fetch information about Nord markets and tokens
|
|
94
|
+
*
|
|
95
|
+
* @throws {NordError} If the request fails
|
|
96
|
+
*/
|
|
97
|
+
fetchNordInfo(): Promise<void>;
|
|
98
|
+
/** @deprecated use Nord.new */
|
|
99
|
+
static initNord(x: Readonly<NordConfig>): Promise<Nord>;
|
|
100
|
+
/**
|
|
101
|
+
* Initialize a new Nord client
|
|
102
|
+
*
|
|
103
|
+
* @param nordConfig - Configuration options for the Nord client
|
|
104
|
+
* @param nordConfig.webServerUrl - Base URL for the Nord web server
|
|
105
|
+
* @param nordConfig.app - App address
|
|
106
|
+
* @param nordConfig.solanaUrl - Solana cluster URL
|
|
107
|
+
* @returns Initialized Nord client
|
|
108
|
+
* @throws {NordError} If initialization fails
|
|
109
|
+
*/
|
|
110
|
+
static new({ app, solanaConnection, webServerUrl, protonUrl, }: Readonly<NordConfig>): Promise<Nord>;
|
|
111
|
+
/**
|
|
112
|
+
* Initialize the Nord client
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
115
|
+
private init;
|
|
116
|
+
/**
|
|
117
|
+
* Query a specific action
|
|
118
|
+
*
|
|
119
|
+
* @param actionId - Action identifier to fetch
|
|
120
|
+
* @returns Action response
|
|
121
|
+
* @throws {NordError} If the request fails
|
|
122
|
+
*/
|
|
123
|
+
queryAction({ actionId, }: Readonly<{
|
|
124
|
+
actionId: number;
|
|
125
|
+
}>): Promise<ActionResponse | null>;
|
|
126
|
+
/**
|
|
127
|
+
* Query recent actions
|
|
128
|
+
*
|
|
129
|
+
* @param from - Starting action index (inclusive)
|
|
130
|
+
* @param to - Ending action index (inclusive)
|
|
131
|
+
* @returns Actions response
|
|
132
|
+
* @throws {NordError} If the request fails
|
|
133
|
+
*/
|
|
134
|
+
queryRecentActions({ from, to, }: Readonly<{
|
|
135
|
+
from: number;
|
|
136
|
+
to: number;
|
|
137
|
+
}>): Promise<ActionResponse[]>;
|
|
138
|
+
/**
|
|
139
|
+
* Get the last action ID
|
|
140
|
+
*
|
|
141
|
+
* @returns Last action ID
|
|
142
|
+
* @throws {NordError} If the request fails
|
|
143
|
+
*/
|
|
144
|
+
getLastActionId(): Promise<number>;
|
|
145
|
+
/**
|
|
146
|
+
* Subscribe to orderbook updates for a market
|
|
147
|
+
*
|
|
148
|
+
* @param symbol - Market symbol
|
|
149
|
+
* @returns Orderbook subscription
|
|
150
|
+
* @throws {NordError} If symbol is invalid
|
|
151
|
+
*/
|
|
152
|
+
subscribeOrderbook(symbol: string): OrderbookSubscription;
|
|
153
|
+
/**
|
|
154
|
+
* Subscribe to trade updates for a market
|
|
155
|
+
*
|
|
156
|
+
* @param symbol - Market symbol
|
|
157
|
+
* @returns Trade subscription
|
|
158
|
+
* @throws {NordError} If symbol is invalid
|
|
159
|
+
*/
|
|
160
|
+
subscribeTrades(symbol: string): TradeSubscription;
|
|
161
|
+
/**
|
|
162
|
+
* Subscribe to account updates
|
|
163
|
+
*
|
|
164
|
+
* @param accountId - Account ID to subscribe to
|
|
165
|
+
* @returns User subscription
|
|
166
|
+
* @throws {NordError} If accountId is invalid
|
|
167
|
+
*/
|
|
168
|
+
subscribeAccount(accountId: number): UserSubscription;
|
|
169
|
+
/**
|
|
170
|
+
* Get trades for a market
|
|
171
|
+
*
|
|
172
|
+
* @param marketId - Market identifier to filter by
|
|
173
|
+
* @param takerId - Taker account identifier
|
|
174
|
+
* @param makerId - Maker account identifier
|
|
175
|
+
* @param takerSide - Side executed by the taker
|
|
176
|
+
* @param pageSize - Maximum number of trades to return
|
|
177
|
+
* @param since - RFC3339 timestamp to start from (inclusive)
|
|
178
|
+
* @param until - RFC3339 timestamp to end at (exclusive)
|
|
179
|
+
* @param pageId - Pagination cursor returned from a prior call
|
|
180
|
+
* @returns Trades response
|
|
181
|
+
* @throws {NordError} If the request fails
|
|
182
|
+
*/
|
|
183
|
+
getTrades({ marketId, takerId, makerId, takerSide, pageSize, since, until, startInclusive, }: Readonly<{
|
|
184
|
+
marketId?: number;
|
|
185
|
+
takerId?: number;
|
|
186
|
+
makerId?: number;
|
|
187
|
+
takerSide?: "bid" | "ask";
|
|
188
|
+
pageSize?: number;
|
|
189
|
+
since?: string;
|
|
190
|
+
until?: string;
|
|
191
|
+
startInclusive?: string;
|
|
192
|
+
}>): Promise<TradesResponse>;
|
|
193
|
+
/**
|
|
194
|
+
* Get user account IDs
|
|
195
|
+
*
|
|
196
|
+
* @param pubkey - User public key to query
|
|
197
|
+
* @returns User account IDs response
|
|
198
|
+
* @throws {NordError} If the request fails
|
|
199
|
+
*/
|
|
200
|
+
getUser({ pubkey, }: Readonly<{
|
|
201
|
+
pubkey: string | PublicKey;
|
|
202
|
+
}>): Promise<User | null>;
|
|
203
|
+
/**
|
|
204
|
+
* Get orderbook for a market
|
|
205
|
+
*
|
|
206
|
+
* @param symbol - Market symbol to resolve into an id
|
|
207
|
+
* @param marketId - Market identifier
|
|
208
|
+
* @returns Orderbook response
|
|
209
|
+
* @throws {NordError} If the request fails or if the market symbol is unknown
|
|
210
|
+
* @remarks It's recommended to initialize the Nord client using the static `initNord` method
|
|
211
|
+
* to ensure market information is properly loaded before calling this method.
|
|
212
|
+
*/
|
|
213
|
+
getOrderbook({ symbol, marketId, }: OrderbookQuery): Promise<OrderbookResponse>;
|
|
214
|
+
/**
|
|
215
|
+
* Get information about the Nord server
|
|
216
|
+
*
|
|
217
|
+
* @returns Information about markets and tokens
|
|
218
|
+
* @throws {NordError} If the request fails
|
|
219
|
+
*/
|
|
220
|
+
getInfo(): Promise<MarketsInfo>;
|
|
221
|
+
/**
|
|
222
|
+
* Fetch the current fee tier brackets configured on Nord.
|
|
223
|
+
*
|
|
224
|
+
* @returns Array of fee tier identifiers paired with their configuration
|
|
225
|
+
* @throws {NordError} If the request fails
|
|
226
|
+
*/
|
|
227
|
+
getFeeBrackets(): Promise<Array<[FeeTierId, FeeTierConfig]>>;
|
|
228
|
+
/**
|
|
229
|
+
* Retrieve the fee tier assigned to a specific account.
|
|
230
|
+
*
|
|
231
|
+
* @param accountId - Account identifier to query
|
|
232
|
+
* @returns Fee tier details for the requested account
|
|
233
|
+
* @throws {NordError} If the request fails
|
|
234
|
+
*/
|
|
235
|
+
getAccountFeeTier(accountId: number): Promise<FeeTierId>;
|
|
236
|
+
/**
|
|
237
|
+
* Get account information
|
|
238
|
+
*
|
|
239
|
+
* @param accountId - Account ID to get information for
|
|
240
|
+
* @returns Account information
|
|
241
|
+
* @throws {NordError} If the request fails
|
|
242
|
+
*/
|
|
243
|
+
getAccount(accountId: number): Promise<Account>;
|
|
244
|
+
/**
|
|
245
|
+
* Get the public key associated with an account id.
|
|
246
|
+
*
|
|
247
|
+
* @param accountId - Account id to query
|
|
248
|
+
* @returns Base58-encoded account public key
|
|
249
|
+
* @throws {NordError} If the request fails
|
|
250
|
+
*/
|
|
251
|
+
getAccountPubkey(accountId: number): Promise<string>;
|
|
252
|
+
/**
|
|
253
|
+
* Get the withdrawal fee charged for an account.
|
|
254
|
+
*
|
|
255
|
+
* @param accountId - Account id to query
|
|
256
|
+
* @returns Withdrawal fee quoted in quote token units
|
|
257
|
+
* @throws {NordError} If the request fails
|
|
258
|
+
*/
|
|
259
|
+
getAccountWithdrawalFee(accountId: number): Promise<number>;
|
|
260
|
+
/**
|
|
261
|
+
* Get open orders for an account.
|
|
262
|
+
*
|
|
263
|
+
* @param accountId - Account id to query
|
|
264
|
+
* @param startInclusive - Pagination cursor (client order id) to resume from
|
|
265
|
+
* @param pageSize - Maximum number of orders to return
|
|
266
|
+
* @returns Page of orders keyed by client order id
|
|
267
|
+
* @throws {NordError} If the request fails
|
|
268
|
+
*/
|
|
269
|
+
getAccountOrders(accountId: number, { startInclusive, pageSize, }?: Readonly<{
|
|
270
|
+
startInclusive?: string | null;
|
|
271
|
+
pageSize?: number | null;
|
|
272
|
+
}>): Promise<PageResultStringOrderInfo>;
|
|
273
|
+
/**
|
|
274
|
+
* List account fee tiers with pagination support.
|
|
275
|
+
*
|
|
276
|
+
* @param startInclusive - Account id cursor to resume from
|
|
277
|
+
* @param pageSize - Maximum number of entries to return
|
|
278
|
+
*/
|
|
279
|
+
getAccountsFeeTiers({ startInclusive, pageSize, }?: Readonly<{
|
|
280
|
+
startInclusive?: number | null;
|
|
281
|
+
pageSize?: number | null;
|
|
282
|
+
}>): Promise<AccountFeeTierPage>;
|
|
283
|
+
/**
|
|
284
|
+
* Get profit and loss history for an account
|
|
285
|
+
*
|
|
286
|
+
* @param accountId - Account ID to query
|
|
287
|
+
* @param since - RFC3339 timestamp to start from (inclusive)
|
|
288
|
+
* @param until - RFC3339 timestamp to end at (exclusive)
|
|
289
|
+
* @param startInclusive - Pagination cursor to resume from
|
|
290
|
+
* @param pageSize - Maximum number of entries to return
|
|
291
|
+
* @returns Page of PnL entries ordered from latest to oldest
|
|
292
|
+
* @throws {NordError} If the request fails
|
|
293
|
+
*/
|
|
294
|
+
getAccountPnl(accountId: number, { since, until, startInclusive, pageSize, }?: Readonly<Partial<AccountPnlQuery>>): Promise<AccountPnlPage>;
|
|
295
|
+
/**
|
|
296
|
+
* Get market statistics (alias for marketsStats for backward compatibility)
|
|
297
|
+
*
|
|
298
|
+
*
|
|
299
|
+
* @param marketId - Market identifier
|
|
300
|
+
*
|
|
301
|
+
* @returns Market statistics response
|
|
302
|
+
*/
|
|
303
|
+
getMarketStats({ marketId, }: Readonly<{
|
|
304
|
+
marketId: number;
|
|
305
|
+
}>): Promise<MarketStats>;
|
|
306
|
+
/**
|
|
307
|
+
* Fetch the per-market fee quote for an account.
|
|
308
|
+
*
|
|
309
|
+
* @param marketId - Market identifier
|
|
310
|
+
* @param feeKind - Fill role (maker/taker) to quote
|
|
311
|
+
* @param accountId - Account identifier to quote
|
|
312
|
+
* @returns Fee in quote token units (negative means fee is charged)
|
|
313
|
+
* @throws {NordError} If the request fails
|
|
314
|
+
*/
|
|
315
|
+
getMarketFee({ marketId, feeKind, accountId, }: Readonly<{
|
|
316
|
+
marketId: number;
|
|
317
|
+
feeKind: FillRole;
|
|
318
|
+
accountId: number;
|
|
319
|
+
}>): Promise<number>;
|
|
320
|
+
/**
|
|
321
|
+
* Fetch token statistics such as index price and oracle metadata.
|
|
322
|
+
*
|
|
323
|
+
* @param tokenId - Token identifier
|
|
324
|
+
* @returns Token stats
|
|
325
|
+
* @throws {NordError} If the request fails
|
|
326
|
+
*/
|
|
327
|
+
getTokenStats(tokenId: number): Promise<TokenStats>;
|
|
328
|
+
/**
|
|
329
|
+
* Get order summary by order id.
|
|
330
|
+
*
|
|
331
|
+
* @param orderId - Order identifier
|
|
332
|
+
* @returns Order information
|
|
333
|
+
* @throws {NordError} If the request fails
|
|
334
|
+
*/
|
|
335
|
+
getOrder(orderId: string): Promise<OrderInfoFromApi>;
|
|
336
|
+
/**
|
|
337
|
+
* Get trade history for a specific order.
|
|
338
|
+
*
|
|
339
|
+
* @param orderId - Order identifier
|
|
340
|
+
* @param startInclusive - Trade pagination cursor
|
|
341
|
+
* @param pageSize - Maximum number of trades to return
|
|
342
|
+
* @returns Page of trades associated with the order
|
|
343
|
+
* @throws {NordError} If the request fails
|
|
344
|
+
*/
|
|
345
|
+
getOrderTrades(orderId: string, { startInclusive, pageSize, }?: Readonly<{
|
|
346
|
+
startInclusive?: string | null;
|
|
347
|
+
pageSize?: number | null;
|
|
348
|
+
}>): Promise<PageResultStringTrade>;
|
|
349
|
+
/**
|
|
350
|
+
* Check if an account exists for the given address
|
|
351
|
+
*
|
|
352
|
+
* @param address - The public key address to check
|
|
353
|
+
* @returns True if the account exists, false otherwise
|
|
354
|
+
* @deprecated use getUser instead
|
|
355
|
+
*/
|
|
356
|
+
accountExists(pubkey: string | PublicKey): Promise<boolean>;
|
|
357
|
+
/**
|
|
358
|
+
* Fetch active triggers for an account.
|
|
359
|
+
*
|
|
360
|
+
* @param accountId - Account identifier owning the triggers
|
|
361
|
+
* @throws {NordError} If no account can be resolved or the request fails.
|
|
362
|
+
*/
|
|
363
|
+
getAccountTriggers({ accountId, }?: Readonly<{
|
|
364
|
+
accountId?: number;
|
|
365
|
+
}>): Promise<AccountTriggerInfo[]>;
|
|
366
|
+
/**
|
|
367
|
+
* Fetch trigger history for an account.
|
|
368
|
+
*
|
|
369
|
+
* @param accountId - Account identifier owning the triggers
|
|
370
|
+
* @param since - RFC3339 timestamp to start from (inclusive)
|
|
371
|
+
* @param until - RFC3339 timestamp to end at (exclusive)
|
|
372
|
+
* @param pageSize - Maximum number of entries to return
|
|
373
|
+
* @param startInclusive - Pagination cursor to resume from
|
|
374
|
+
* @throws {NordError} If no account can be resolved or the request fails.
|
|
375
|
+
*/
|
|
376
|
+
getAccountTriggerHistory({ accountId, since, until, pageSize, startInclusive, }: Readonly<HistoryTriggerQuery & {
|
|
377
|
+
accountId?: number;
|
|
378
|
+
}>): Promise<TriggerHistoryPage>;
|
|
379
|
+
}
|