@flexemarkets/fm-sdk 0.0.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/client.d.ts +73 -0
- package/dist/client.js +576 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/order-utils.d.ts +22 -0
- package/dist/order-utils.js +131 -0
- package/dist/order-utils.js.map +1 -0
- package/dist/orderbook.d.ts +48 -0
- package/dist/orderbook.js +150 -0
- package/dist/orderbook.js.map +1 -0
- package/dist/stomp.d.ts +49 -0
- package/dist/stomp.js +275 -0
- package/dist/stomp.js.map +1 -0
- package/dist/ticker.d.ts +7 -0
- package/dist/ticker.js +128 -0
- package/dist/ticker.js.map +1 -0
- package/dist/trades.d.ts +36 -0
- package/dist/trades.js +100 -0
- package/dist/trades.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.js +27 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flexemarkets API client.
|
|
3
|
+
*
|
|
4
|
+
* Port of fm.client (Python) / fm.Flexemarkets (Java).
|
|
5
|
+
*/
|
|
6
|
+
import type { Account, ClientConnection, Holding, Market, Marketplace, Order, Person, Session } from "./types.js";
|
|
7
|
+
import { type EventCallback } from "./stomp.js";
|
|
8
|
+
export declare class FlexemarketsError extends Error {
|
|
9
|
+
}
|
|
10
|
+
export declare class AuthenticationError extends FlexemarketsError {
|
|
11
|
+
}
|
|
12
|
+
export declare class AuthorizationError extends FlexemarketsError {
|
|
13
|
+
}
|
|
14
|
+
export declare class InvalidArgumentError extends FlexemarketsError {
|
|
15
|
+
}
|
|
16
|
+
export declare class ConnectionFailedError extends FlexemarketsError {
|
|
17
|
+
}
|
|
18
|
+
export declare class ConfigurationError extends FlexemarketsError {
|
|
19
|
+
}
|
|
20
|
+
type JsonObject = Record<string, unknown>;
|
|
21
|
+
export declare function parseOrder(data: JsonObject): Order;
|
|
22
|
+
export declare function parseHolding(data: JsonObject): Holding;
|
|
23
|
+
export interface FlexemarketsOptions {
|
|
24
|
+
credential?: string;
|
|
25
|
+
endpoint?: string;
|
|
26
|
+
clientDescription?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare class Flexemarkets {
|
|
29
|
+
private readonly _clientDescription;
|
|
30
|
+
private readonly _endpoint;
|
|
31
|
+
private readonly _baseUrl;
|
|
32
|
+
private readonly _bearerToken;
|
|
33
|
+
private _apiRoot;
|
|
34
|
+
private _account;
|
|
35
|
+
private _user;
|
|
36
|
+
private _eventListener;
|
|
37
|
+
private constructor();
|
|
38
|
+
/** Connect to the Flexemarkets API. */
|
|
39
|
+
static connect(credential?: string | null, endpoint?: string | null, clientDescription?: string | null): Promise<Flexemarkets>;
|
|
40
|
+
get account(): Account;
|
|
41
|
+
get accountId(): number;
|
|
42
|
+
get accountName(): string;
|
|
43
|
+
get user(): Person;
|
|
44
|
+
get userId(): number;
|
|
45
|
+
get endpointUrl(): string;
|
|
46
|
+
get endpointMarketplaceId(): number;
|
|
47
|
+
private _authHeaders;
|
|
48
|
+
private _get;
|
|
49
|
+
private _post;
|
|
50
|
+
private _fetchApiRoot;
|
|
51
|
+
marketplaces(): Promise<Marketplace[]>;
|
|
52
|
+
marketplace(marketplaceId: number): Promise<Marketplace>;
|
|
53
|
+
markets(marketplaceId: number): Promise<Market[]>;
|
|
54
|
+
symbols(marketplaceId: number): Promise<string[]>;
|
|
55
|
+
sessions(marketplaceId: number, sessionIds?: number[] | null): Promise<Session[]>;
|
|
56
|
+
session(marketplaceId: number): Promise<Session>;
|
|
57
|
+
submitLimit(marketplaceId: number, marketId: number, side: string, units: number, price: number): Promise<Order>;
|
|
58
|
+
submitCancel(marketplaceId: number, marketId: number, originalId: number): Promise<Order>;
|
|
59
|
+
orders(marketplaceId: number, options?: {
|
|
60
|
+
symbol?: string;
|
|
61
|
+
sessionIds?: number[];
|
|
62
|
+
}): Promise<Order[]>;
|
|
63
|
+
trades(marketplaceId: number, symbol: string): Promise<Order[]>;
|
|
64
|
+
holdings(marketplaceId: number, sessionIds?: number[] | null): Promise<Holding[]>;
|
|
65
|
+
holding(marketplaceId: number): Promise<Holding>;
|
|
66
|
+
connections(marketplaceId: number, sessionIds?: number[] | null): Promise<ClientConnection[]>;
|
|
67
|
+
/** Start receiving real-time events via WebSocket STOMP. */
|
|
68
|
+
listen(marketplaceId: number, callback: EventCallback): Promise<void>;
|
|
69
|
+
/** Reconnect the WebSocket after a transport error. */
|
|
70
|
+
reconnect(): Promise<void>;
|
|
71
|
+
close(): void;
|
|
72
|
+
}
|
|
73
|
+
export {};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flexemarkets API client.
|
|
3
|
+
*
|
|
4
|
+
* Port of fm.client (Python) / fm.Flexemarkets (Java).
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
import { EventListener } from "./stomp.js";
|
|
11
|
+
function readVersion() {
|
|
12
|
+
try {
|
|
13
|
+
const dir = fileURLToPath(new URL(".", import.meta.url));
|
|
14
|
+
return readFileSync(join(dir, "..", "..", "..", "VERSION"), "utf-8").trim();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return "0.0.0";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const FM_NETWORK_CLIENT = `fm-sdk-typescript/${readVersion()}`;
|
|
21
|
+
const DEFAULT_ENDPOINT = "https://fm-data.herokuapp.com";
|
|
22
|
+
const BCRYPT_RE = /^\$2[abxy]?\$\d{2}\$[./A-Za-z0-9]{53}$/;
|
|
23
|
+
const JWT_RE = /^[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+$/;
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Errors
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
export class FlexemarketsError extends Error {
|
|
28
|
+
}
|
|
29
|
+
export class AuthenticationError extends FlexemarketsError {
|
|
30
|
+
}
|
|
31
|
+
export class AuthorizationError extends FlexemarketsError {
|
|
32
|
+
}
|
|
33
|
+
export class InvalidArgumentError extends FlexemarketsError {
|
|
34
|
+
}
|
|
35
|
+
export class ConnectionFailedError extends FlexemarketsError {
|
|
36
|
+
}
|
|
37
|
+
export class ConfigurationError extends FlexemarketsError {
|
|
38
|
+
}
|
|
39
|
+
function parsePerson(data) {
|
|
40
|
+
if (!data)
|
|
41
|
+
return null;
|
|
42
|
+
return {
|
|
43
|
+
id: data.id ?? 0,
|
|
44
|
+
accountId: data.accountId ?? 0,
|
|
45
|
+
firstName: data.firstName ?? null,
|
|
46
|
+
lastName: data.lastName ?? null,
|
|
47
|
+
email: data.email ?? null,
|
|
48
|
+
roles: data.roles ?? [],
|
|
49
|
+
accountOwner: data.accountOwner ?? false,
|
|
50
|
+
createdDate: data.createdDate ?? null,
|
|
51
|
+
lastModifiedDate: data.lastModifiedDate ?? null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function parseAccount(data) {
|
|
55
|
+
if (!data)
|
|
56
|
+
return null;
|
|
57
|
+
return {
|
|
58
|
+
id: data.id ?? null,
|
|
59
|
+
name: data.name ?? null,
|
|
60
|
+
description: data.description ?? null,
|
|
61
|
+
owner: parsePerson(data.owner),
|
|
62
|
+
approval: data.approval ?? false,
|
|
63
|
+
approvalDescription: data.approvalDescription ?? null,
|
|
64
|
+
createdDate: data.createdDate ?? null,
|
|
65
|
+
lastModifiedDate: data.lastModifiedDate ?? null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function parseToken(data) {
|
|
69
|
+
return {
|
|
70
|
+
requestUrl: data.requestUrl ?? null,
|
|
71
|
+
person: parsePerson(data.person),
|
|
72
|
+
account: parseAccount(data.account),
|
|
73
|
+
token: data.token ?? null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function parseSecurity(data) {
|
|
77
|
+
return {
|
|
78
|
+
marketId: data.marketId ?? 0,
|
|
79
|
+
units: data.units ?? 0,
|
|
80
|
+
availableUnits: data.availableUnits ?? 0,
|
|
81
|
+
canBuy: data.canBuy ?? false,
|
|
82
|
+
canSell: data.canSell ?? false,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function parseMarket(data) {
|
|
86
|
+
return {
|
|
87
|
+
id: data.id ?? 0,
|
|
88
|
+
marketplaceId: data.marketplaceId ?? 0,
|
|
89
|
+
name: data.name ?? null,
|
|
90
|
+
description: data.description ?? null,
|
|
91
|
+
symbol: data.symbol ?? null,
|
|
92
|
+
privateMarket: data.privateMarket ?? false,
|
|
93
|
+
priceMinimum: data.priceMinimum ?? 0,
|
|
94
|
+
priceMaximum: data.priceMaximum ?? 0,
|
|
95
|
+
priceTick: data.priceTick ?? 0,
|
|
96
|
+
unitMinimum: data.unitMinimum ?? 0,
|
|
97
|
+
unitMaximum: data.unitMaximum ?? 0,
|
|
98
|
+
unitTick: data.unitTick ?? 0,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function parseMarketplace(data) {
|
|
102
|
+
return {
|
|
103
|
+
id: data.id ?? 0,
|
|
104
|
+
name: data.name ?? null,
|
|
105
|
+
description: data.description ?? null,
|
|
106
|
+
markets: (data.markets ?? []).map(parseMarket),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function parseSession(data) {
|
|
110
|
+
return {
|
|
111
|
+
marketplaceId: data.marketplaceId ?? 0,
|
|
112
|
+
allocationId: data.allocationId ?? 0,
|
|
113
|
+
id: data.id ?? 0,
|
|
114
|
+
original: data.original ?? 0,
|
|
115
|
+
state: data.state ?? null,
|
|
116
|
+
name: data.name ?? null,
|
|
117
|
+
description: data.description ?? null,
|
|
118
|
+
openDate: data.openDate ?? null,
|
|
119
|
+
closeDate: data.closeDate ?? null,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export function parseOrder(data) {
|
|
123
|
+
return {
|
|
124
|
+
id: data.id ?? 0,
|
|
125
|
+
original: data.original ?? 0,
|
|
126
|
+
supplier: data.supplier ?? 0,
|
|
127
|
+
consumer: data.consumer ?? null,
|
|
128
|
+
type: data.type ?? null,
|
|
129
|
+
side: data.side ?? null,
|
|
130
|
+
units: data.units ?? 0,
|
|
131
|
+
price: data.price ?? 0,
|
|
132
|
+
ownerId: data.ownerId ?? null,
|
|
133
|
+
marketplaceId: data.marketplaceId ?? 0,
|
|
134
|
+
sessionId: data.sessionId ?? 0,
|
|
135
|
+
symbol: data.symbol ?? null,
|
|
136
|
+
marketId: data.marketId ?? 0,
|
|
137
|
+
ownerTarget: data.ownerTarget ?? null,
|
|
138
|
+
clientDescription: data.clientDescription ?? null,
|
|
139
|
+
createdDate: data.createdDate ?? null,
|
|
140
|
+
lastModifiedDate: data.lastModifiedDate ?? null,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export function parseHolding(data) {
|
|
144
|
+
const securitiesRaw = data.securities ?? data.assets ?? [];
|
|
145
|
+
return {
|
|
146
|
+
marketplaceId: data.marketplaceId ?? 0,
|
|
147
|
+
sessionId: data.sessionId ?? 0,
|
|
148
|
+
allocationId: data.allocationId ?? 0,
|
|
149
|
+
ownerId: data.ownerId ?? 0,
|
|
150
|
+
name: data.name ?? null,
|
|
151
|
+
cash: data.cash ?? 0,
|
|
152
|
+
availableCash: data.availableCash ?? 0,
|
|
153
|
+
securities: securitiesRaw.map(parseSecurity),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function parseConnection(data) {
|
|
157
|
+
return {
|
|
158
|
+
marketplaceId: data.marketplaceId ?? 0,
|
|
159
|
+
connectionId: data.connectionId ?? 0,
|
|
160
|
+
ownerId: data.ownerId ?? 0,
|
|
161
|
+
established: data.established ?? null,
|
|
162
|
+
terminated: data.terminated ?? null,
|
|
163
|
+
description: data.description ?? null,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function parseApiRoot(data) {
|
|
167
|
+
const linksRaw = data._links ?? {};
|
|
168
|
+
const links = {};
|
|
169
|
+
for (const [name, value] of Object.entries(linksRaw)) {
|
|
170
|
+
if (typeof value === "object" && value !== null && "href" in value) {
|
|
171
|
+
links[name] = value.href ?? "";
|
|
172
|
+
}
|
|
173
|
+
else if (typeof value === "string") {
|
|
174
|
+
links[name] = value;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { links };
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// HATEOAS link resolution
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
function processTemplate(href) {
|
|
183
|
+
const idx = href.indexOf("{");
|
|
184
|
+
return idx >= 0 ? href.substring(0, idx) : href;
|
|
185
|
+
}
|
|
186
|
+
function uri(root, linkName) {
|
|
187
|
+
const href = root.links[linkName];
|
|
188
|
+
if (href === undefined)
|
|
189
|
+
throw new Error(`Link '${linkName}' not found in API root.`);
|
|
190
|
+
return processTemplate(href);
|
|
191
|
+
}
|
|
192
|
+
function uriId(root, linkName, id) {
|
|
193
|
+
return `${uri(root, linkName)}/${id}`;
|
|
194
|
+
}
|
|
195
|
+
function uriIdSegment(root, linkName, id, segment) {
|
|
196
|
+
return `${uriId(root, linkName, id)}/${segment}`;
|
|
197
|
+
}
|
|
198
|
+
function uriParam(root, linkName, param) {
|
|
199
|
+
return `${uri(root, linkName)}?${param}`;
|
|
200
|
+
}
|
|
201
|
+
function uriIdSegmentParam(root, linkName, id, segment, param) {
|
|
202
|
+
const base = uriIdSegment(root, linkName, id, segment);
|
|
203
|
+
return param ? `${base}?${param}` : base;
|
|
204
|
+
}
|
|
205
|
+
function uriParamMarketplaceIdParam(root, linkName, id, param) {
|
|
206
|
+
let u = uriParam(root, linkName, `marketplaceId=${id}`);
|
|
207
|
+
if (param)
|
|
208
|
+
u += `&${param}`;
|
|
209
|
+
return u;
|
|
210
|
+
}
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// Credential / configuration helpers
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
function isValidToken(value) {
|
|
215
|
+
return BCRYPT_RE.test(value) || JWT_RE.test(value);
|
|
216
|
+
}
|
|
217
|
+
function server(endpoint) {
|
|
218
|
+
const idx = endpoint.indexOf("/api");
|
|
219
|
+
return idx < 0 ? endpoint : endpoint.substring(0, idx + 4);
|
|
220
|
+
}
|
|
221
|
+
function resourceId(endpoint) {
|
|
222
|
+
const trimmed = endpoint.replace(/\/+$/, "");
|
|
223
|
+
const last = trimmed.lastIndexOf("/");
|
|
224
|
+
return parseInt(trimmed.substring(last + 1), 10);
|
|
225
|
+
}
|
|
226
|
+
function sessionIdsParam(sessionIds) {
|
|
227
|
+
if (!sessionIds || sessionIds.length === 0)
|
|
228
|
+
return "";
|
|
229
|
+
return "sessionIds=" + sessionIds.join(",");
|
|
230
|
+
}
|
|
231
|
+
function loadPropertiesFile(path) {
|
|
232
|
+
const props = {};
|
|
233
|
+
if (!existsSync(path))
|
|
234
|
+
return props;
|
|
235
|
+
const content = readFileSync(path, "utf-8");
|
|
236
|
+
for (const line of content.split("\n")) {
|
|
237
|
+
const trimmed = line.trim();
|
|
238
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
239
|
+
continue;
|
|
240
|
+
const eqIdx = trimmed.indexOf("=");
|
|
241
|
+
if (eqIdx >= 0) {
|
|
242
|
+
props[trimmed.substring(0, eqIdx).trim()] = trimmed.substring(eqIdx + 1).trim();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return props;
|
|
246
|
+
}
|
|
247
|
+
function loadConfig() {
|
|
248
|
+
const config = {};
|
|
249
|
+
const fmDir = join(homedir(), ".fm");
|
|
250
|
+
Object.assign(config, loadPropertiesFile(join(fmDir, "credential")));
|
|
251
|
+
Object.assign(config, loadPropertiesFile(join(fmDir, "endpoint")));
|
|
252
|
+
const envUrl = process.env.FM_API_URL;
|
|
253
|
+
if (envUrl)
|
|
254
|
+
config.endpoint = envUrl;
|
|
255
|
+
if (!config.endpoint)
|
|
256
|
+
config.endpoint = DEFAULT_ENDPOINT;
|
|
257
|
+
return config;
|
|
258
|
+
}
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
// Response handling
|
|
261
|
+
// ---------------------------------------------------------------------------
|
|
262
|
+
function checkResponse(response, body) {
|
|
263
|
+
const status = response.status;
|
|
264
|
+
if (status >= 200 && status < 300)
|
|
265
|
+
return;
|
|
266
|
+
if (status === 400)
|
|
267
|
+
throw new InvalidArgumentError(body);
|
|
268
|
+
if (status === 401)
|
|
269
|
+
throw new AuthenticationError(body);
|
|
270
|
+
if (status === 403)
|
|
271
|
+
throw new AuthorizationError(body);
|
|
272
|
+
if (status >= 500)
|
|
273
|
+
throw new ConnectionFailedError(body);
|
|
274
|
+
throw new FlexemarketsError(`HTTP ${status}: ${body}`);
|
|
275
|
+
}
|
|
276
|
+
export class Flexemarkets {
|
|
277
|
+
_clientDescription;
|
|
278
|
+
_endpoint;
|
|
279
|
+
_baseUrl;
|
|
280
|
+
_bearerToken;
|
|
281
|
+
_apiRoot;
|
|
282
|
+
_account;
|
|
283
|
+
_user;
|
|
284
|
+
_eventListener = null;
|
|
285
|
+
constructor(endpoint, baseUrl, bearerToken, clientDescription) {
|
|
286
|
+
this._endpoint = endpoint;
|
|
287
|
+
this._baseUrl = baseUrl;
|
|
288
|
+
this._bearerToken = bearerToken;
|
|
289
|
+
this._clientDescription = clientDescription;
|
|
290
|
+
}
|
|
291
|
+
/** Connect to the Flexemarkets API. */
|
|
292
|
+
static async connect(credential, endpoint, clientDescription) {
|
|
293
|
+
const desc = clientDescription ?? "Unspecified client";
|
|
294
|
+
const config = loadConfig();
|
|
295
|
+
if (credential != null) {
|
|
296
|
+
if (existsSync(credential)) {
|
|
297
|
+
Object.assign(config, loadPropertiesFile(credential));
|
|
298
|
+
}
|
|
299
|
+
else if (isValidToken(credential)) {
|
|
300
|
+
config.token = credential;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
throw new ConfigurationError(`Invalid credential: '${credential}' is not a file or token.`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (endpoint != null) {
|
|
307
|
+
if (existsSync(endpoint)) {
|
|
308
|
+
Object.assign(config, loadPropertiesFile(endpoint));
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
config.endpoint = endpoint;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const ep = config.endpoint ?? DEFAULT_ENDPOINT;
|
|
315
|
+
const baseUrl = server(ep);
|
|
316
|
+
// Authenticate
|
|
317
|
+
const tokenObj = await signIn(baseUrl, config, desc);
|
|
318
|
+
const bearer = `Bearer ${tokenObj.token}`;
|
|
319
|
+
const fm = new Flexemarkets(ep, baseUrl, bearer, desc);
|
|
320
|
+
fm._account = tokenObj.account;
|
|
321
|
+
fm._user = tokenObj.person;
|
|
322
|
+
// Fetch API root for HATEOAS links
|
|
323
|
+
fm._apiRoot = await fm._fetchApiRoot();
|
|
324
|
+
return fm;
|
|
325
|
+
}
|
|
326
|
+
// -- properties ------------------------------------------------------------
|
|
327
|
+
get account() {
|
|
328
|
+
return this._account;
|
|
329
|
+
}
|
|
330
|
+
get accountId() {
|
|
331
|
+
return this._account.id;
|
|
332
|
+
}
|
|
333
|
+
get accountName() {
|
|
334
|
+
return this._account.name;
|
|
335
|
+
}
|
|
336
|
+
get user() {
|
|
337
|
+
return this._user;
|
|
338
|
+
}
|
|
339
|
+
get userId() {
|
|
340
|
+
return this._user.id;
|
|
341
|
+
}
|
|
342
|
+
get endpointUrl() {
|
|
343
|
+
return this._endpoint;
|
|
344
|
+
}
|
|
345
|
+
get endpointMarketplaceId() {
|
|
346
|
+
return resourceId(this._endpoint);
|
|
347
|
+
}
|
|
348
|
+
// -- internal HTTP helpers -------------------------------------------------
|
|
349
|
+
_authHeaders() {
|
|
350
|
+
return { Authorization: this._bearerToken };
|
|
351
|
+
}
|
|
352
|
+
async _get(url) {
|
|
353
|
+
const resp = await fetch(url.startsWith("/") ? `${this._baseUrl}${url}` : url, {
|
|
354
|
+
headers: {
|
|
355
|
+
...this._authHeaders(),
|
|
356
|
+
Accept: "application/json, application/hal+json",
|
|
357
|
+
"User-Agent": FM_NETWORK_CLIENT,
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
const body = await resp.text();
|
|
361
|
+
checkResponse(resp, body);
|
|
362
|
+
return JSON.parse(body);
|
|
363
|
+
}
|
|
364
|
+
async _post(url, json) {
|
|
365
|
+
const resp = await fetch(url.startsWith("/") ? `${this._baseUrl}${url}` : url, {
|
|
366
|
+
method: "POST",
|
|
367
|
+
headers: {
|
|
368
|
+
...this._authHeaders(),
|
|
369
|
+
"Content-Type": "application/json",
|
|
370
|
+
Accept: "application/json, application/hal+json",
|
|
371
|
+
"User-Agent": FM_NETWORK_CLIENT,
|
|
372
|
+
},
|
|
373
|
+
body: JSON.stringify(json),
|
|
374
|
+
});
|
|
375
|
+
const body = await resp.text();
|
|
376
|
+
checkResponse(resp, body);
|
|
377
|
+
return JSON.parse(body);
|
|
378
|
+
}
|
|
379
|
+
async _fetchApiRoot() {
|
|
380
|
+
const data = await this._get(this._baseUrl);
|
|
381
|
+
return parseApiRoot(data);
|
|
382
|
+
}
|
|
383
|
+
// ======================================================================
|
|
384
|
+
// REST APIs
|
|
385
|
+
// ======================================================================
|
|
386
|
+
// -- marketplaces ----------------------------------------------------------
|
|
387
|
+
async marketplaces() {
|
|
388
|
+
const url = uriParam(this._apiRoot, "marketplaces", "format=application/json");
|
|
389
|
+
const data = await this._get(url);
|
|
390
|
+
return data.map(parseMarketplace);
|
|
391
|
+
}
|
|
392
|
+
async marketplace(marketplaceId) {
|
|
393
|
+
const url = uriId(this._apiRoot, "marketplaces", marketplaceId);
|
|
394
|
+
return parseMarketplace(await this._get(url));
|
|
395
|
+
}
|
|
396
|
+
// -- markets ---------------------------------------------------------------
|
|
397
|
+
async markets(marketplaceId) {
|
|
398
|
+
const url = uriIdSegmentParam(this._apiRoot, "marketplaces", marketplaceId, "markets", "format=application/json");
|
|
399
|
+
const data = await this._get(url);
|
|
400
|
+
return data.map(parseMarket);
|
|
401
|
+
}
|
|
402
|
+
async symbols(marketplaceId) {
|
|
403
|
+
const url = uriIdSegment(this._apiRoot, "marketplaces", marketplaceId, "symbols");
|
|
404
|
+
return (await this._get(url));
|
|
405
|
+
}
|
|
406
|
+
// -- sessions --------------------------------------------------------------
|
|
407
|
+
async sessions(marketplaceId, sessionIds) {
|
|
408
|
+
let url;
|
|
409
|
+
if (sessionIds && sessionIds.length > 0) {
|
|
410
|
+
url = uriIdSegmentParam(this._apiRoot, "marketplaces", marketplaceId, "sessions", `${sessionIdsParam(sessionIds)}&format=application/json`);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
url = uriIdSegmentParam(this._apiRoot, "marketplaces", marketplaceId, "sessions", "format=application/json");
|
|
414
|
+
}
|
|
415
|
+
const data = await this._get(url);
|
|
416
|
+
return data.map(parseSession);
|
|
417
|
+
}
|
|
418
|
+
async session(marketplaceId) {
|
|
419
|
+
const url = uriIdSegment(this._apiRoot, "marketplaces", marketplaceId, "currentSession");
|
|
420
|
+
return parseSession(await this._get(url));
|
|
421
|
+
}
|
|
422
|
+
// -- orders ----------------------------------------------------------------
|
|
423
|
+
async submitLimit(marketplaceId, marketId, side, units, price) {
|
|
424
|
+
const url = uri(this._apiRoot, "orders");
|
|
425
|
+
const data = await this._post(url, {
|
|
426
|
+
marketplaceId,
|
|
427
|
+
marketId,
|
|
428
|
+
type: "LIMIT",
|
|
429
|
+
side,
|
|
430
|
+
units,
|
|
431
|
+
price,
|
|
432
|
+
clientDescription: this._clientDescription,
|
|
433
|
+
});
|
|
434
|
+
return parseOrder(data);
|
|
435
|
+
}
|
|
436
|
+
async submitCancel(marketplaceId, marketId, originalId) {
|
|
437
|
+
const url = uri(this._apiRoot, "orders");
|
|
438
|
+
const data = await this._post(url, {
|
|
439
|
+
marketplaceId,
|
|
440
|
+
marketId,
|
|
441
|
+
type: "CANCEL",
|
|
442
|
+
id: originalId,
|
|
443
|
+
original: originalId,
|
|
444
|
+
supplier: originalId,
|
|
445
|
+
clientDescription: this._clientDescription,
|
|
446
|
+
});
|
|
447
|
+
return parseOrder(data);
|
|
448
|
+
}
|
|
449
|
+
async orders(marketplaceId, options) {
|
|
450
|
+
if (options?.symbol != null) {
|
|
451
|
+
const url = uriParamMarketplaceIdParam(this._apiRoot, "symbolOrdersJson", marketplaceId, `symbol=${options.symbol}`);
|
|
452
|
+
const data = await this._get(url);
|
|
453
|
+
const orders = data.map(parseOrder);
|
|
454
|
+
for (const o of orders)
|
|
455
|
+
o.symbol = options.symbol;
|
|
456
|
+
return orders;
|
|
457
|
+
}
|
|
458
|
+
if (options?.sessionIds != null) {
|
|
459
|
+
const url = uriParamMarketplaceIdParam(this._apiRoot, "sessionOrdersJson", marketplaceId, sessionIdsParam(options.sessionIds));
|
|
460
|
+
const data = await this._get(url);
|
|
461
|
+
return data.map(parseOrder);
|
|
462
|
+
}
|
|
463
|
+
const url = uriIdSegment(this._apiRoot, "marketplaces", marketplaceId, "orders");
|
|
464
|
+
const data = await this._get(url);
|
|
465
|
+
return data.map(parseOrder);
|
|
466
|
+
}
|
|
467
|
+
async trades(marketplaceId, symbol) {
|
|
468
|
+
const url = uriParamMarketplaceIdParam(this._apiRoot, "symbolTradesJson", marketplaceId, `symbol=${symbol}`);
|
|
469
|
+
const data = await this._get(url);
|
|
470
|
+
const orders = data.map(parseOrder);
|
|
471
|
+
for (const o of orders)
|
|
472
|
+
o.symbol = symbol;
|
|
473
|
+
return orders;
|
|
474
|
+
}
|
|
475
|
+
// -- holdings --------------------------------------------------------------
|
|
476
|
+
async holdings(marketplaceId, sessionIds) {
|
|
477
|
+
let url;
|
|
478
|
+
if (sessionIds && sessionIds.length > 0) {
|
|
479
|
+
url = uriIdSegmentParam(this._apiRoot, "marketplaces", marketplaceId, "holdings", `sessions=${sessionIds.join(",")}`);
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
url = uriIdSegment(this._apiRoot, "marketplaces", marketplaceId, "holdings");
|
|
483
|
+
}
|
|
484
|
+
const data = await this._get(url);
|
|
485
|
+
return data.map(parseHolding);
|
|
486
|
+
}
|
|
487
|
+
async holding(marketplaceId) {
|
|
488
|
+
const url = uriIdSegment(this._apiRoot, "marketplaces", marketplaceId, "currentHolding");
|
|
489
|
+
return parseHolding(await this._get(url));
|
|
490
|
+
}
|
|
491
|
+
// -- connections -----------------------------------------------------------
|
|
492
|
+
async connections(marketplaceId, sessionIds) {
|
|
493
|
+
const url = uriIdSegmentParam(this._apiRoot, "marketplaces", marketplaceId, "connections", sessionIdsParam(sessionIds ?? null));
|
|
494
|
+
const data = await this._get(url);
|
|
495
|
+
return data.map(parseConnection);
|
|
496
|
+
}
|
|
497
|
+
// -- events / WebSocket ----------------------------------------------------
|
|
498
|
+
/** Start receiving real-time events via WebSocket STOMP. */
|
|
499
|
+
async listen(marketplaceId, callback) {
|
|
500
|
+
const wsUrl = server(this._endpoint)
|
|
501
|
+
.replace("https://", "wss://")
|
|
502
|
+
.replace("http://", "ws://") + "/events";
|
|
503
|
+
this._eventListener = new EventListener(wsUrl, this._bearerToken, marketplaceId, callback, this._clientDescription, parseHolding, parseOrder);
|
|
504
|
+
await this._eventListener.start();
|
|
505
|
+
}
|
|
506
|
+
/** Reconnect the WebSocket after a transport error. */
|
|
507
|
+
async reconnect() {
|
|
508
|
+
if (this._eventListener !== null) {
|
|
509
|
+
await this._eventListener.reconnect();
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// -- lifecycle -------------------------------------------------------------
|
|
513
|
+
close() {
|
|
514
|
+
if (this._eventListener !== null) {
|
|
515
|
+
this._eventListener.close();
|
|
516
|
+
this._eventListener = null;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// ---------------------------------------------------------------------------
|
|
521
|
+
// Authentication
|
|
522
|
+
// ---------------------------------------------------------------------------
|
|
523
|
+
async function signIn(baseUrl, config, clientDescription) {
|
|
524
|
+
const tok = config.token ?? "";
|
|
525
|
+
if (tok && isValidToken(tok)) {
|
|
526
|
+
const authUrl = `${baseUrl}/tokens`;
|
|
527
|
+
const resp = await fetch(authUrl, {
|
|
528
|
+
method: "POST",
|
|
529
|
+
headers: {
|
|
530
|
+
Authorization: `Bearer ${tok}`,
|
|
531
|
+
"Content-Type": "application/json",
|
|
532
|
+
Accept: "application/json",
|
|
533
|
+
"User-Agent": FM_NETWORK_CLIENT,
|
|
534
|
+
},
|
|
535
|
+
body: JSON.stringify({
|
|
536
|
+
username: `${config.account ?? ""}|${config.email ?? ""}`,
|
|
537
|
+
password: "",
|
|
538
|
+
}),
|
|
539
|
+
});
|
|
540
|
+
const body = await resp.text();
|
|
541
|
+
if (resp.status === 401) {
|
|
542
|
+
throw new AuthenticationError("Authentication failed with provided token.");
|
|
543
|
+
}
|
|
544
|
+
checkResponse(resp, body);
|
|
545
|
+
return parseToken(JSON.parse(body));
|
|
546
|
+
}
|
|
547
|
+
const acct = config.account ?? "";
|
|
548
|
+
const email = config.email ?? "";
|
|
549
|
+
const password = config.password ?? "";
|
|
550
|
+
if (!acct)
|
|
551
|
+
throw new ConfigurationError("Missing 'account' in configuration.");
|
|
552
|
+
if (!email)
|
|
553
|
+
throw new ConfigurationError("Missing 'email' in configuration.");
|
|
554
|
+
if (!password)
|
|
555
|
+
throw new ConfigurationError("Missing 'password' in configuration.");
|
|
556
|
+
const authUrl = `${baseUrl}/tokens`;
|
|
557
|
+
const resp = await fetch(authUrl, {
|
|
558
|
+
method: "POST",
|
|
559
|
+
headers: {
|
|
560
|
+
"Content-Type": "application/json",
|
|
561
|
+
Accept: "application/json",
|
|
562
|
+
"User-Agent": FM_NETWORK_CLIENT,
|
|
563
|
+
},
|
|
564
|
+
body: JSON.stringify({
|
|
565
|
+
username: `${acct}|${email}`,
|
|
566
|
+
password,
|
|
567
|
+
}),
|
|
568
|
+
});
|
|
569
|
+
const body = await resp.text();
|
|
570
|
+
if (resp.status === 401) {
|
|
571
|
+
throw new AuthenticationError("Authentication failed.");
|
|
572
|
+
}
|
|
573
|
+
checkResponse(resp, body);
|
|
574
|
+
return parseToken(JSON.parse(body));
|
|
575
|
+
}
|
|
576
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|