@danielgroen/dxtrade-api 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.d.mts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +50 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
declare const BROKER: {
|
|
2
2
|
readonly LARKFUNDING: "https://trade.gooeytrade.com";
|
|
3
3
|
readonly EIGHTCAP: "https://trader.dx-eightcap.com";
|
|
4
|
+
readonly FTMO: "https://dxtrade.ftmo.com";
|
|
4
5
|
};
|
|
5
|
-
declare function resolveBrokerUrl(broker: string, customUrls?: Record<string, string>): string;
|
|
6
6
|
|
|
7
7
|
declare const endpoints: {
|
|
8
8
|
login: (base: string) => string;
|
|
@@ -12,6 +12,10 @@ declare const endpoints: {
|
|
|
12
12
|
submitOrder: (base: string) => string;
|
|
13
13
|
assessments: (base: string) => string;
|
|
14
14
|
websocket: (base: string) => string;
|
|
15
|
+
tradeJournal: (base: string, params: {
|
|
16
|
+
from: number;
|
|
17
|
+
to: number;
|
|
18
|
+
}) => string;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
declare enum ORDER_TYPE {
|
|
@@ -144,7 +148,7 @@ declare namespace Order {
|
|
|
144
148
|
interface DxtradeConfig {
|
|
145
149
|
username: string;
|
|
146
150
|
password: string;
|
|
147
|
-
broker:
|
|
151
|
+
broker: keyof typeof BROKER;
|
|
148
152
|
accountId?: string;
|
|
149
153
|
brokerUrls?: Record<string, string>;
|
|
150
154
|
retries?: number;
|
|
@@ -186,7 +190,7 @@ declare namespace Assessments {
|
|
|
186
190
|
from: number;
|
|
187
191
|
to: number;
|
|
188
192
|
instrument: string;
|
|
189
|
-
subtype?:
|
|
193
|
+
subtype?: "Agriculture" | "Cash CFD" | "Cash II CFD" | "Cash III CFD" | "Commodities" | "Crypto I CFD" | "Crypto II CFD" | "Equities I CFD" | "Equities II CFD" | "Exotics" | "Forex" | "Metals CFD" | null;
|
|
190
194
|
}
|
|
191
195
|
interface Response {
|
|
192
196
|
totalPL?: number;
|
|
@@ -272,8 +276,12 @@ declare class DxtradeClient {
|
|
|
272
276
|
getSymbolLimits(): Promise<Symbol.Limits[]>;
|
|
273
277
|
submitOrder(params: Order.SubmitParams): Promise<Order.Update>;
|
|
274
278
|
getAccountMetrics(): Promise<Account.Metrics>;
|
|
279
|
+
getTradeJournal(params: {
|
|
280
|
+
from: number;
|
|
281
|
+
to: number;
|
|
282
|
+
}): Promise<any>;
|
|
275
283
|
getInstruments(params?: Partial<Instrument.Info>): Promise<Instrument.Info[]>;
|
|
276
284
|
getAssessments(params: Assessments.Params): Promise<Assessments.Response>;
|
|
277
285
|
}
|
|
278
286
|
|
|
279
|
-
export { ACTION, BROKER, type DxtradeCallbacks, DxtradeClient, type DxtradeConfig, DxtradeError, ORDER_TYPE, SIDE, TIF, WS_MESSAGE, type WsPayload, endpoints
|
|
287
|
+
export { ACTION, BROKER, type DxtradeCallbacks, DxtradeClient, type DxtradeConfig, DxtradeError, ORDER_TYPE, SIDE, TIF, WS_MESSAGE, type WsPayload, endpoints };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
declare const BROKER: {
|
|
2
2
|
readonly LARKFUNDING: "https://trade.gooeytrade.com";
|
|
3
3
|
readonly EIGHTCAP: "https://trader.dx-eightcap.com";
|
|
4
|
+
readonly FTMO: "https://dxtrade.ftmo.com";
|
|
4
5
|
};
|
|
5
|
-
declare function resolveBrokerUrl(broker: string, customUrls?: Record<string, string>): string;
|
|
6
6
|
|
|
7
7
|
declare const endpoints: {
|
|
8
8
|
login: (base: string) => string;
|
|
@@ -12,6 +12,10 @@ declare const endpoints: {
|
|
|
12
12
|
submitOrder: (base: string) => string;
|
|
13
13
|
assessments: (base: string) => string;
|
|
14
14
|
websocket: (base: string) => string;
|
|
15
|
+
tradeJournal: (base: string, params: {
|
|
16
|
+
from: number;
|
|
17
|
+
to: number;
|
|
18
|
+
}) => string;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
declare enum ORDER_TYPE {
|
|
@@ -144,7 +148,7 @@ declare namespace Order {
|
|
|
144
148
|
interface DxtradeConfig {
|
|
145
149
|
username: string;
|
|
146
150
|
password: string;
|
|
147
|
-
broker:
|
|
151
|
+
broker: keyof typeof BROKER;
|
|
148
152
|
accountId?: string;
|
|
149
153
|
brokerUrls?: Record<string, string>;
|
|
150
154
|
retries?: number;
|
|
@@ -186,7 +190,7 @@ declare namespace Assessments {
|
|
|
186
190
|
from: number;
|
|
187
191
|
to: number;
|
|
188
192
|
instrument: string;
|
|
189
|
-
subtype?:
|
|
193
|
+
subtype?: "Agriculture" | "Cash CFD" | "Cash II CFD" | "Cash III CFD" | "Commodities" | "Crypto I CFD" | "Crypto II CFD" | "Equities I CFD" | "Equities II CFD" | "Exotics" | "Forex" | "Metals CFD" | null;
|
|
190
194
|
}
|
|
191
195
|
interface Response {
|
|
192
196
|
totalPL?: number;
|
|
@@ -272,8 +276,12 @@ declare class DxtradeClient {
|
|
|
272
276
|
getSymbolLimits(): Promise<Symbol.Limits[]>;
|
|
273
277
|
submitOrder(params: Order.SubmitParams): Promise<Order.Update>;
|
|
274
278
|
getAccountMetrics(): Promise<Account.Metrics>;
|
|
279
|
+
getTradeJournal(params: {
|
|
280
|
+
from: number;
|
|
281
|
+
to: number;
|
|
282
|
+
}): Promise<any>;
|
|
275
283
|
getInstruments(params?: Partial<Instrument.Info>): Promise<Instrument.Info[]>;
|
|
276
284
|
getAssessments(params: Assessments.Params): Promise<Assessments.Response>;
|
|
277
285
|
}
|
|
278
286
|
|
|
279
|
-
export { ACTION, BROKER, type DxtradeCallbacks, DxtradeClient, type DxtradeConfig, DxtradeError, ORDER_TYPE, SIDE, TIF, WS_MESSAGE, type WsPayload, endpoints
|
|
287
|
+
export { ACTION, BROKER, type DxtradeCallbacks, DxtradeClient, type DxtradeConfig, DxtradeError, ORDER_TYPE, SIDE, TIF, WS_MESSAGE, type WsPayload, endpoints };
|
package/dist/index.js
CHANGED
|
@@ -38,24 +38,16 @@ __export(index_exports, {
|
|
|
38
38
|
SIDE: () => SIDE,
|
|
39
39
|
TIF: () => TIF,
|
|
40
40
|
WS_MESSAGE: () => WS_MESSAGE,
|
|
41
|
-
endpoints: () => endpoints
|
|
42
|
-
resolveBrokerUrl: () => resolveBrokerUrl
|
|
41
|
+
endpoints: () => endpoints
|
|
43
42
|
});
|
|
44
43
|
module.exports = __toCommonJS(index_exports);
|
|
45
44
|
|
|
46
45
|
// src/constants/brokers.ts
|
|
47
46
|
var BROKER = {
|
|
48
47
|
LARKFUNDING: "https://trade.gooeytrade.com",
|
|
49
|
-
EIGHTCAP: "https://trader.dx-eightcap.com"
|
|
48
|
+
EIGHTCAP: "https://trader.dx-eightcap.com",
|
|
49
|
+
FTMO: "https://dxtrade.ftmo.com"
|
|
50
50
|
};
|
|
51
|
-
function resolveBrokerUrl(broker, customUrls) {
|
|
52
|
-
if (customUrls?.[broker]) return customUrls[broker];
|
|
53
|
-
const key = broker.toUpperCase();
|
|
54
|
-
if (BROKER[key]) {
|
|
55
|
-
return BROKER[key];
|
|
56
|
-
}
|
|
57
|
-
return `https://dxtrade.${broker}.com`;
|
|
58
|
-
}
|
|
59
51
|
|
|
60
52
|
// src/constants/endpoints.ts
|
|
61
53
|
var websocketQuery = `?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.2-javascript&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true&sessionState=dx-new&guest-mode=false`;
|
|
@@ -66,7 +58,8 @@ var endpoints = {
|
|
|
66
58
|
instrumentInfo: (base, symbol, tzOffset) => `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,
|
|
67
59
|
submitOrder: (base) => `${base}/api/orders/single`,
|
|
68
60
|
assessments: (base) => `${base}/api/assessments`,
|
|
69
|
-
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery
|
|
61
|
+
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery,
|
|
62
|
+
tradeJournal: (base, params) => `${base}/api/tradejournal?from=${params.from}&to=${params.to}`
|
|
70
63
|
};
|
|
71
64
|
|
|
72
65
|
// src/constants/enums.ts
|
|
@@ -209,7 +202,7 @@ function parseWsData(data) {
|
|
|
209
202
|
// src/domains/account/account.ts
|
|
210
203
|
async function getAccountMetrics(ctx, timeout = 3e4) {
|
|
211
204
|
ctx.ensureSession();
|
|
212
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
205
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
213
206
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
214
207
|
return new Promise((resolve, reject) => {
|
|
215
208
|
const ws = new import_ws.default(wsUrl, { headers: { Cookie: cookieStr } });
|
|
@@ -235,6 +228,32 @@ async function getAccountMetrics(ctx, timeout = 3e4) {
|
|
|
235
228
|
});
|
|
236
229
|
});
|
|
237
230
|
}
|
|
231
|
+
async function getTradeJournal(ctx, params) {
|
|
232
|
+
ctx.ensureSession();
|
|
233
|
+
try {
|
|
234
|
+
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
235
|
+
const response = await retryRequest(
|
|
236
|
+
{
|
|
237
|
+
method: "GET",
|
|
238
|
+
url: endpoints.tradeJournal(ctx.broker, params),
|
|
239
|
+
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
240
|
+
},
|
|
241
|
+
ctx.retries
|
|
242
|
+
);
|
|
243
|
+
if (response.status === 200) {
|
|
244
|
+
const setCookies = response.headers["set-cookie"] ?? [];
|
|
245
|
+
const incoming = Cookies.parse(setCookies);
|
|
246
|
+
ctx.cookies = Cookies.merge(ctx.cookies, incoming);
|
|
247
|
+
return response.data;
|
|
248
|
+
} else {
|
|
249
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Login failed: ${response.status}`);
|
|
250
|
+
}
|
|
251
|
+
} catch (error) {
|
|
252
|
+
if (error instanceof DxtradeError) throw error;
|
|
253
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
254
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Trade journal error: ${message}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
238
257
|
|
|
239
258
|
// src/domains/assessments/assessments.ts
|
|
240
259
|
async function getAssessments(ctx, params) {
|
|
@@ -243,7 +262,7 @@ async function getAssessments(ctx, params) {
|
|
|
243
262
|
const response = await retryRequest(
|
|
244
263
|
{
|
|
245
264
|
method: "POST",
|
|
246
|
-
url: endpoints.assessments(ctx.
|
|
265
|
+
url: endpoints.assessments(ctx.broker),
|
|
247
266
|
data: {
|
|
248
267
|
from: params.from,
|
|
249
268
|
instrument: params.instrument,
|
|
@@ -266,7 +285,7 @@ async function getAssessments(ctx, params) {
|
|
|
266
285
|
var import_ws2 = __toESM(require("ws"));
|
|
267
286
|
async function getInstruments(ctx, params = {}, timeout = 3e4) {
|
|
268
287
|
ctx.ensureSession();
|
|
269
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
288
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
270
289
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
271
290
|
return new Promise((resolve, reject) => {
|
|
272
291
|
const ws = new import_ws2.default(wsUrl, { headers: { Cookie: cookieStr } });
|
|
@@ -320,7 +339,7 @@ async function getSymbolSuggestions(ctx, text) {
|
|
|
320
339
|
const response = await retryRequest(
|
|
321
340
|
{
|
|
322
341
|
method: "GET",
|
|
323
|
-
url: endpoints.suggest(ctx.
|
|
342
|
+
url: endpoints.suggest(ctx.broker, text),
|
|
324
343
|
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
325
344
|
},
|
|
326
345
|
ctx.retries
|
|
@@ -344,7 +363,7 @@ async function getSymbolInfo(ctx, symbol) {
|
|
|
344
363
|
const response = await retryRequest(
|
|
345
364
|
{
|
|
346
365
|
method: "GET",
|
|
347
|
-
url: endpoints.instrumentInfo(ctx.
|
|
366
|
+
url: endpoints.instrumentInfo(ctx.broker, symbol, offsetMinutes),
|
|
348
367
|
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
349
368
|
},
|
|
350
369
|
ctx.retries
|
|
@@ -361,7 +380,7 @@ async function getSymbolInfo(ctx, symbol) {
|
|
|
361
380
|
}
|
|
362
381
|
async function getSymbolLimits(ctx, timeout = 3e4) {
|
|
363
382
|
ctx.ensureSession();
|
|
364
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
383
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
365
384
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
366
385
|
return new Promise((resolve, reject) => {
|
|
367
386
|
const ws = new import_ws3.default(wsUrl, { headers: { Cookie: cookieStr } });
|
|
@@ -531,14 +550,14 @@ async function submitOrder(ctx, params) {
|
|
|
531
550
|
};
|
|
532
551
|
}
|
|
533
552
|
try {
|
|
534
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
553
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
535
554
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
536
555
|
const listener = createOrderListener(wsUrl, cookieStr, 3e4, ctx.debug);
|
|
537
556
|
await listener.ready;
|
|
538
557
|
const response = await retryRequest(
|
|
539
558
|
{
|
|
540
559
|
method: "POST",
|
|
541
|
-
url: endpoints.submitOrder(ctx.
|
|
560
|
+
url: endpoints.submitOrder(ctx.broker),
|
|
542
561
|
data: orderData,
|
|
543
562
|
headers: authHeaders(ctx.csrf, Cookies.serialize(ctx.cookies))
|
|
544
563
|
},
|
|
@@ -586,7 +605,7 @@ async function login(ctx) {
|
|
|
586
605
|
const response = await retryRequest(
|
|
587
606
|
{
|
|
588
607
|
method: "POST",
|
|
589
|
-
url: endpoints.login(ctx.
|
|
608
|
+
url: endpoints.login(ctx.broker),
|
|
590
609
|
data: {
|
|
591
610
|
username: ctx.config.username,
|
|
592
611
|
password: ctx.config.password,
|
|
@@ -616,8 +635,8 @@ async function fetchCsrf(ctx) {
|
|
|
616
635
|
const response = await retryRequest(
|
|
617
636
|
{
|
|
618
637
|
method: "GET",
|
|
619
|
-
url: ctx.
|
|
620
|
-
headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.
|
|
638
|
+
url: ctx.broker,
|
|
639
|
+
headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.broker }
|
|
621
640
|
},
|
|
622
641
|
ctx.retries
|
|
623
642
|
);
|
|
@@ -639,7 +658,7 @@ async function switchAccount(ctx, accountId) {
|
|
|
639
658
|
await retryRequest(
|
|
640
659
|
{
|
|
641
660
|
method: "POST",
|
|
642
|
-
url: endpoints.switchAccount(ctx.
|
|
661
|
+
url: endpoints.switchAccount(ctx.broker, accountId),
|
|
643
662
|
headers: authHeaders(ctx.csrf, Cookies.serialize(ctx.cookies))
|
|
644
663
|
},
|
|
645
664
|
ctx.retries
|
|
@@ -655,12 +674,12 @@ async function connect(ctx) {
|
|
|
655
674
|
await login(ctx);
|
|
656
675
|
await fetchCsrf(ctx);
|
|
657
676
|
if (ctx.debug) clearDebugLog();
|
|
658
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
677
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
659
678
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
660
679
|
await waitForHandshake(wsUrl, cookieStr, 3e4, ctx.debug);
|
|
661
680
|
if (ctx.config.accountId) {
|
|
662
681
|
await switchAccount(ctx, ctx.config.accountId);
|
|
663
|
-
await waitForHandshake(endpoints.websocket(ctx.
|
|
682
|
+
await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 3e4, ctx.debug);
|
|
664
683
|
}
|
|
665
684
|
}
|
|
666
685
|
|
|
@@ -674,7 +693,7 @@ var DxtradeClient = class {
|
|
|
674
693
|
callbacks,
|
|
675
694
|
cookies: {},
|
|
676
695
|
csrf: null,
|
|
677
|
-
|
|
696
|
+
broker: config.broker,
|
|
678
697
|
retries: config.retries ?? 3,
|
|
679
698
|
debug: config.debug ?? false,
|
|
680
699
|
ensureSession() {
|
|
@@ -716,6 +735,9 @@ var DxtradeClient = class {
|
|
|
716
735
|
async getAccountMetrics() {
|
|
717
736
|
return getAccountMetrics(this._ctx);
|
|
718
737
|
}
|
|
738
|
+
async getTradeJournal(params) {
|
|
739
|
+
return getTradeJournal(this._ctx, params);
|
|
740
|
+
}
|
|
719
741
|
async getInstruments(params = {}) {
|
|
720
742
|
return getInstruments(this._ctx, params);
|
|
721
743
|
}
|
|
@@ -733,7 +755,6 @@ var DxtradeClient = class {
|
|
|
733
755
|
SIDE,
|
|
734
756
|
TIF,
|
|
735
757
|
WS_MESSAGE,
|
|
736
|
-
endpoints
|
|
737
|
-
resolveBrokerUrl
|
|
758
|
+
endpoints
|
|
738
759
|
});
|
|
739
760
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/constants/brokers.ts","../src/constants/endpoints.ts","../src/constants/enums.ts","../src/constants/errors.ts","../src/domains/account/account.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts","../src/domains/assessments/assessments.ts","../src/domains/instrument/instrument.ts","../src/domains/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export * from \"./constants\";\nexport type { DxtradeConfig, DxtradeCallbacks } from \"./client.types\";\nexport type { WsPayload } from \"./utils/websocket.types\";\nexport { DxtradeClient } from \"./client\";\n","export const BROKER = {\n LARKFUNDING: \"https://trade.gooeytrade.com\",\n EIGHTCAP: \"https://trader.dx-eightcap.com\",\n} as const;\n\nexport function resolveBrokerUrl(broker: string, customUrls?: Record<string, string>): string {\n if (customUrls?.[broker]) return customUrls[broker];\n\n const key = broker.toUpperCase() as keyof typeof BROKER;\n if (BROKER[key]) {\n return BROKER[key];\n }\n\n return `https://dxtrade.${broker}.com`;\n}\n","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.2-javascript` +\n `&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true` +\n `&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true` +\n `&sessionState=dx-new&guest-mode=false`;\n\nexport const endpoints = {\n login: (base: string) => `${base}/api/auth/login`,\n\n switchAccount: (base: string, id: string) => `${base}/api/accounts/switch?accountId=${id}`,\n\n suggest: (base: string, text: string) => `${base}/api/suggest?text=${text}`,\n\n instrumentInfo: (base: string, symbol: string, tzOffset: number) =>\n `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,\n\n submitOrder: (base: string) => `${base}/api/orders/single`,\n\n assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n};\n","export enum ORDER_TYPE {\n MARKET = \"MARKET\",\n LIMIT = \"LIMIT\",\n STOP = \"STOP\",\n}\n\nexport enum SIDE {\n BUY = \"BUY\",\n SELL = \"SELL\",\n}\n\nexport enum ACTION {\n OPENING = \"OPENING\",\n CLOSING = \"CLOSING\",\n}\n\nexport enum TIF {\n GTC = \"GTC\",\n DAY = \"DAY\",\n GTD = \"GTD\",\n}\n\nexport enum WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\n}\n","export class DxtradeError extends Error {\n public code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = \"DxtradeError\";\n this.code = code;\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Account } from \".\";\n\nexport async function getAccountMetrics(ctx: ClientContext, timeout = 30_000): Promise<Account.Metrics> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_TIMEOUT\", \"Account metrics timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ACCOUNT_METRICS) {\n clearTimeout(timer);\n ws.close();\n const body = msg.body as { allMetrics: Account.Metrics };\n resolve(body.allMetrics);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\n });\n}\n","export class Cookies {\n static parse(setCookieHeaders: string[]): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n for (const cookie of setCookieHeaders) {\n const [nameValue] = cookie.split(\";\");\n const eqIndex = nameValue.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const name = nameValue.slice(0, eqIndex).trim();\n const value = nameValue.slice(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n return cookies;\n }\n\n static serialize(cookies: Record<string, string>): string {\n return Object.entries(cookies)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"; \");\n }\n\n static merge(existing: Record<string, string>, incoming: Record<string, string>): Record<string, string> {\n return { ...existing, ...incoming };\n }\n}\n","export function baseHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json; charset=UTF-8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n };\n}\n\nexport function authHeaders(csrf: string, cookieStr: string): Record<string, string> {\n return {\n ...baseHeaders(),\n \"X-CSRF-Token\": csrf,\n \"X-Requested-With\": \"XMLHttpRequest\",\n Accept: \"*/*\",\n Cookie: cookieStr,\n };\n}\n\nexport function cookieOnlyHeaders(cookieStr: string): Record<string, string> {\n return { Cookie: cookieStr };\n}\n","import axios, { type AxiosRequestConfig, type AxiosResponse } from \"axios\";\n\nexport async function retryRequest(config: AxiosRequestConfig, retries = 3): Promise<AxiosResponse> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await axios(config);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.warn(`[dxtrade-api] Attempt ${attempt} failed: ${message}`);\n if (attempt === retries) throw error;\n await new Promise((res) => setTimeout(res, 1000 * attempt));\n }\n }\n throw new Error(\"[dxtrade-api] Failed after retries\");\n}\n","import { appendFileSync, writeFileSync } from \"fs\";\nimport type WebSocket from \"ws\";\nimport type { WsPayload } from \"./websocket.types\";\n\nexport type { WsPayload } from \"./websocket.types\";\n\nconst DEBUG_LOG = \"debug.log\";\n\nexport function shouldLog(msg: WsPayload | string, debug: boolean | string): boolean {\n if (!debug) return false;\n if (debug === true || debug === \"true\") return true;\n if (typeof msg === \"string\") return false;\n const filters = (debug as string).split(\",\").map((s) => s.trim().toUpperCase());\n return filters.includes(msg.type);\n}\n\nexport function debugLog(msg: WsPayload | string): void {\n appendFileSync(DEBUG_LOG, JSON.stringify(msg) + \"\\n\");\n}\n\nexport function clearDebugLog(): void {\n writeFileSync(DEBUG_LOG, \"\");\n}\n\nexport function parseWsData(data: WebSocket.Data): WsPayload | string {\n const raw = data.toString();\n const pipeIndex = raw.indexOf(\"|\");\n if (pipeIndex === -1) return raw;\n\n try {\n return JSON.parse(raw.slice(pipeIndex + 1)) as WsPayload;\n } catch {\n return raw;\n }\n}\n","import { endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Assessments } from \".\";\n\nexport async function getAssessments(ctx: ClientContext, params: Assessments.Params): Promise<Assessments.Response> {\n ctx.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.assessments(ctx.baseUrl),\n data: {\n from: params.from,\n instrument: params.instrument,\n subtype: params.subtype ?? null,\n to: params.to,\n },\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n return response.data as Assessments.Response;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Instrument } from \".\";\n\nexport async function getInstruments(\n ctx: ClientContext,\n params: Partial<Instrument.Info> = {},\n timeout = 30_000,\n): Promise<Instrument.Info[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_TIMEOUT\", \"Instruments request timed out\"));\n }, timeout);\n\n let instruments: Instrument.Info[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.INSTRUMENTS) {\n instruments.push(...(msg.body as Instrument.Info[]));\n\n // Reset settle timer on each batch — resolve once no more arrive\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(\n instruments.filter((instrument) => {\n for (const key in params) {\n if (params[key as keyof Instrument.Info] !== instrument[key as keyof Instrument.Info]) {\n return false;\n }\n }\n return true;\n }),\n );\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport { getSymbolInfo } from \"../symbol/symbol\";\nimport type { Order, Message } from \".\";\n\nfunction createOrderListener(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): { promise: Promise<Order.Update>; ready: Promise<void> } {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let settled = false;\n\n const ready = new Promise<void>((resolve) => {\n ws.on(\"open\", resolve);\n });\n\n const promise = new Promise<Order.Update>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n ws.close();\n reject(new Error(\"[dxtrade-api] Order update timed out\"));\n }, timeout);\n\n function done(err: Error | null, result?: Order.Update) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n if (err) reject(err);\n else resolve(result!);\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Trade log messages (fills and rejections come through here)\n if (msg.type === WS_MESSAGE.MESSAGE) {\n const messages = msg.body as Message.Entry[];\n const orderMsg = messages?.findLast?.(\n (m) => m.messageCategory === \"TRADE_LOG\" && m.messageType === \"ORDER\" && !m.historyMessage,\n );\n if (!orderMsg) return;\n\n const params = orderMsg.parametersTO as Message.OrderParams;\n if (params.orderStatus === \"REJECTED\") {\n const reason = params.rejectReason?.key ?? \"Unknown reason\";\n done(new Error(`[dxtrade-api] Order rejected: ${reason}`));\n } else if (params.orderStatus === \"FILLED\") {\n done(null, {\n orderId: params.orderKey,\n status: params.orderStatus,\n symbol: params.symbol,\n filledQuantity: params.filledQuantity,\n filledPrice: params.filledPrice,\n });\n }\n return;\n }\n\n // Order updates (also carry fills)\n if (msg.type === WS_MESSAGE.ORDERS) {\n const body = (msg.body as Order.Update[])?.[0];\n if (!body?.orderId) return;\n\n if (body.status === \"REJECTED\") {\n done(new Error(`[dxtrade-api] Order rejected: ${body.statusDescription ?? \"Unknown reason\"}`));\n } else if (body.status === \"FILLED\") {\n done(null, body);\n }\n }\n });\n\n ws.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket order listener error: ${error.message}`));\n });\n });\n\n return { promise, ready };\n}\n\nexport async function submitOrder(ctx: ClientContext, params: Order.SubmitParams): Promise<Order.Update> {\n ctx.ensureSession();\n\n const {\n symbol,\n side,\n quantity,\n orderType,\n orderCode,\n price,\n instrumentId,\n stopLoss,\n takeProfit,\n positionEffect = ACTION.OPENING,\n positionCode,\n tif = \"GTC\",\n expireDate,\n metadata,\n } = params;\n const info = await getSymbolInfo(ctx, symbol);\n const units = Math.round(quantity * info.lotSize);\n const qty = side === SIDE.BUY ? units : -units;\n const priceParam = orderType === ORDER_TYPE.STOP ? \"stopPrice\" : \"limitPrice\";\n\n const orderData: Record<string, unknown> = {\n directExchange: false,\n legs: [\n {\n ...(instrumentId != null && { instrumentId }),\n ...(positionCode != null && { positionCode }),\n positionEffect,\n ratioQuantity: 1,\n symbol,\n },\n ],\n orderSide: side,\n orderType,\n quantity: qty,\n requestId: orderCode ?? `gwt-uid-931-${crypto.randomUUID()}`,\n timeInForce: tif,\n ...(expireDate != null && { expireDate }),\n ...(metadata != null && { metadata }),\n };\n\n if (price != null && orderType !== ORDER_TYPE.MARKET) {\n orderData[priceParam] = price;\n }\n\n if (stopLoss) {\n orderData.stopLoss = {\n ...(stopLoss.offset != null && { fixedOffset: stopLoss.offset }),\n ...(stopLoss.price != null && { fixedPrice: stopLoss.price }),\n priceFixed: stopLoss.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.STOP,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n if (takeProfit) {\n orderData.takeProfit = {\n ...(takeProfit.offset != null && { fixedOffset: takeProfit.offset }),\n ...(takeProfit.price != null && { fixedPrice: takeProfit.price }),\n priceFixed: takeProfit.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.LIMIT,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n try {\n // Open WS listener BEFORE submitting so we don't miss the response\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const listener = createOrderListener(wsUrl, cookieStr, 30_000, ctx.debug);\n await listener.ready;\n\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.submitOrder(ctx.baseUrl),\n data: orderData,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n ctx.callbacks.onOrderPlaced?.(response.data as Order.Response);\n\n const orderUpdate = await listener.promise;\n\n ctx.callbacks.onOrderUpdate?.(orderUpdate);\n return orderUpdate;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, baseHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Symbol } from \".\";\n\nexport async function getSymbolSuggestions(ctx: ClientContext, text: string): Promise<Symbol.Suggestion[]> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.suggest(ctx.baseUrl, text),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n const suggests = response.data?.suggests;\n if (!suggests?.length) {\n ctx.throwError(\"NO_SUGGESTIONS\", \"No symbol suggestions found\");\n }\n return suggests as Symbol.Suggestion[];\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SUGGEST_ERROR\", `Error getting symbol suggestions: ${message}`);\n }\n}\n\nexport async function getSymbolInfo(ctx: ClientContext, symbol: string): Promise<Symbol.Info> {\n ctx.ensureSession();\n\n try {\n const offsetMinutes = Math.abs(new Date().getTimezoneOffset());\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.instrumentInfo(ctx.baseUrl, symbol, offsetMinutes),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (!response.data) {\n ctx.throwError(\"NO_SYMBOL_INFO\", \"No symbol info returned\");\n }\n return response.data as Symbol.Info;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SYMBOL_INFO_ERROR\", `Error getting symbol info: ${message}`);\n }\n}\n\nexport async function getSymbolLimits(ctx: ClientContext, timeout = 30_000): Promise<Symbol.Limits[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"LIMITS_TIMEOUT\", \"Symbol limits request timed out\"));\n }, timeout);\n\n let limits: Symbol.Limits[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.LIMITS) {\n const batch = msg.body as Symbol.Limits[];\n if (batch.length === 0) return;\n\n limits.push(...batch);\n\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(limits);\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.POSITIONS) {\n clearTimeout(timer);\n ws.close();\n resolve();\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket handshake error: ${error.message}`));\n });\n });\n}\n\nexport async function login(ctx: ClientContext): Promise<void> {\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.login(ctx.baseUrl),\n data: {\n username: ctx.config.username,\n password: ctx.config.password,\n domain: ctx.config.broker,\n },\n headers: { \"Content-Type\": \"application/json\" },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n ctx.callbacks.onLogin?.();\n } else {\n ctx.throwError(\"LOGIN_FAILED\", `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"LOGIN_ERROR\", `Login error: ${message}`);\n }\n}\n\nexport async function fetchCsrf(ctx: ClientContext): Promise<void> {\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: ctx.baseUrl,\n headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.baseUrl },\n },\n ctx.retries,\n );\n\n const csrfMatch = response.data?.match(/name=\"csrf\" content=\"([^\"]+)\"/);\n if (csrfMatch) {\n ctx.csrf = csrfMatch[1];\n } else {\n ctx.throwError(\"CSRF_NOT_FOUND\", \"CSRF token not found\");\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"CSRF_ERROR\", `CSRF fetch error: ${message}`);\n }\n}\n\nexport async function switchAccount(ctx: ClientContext, accountId: string): Promise<void> {\n ctx.ensureSession();\n\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.switchAccount(ctx.baseUrl, accountId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n ctx.callbacks.onAccountSwitch?.(accountId);\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ACCOUNT_SWITCH_ERROR\", `Error switching account: ${message}`);\n }\n}\n\nexport async function connect(ctx: ClientContext): Promise<void> {\n await login(ctx);\n await fetchCsrf(ctx);\n if (ctx.debug) clearDebugLog();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.baseUrl), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { resolveBrokerUrl, DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\n} from \"@/domains\";\n\nexport class DxtradeClient {\n private _ctx: ClientContext;\n\n constructor(config: DxtradeConfig) {\n const callbacks = config.callbacks ?? {};\n\n this._ctx = {\n config,\n callbacks,\n cookies: {},\n csrf: null,\n baseUrl: resolveBrokerUrl(config.broker, config.brokerUrls),\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() or connect() first.\");\n }\n },\n throwError(code: string, message: string): never {\n const error = new DxtradeError(code, message);\n callbacks.onError?.(error);\n throw error;\n },\n };\n }\n\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n public async getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n public async getSymbolInfo(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n public async getSymbolLimits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n\n public async submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n public async getAccountMetrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n public async getInstruments(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n\n public async getAssessments(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","axios","WebSocket","import_ws","WebSocket","import_ws","import_ws","WebSocket","WebSocket","crypto","import_ws","WebSocket"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constants/brokers.ts","../src/constants/endpoints.ts","../src/constants/enums.ts","../src/constants/errors.ts","../src/domains/account/account.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts","../src/domains/assessments/assessments.ts","../src/domains/instrument/instrument.ts","../src/domains/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export * from \"./constants\";\nexport type { DxtradeConfig, DxtradeCallbacks } from \"./client.types\";\nexport type { WsPayload } from \"./utils/websocket.types\";\nexport { DxtradeClient } from \"./client\";\n","export const BROKER = {\n LARKFUNDING: \"https://trade.gooeytrade.com\",\n EIGHTCAP: \"https://trader.dx-eightcap.com\",\n FTMO: \"https://dxtrade.ftmo.com\",\n} as const;\n","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.2-javascript` +\n `&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true` +\n `&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true` +\n `&sessionState=dx-new&guest-mode=false`;\n\nexport const endpoints = {\n login: (base: string) => `${base}/api/auth/login`,\n\n switchAccount: (base: string, id: string) => `${base}/api/accounts/switch?accountId=${id}`,\n\n suggest: (base: string, text: string) => `${base}/api/suggest?text=${text}`,\n\n instrumentInfo: (base: string, symbol: string, tzOffset: number) =>\n `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,\n\n submitOrder: (base: string) => `${base}/api/orders/single`,\n\n assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\n};\n","export enum ORDER_TYPE {\n MARKET = \"MARKET\",\n LIMIT = \"LIMIT\",\n STOP = \"STOP\",\n}\n\nexport enum SIDE {\n BUY = \"BUY\",\n SELL = \"SELL\",\n}\n\nexport enum ACTION {\n OPENING = \"OPENING\",\n CLOSING = \"CLOSING\",\n}\n\nexport enum TIF {\n GTC = \"GTC\",\n DAY = \"DAY\",\n GTD = \"GTD\",\n}\n\nexport enum WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\n}\n","export class DxtradeError extends Error {\n public code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = \"DxtradeError\";\n this.code = code;\n }\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog, retryRequest, baseHeaders } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Account } from \".\";\n\nexport async function getAccountMetrics(ctx: ClientContext, timeout = 30_000): Promise<Account.Metrics> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_TIMEOUT\", \"Account metrics timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ACCOUNT_METRICS) {\n clearTimeout(timer);\n ws.close();\n const body = msg.body as { allMetrics: Account.Metrics };\n resolve(body.allMetrics);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\n });\n}\n\nexport async function getTradeJournal(ctx: ClientContext, params: { from: number; to: number }): Promise<any> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.tradeJournal(ctx.broker, params),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n return response.data;\n } else {\n ctx.throwError(\"TRADE_JOURNAL_ERROR\", `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"TRADE_JOURNAL_ERROR\", `Trade journal error: ${message}`);\n }\n}\n","export class Cookies {\n static parse(setCookieHeaders: string[]): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n for (const cookie of setCookieHeaders) {\n const [nameValue] = cookie.split(\";\");\n const eqIndex = nameValue.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const name = nameValue.slice(0, eqIndex).trim();\n const value = nameValue.slice(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n return cookies;\n }\n\n static serialize(cookies: Record<string, string>): string {\n return Object.entries(cookies)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"; \");\n }\n\n static merge(existing: Record<string, string>, incoming: Record<string, string>): Record<string, string> {\n return { ...existing, ...incoming };\n }\n}\n","export function baseHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json; charset=UTF-8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n };\n}\n\nexport function authHeaders(csrf: string, cookieStr: string): Record<string, string> {\n return {\n ...baseHeaders(),\n \"X-CSRF-Token\": csrf,\n \"X-Requested-With\": \"XMLHttpRequest\",\n Accept: \"*/*\",\n Cookie: cookieStr,\n };\n}\n\nexport function cookieOnlyHeaders(cookieStr: string): Record<string, string> {\n return { Cookie: cookieStr };\n}\n","import axios, { type AxiosRequestConfig, type AxiosResponse } from \"axios\";\n\nexport async function retryRequest(config: AxiosRequestConfig, retries = 3): Promise<AxiosResponse> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await axios(config);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.warn(`[dxtrade-api] Attempt ${attempt} failed: ${message}`);\n if (attempt === retries) throw error;\n await new Promise((res) => setTimeout(res, 1000 * attempt));\n }\n }\n throw new Error(\"[dxtrade-api] Failed after retries\");\n}\n","import { appendFileSync, writeFileSync } from \"fs\";\nimport type WebSocket from \"ws\";\nimport type { WsPayload } from \"./websocket.types\";\n\nexport type { WsPayload } from \"./websocket.types\";\n\nconst DEBUG_LOG = \"debug.log\";\n\nexport function shouldLog(msg: WsPayload | string, debug: boolean | string): boolean {\n if (!debug) return false;\n if (debug === true || debug === \"true\") return true;\n if (typeof msg === \"string\") return false;\n const filters = (debug as string).split(\",\").map((s) => s.trim().toUpperCase());\n return filters.includes(msg.type);\n}\n\nexport function debugLog(msg: WsPayload | string): void {\n appendFileSync(DEBUG_LOG, JSON.stringify(msg) + \"\\n\");\n}\n\nexport function clearDebugLog(): void {\n writeFileSync(DEBUG_LOG, \"\");\n}\n\nexport function parseWsData(data: WebSocket.Data): WsPayload | string {\n const raw = data.toString();\n const pipeIndex = raw.indexOf(\"|\");\n if (pipeIndex === -1) return raw;\n\n try {\n return JSON.parse(raw.slice(pipeIndex + 1)) as WsPayload;\n } catch {\n return raw;\n }\n}\n","import { endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Assessments } from \".\";\n\nexport async function getAssessments(ctx: ClientContext, params: Assessments.Params): Promise<Assessments.Response> {\n ctx.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.assessments(ctx.broker),\n data: {\n from: params.from,\n instrument: params.instrument,\n subtype: params.subtype ?? null,\n to: params.to,\n },\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n return response.data as Assessments.Response;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Instrument } from \".\";\n\nexport async function getInstruments(\n ctx: ClientContext,\n params: Partial<Instrument.Info> = {},\n timeout = 30_000,\n): Promise<Instrument.Info[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_TIMEOUT\", \"Instruments request timed out\"));\n }, timeout);\n\n let instruments: Instrument.Info[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.INSTRUMENTS) {\n instruments.push(...(msg.body as Instrument.Info[]));\n\n // Reset settle timer on each batch — resolve once no more arrive\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(\n instruments.filter((instrument) => {\n for (const key in params) {\n if (params[key as keyof Instrument.Info] !== instrument[key as keyof Instrument.Info]) {\n return false;\n }\n }\n return true;\n }),\n );\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport { getSymbolInfo } from \"../symbol/symbol\";\nimport type { Order, Message } from \".\";\n\nfunction createOrderListener(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): { promise: Promise<Order.Update>; ready: Promise<void> } {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let settled = false;\n\n const ready = new Promise<void>((resolve) => {\n ws.on(\"open\", resolve);\n });\n\n const promise = new Promise<Order.Update>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n ws.close();\n reject(new Error(\"[dxtrade-api] Order update timed out\"));\n }, timeout);\n\n function done(err: Error | null, result?: Order.Update) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n if (err) reject(err);\n else resolve(result!);\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Trade log messages (fills and rejections come through here)\n if (msg.type === WS_MESSAGE.MESSAGE) {\n const messages = msg.body as Message.Entry[];\n const orderMsg = messages?.findLast?.(\n (m) => m.messageCategory === \"TRADE_LOG\" && m.messageType === \"ORDER\" && !m.historyMessage,\n );\n if (!orderMsg) return;\n\n const params = orderMsg.parametersTO as Message.OrderParams;\n if (params.orderStatus === \"REJECTED\") {\n const reason = params.rejectReason?.key ?? \"Unknown reason\";\n done(new Error(`[dxtrade-api] Order rejected: ${reason}`));\n } else if (params.orderStatus === \"FILLED\") {\n done(null, {\n orderId: params.orderKey,\n status: params.orderStatus,\n symbol: params.symbol,\n filledQuantity: params.filledQuantity,\n filledPrice: params.filledPrice,\n });\n }\n return;\n }\n\n // Order updates (also carry fills)\n if (msg.type === WS_MESSAGE.ORDERS) {\n const body = (msg.body as Order.Update[])?.[0];\n if (!body?.orderId) return;\n\n if (body.status === \"REJECTED\") {\n done(new Error(`[dxtrade-api] Order rejected: ${body.statusDescription ?? \"Unknown reason\"}`));\n } else if (body.status === \"FILLED\") {\n done(null, body);\n }\n }\n });\n\n ws.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket order listener error: ${error.message}`));\n });\n });\n\n return { promise, ready };\n}\n\nexport async function submitOrder(ctx: ClientContext, params: Order.SubmitParams): Promise<Order.Update> {\n ctx.ensureSession();\n\n const {\n symbol,\n side,\n quantity,\n orderType,\n orderCode,\n price,\n instrumentId,\n stopLoss,\n takeProfit,\n positionEffect = ACTION.OPENING,\n positionCode,\n tif = \"GTC\",\n expireDate,\n metadata,\n } = params;\n const info = await getSymbolInfo(ctx, symbol);\n const units = Math.round(quantity * info.lotSize);\n const qty = side === SIDE.BUY ? units : -units;\n const priceParam = orderType === ORDER_TYPE.STOP ? \"stopPrice\" : \"limitPrice\";\n\n const orderData: Record<string, unknown> = {\n directExchange: false,\n legs: [\n {\n ...(instrumentId != null && { instrumentId }),\n ...(positionCode != null && { positionCode }),\n positionEffect,\n ratioQuantity: 1,\n symbol,\n },\n ],\n orderSide: side,\n orderType,\n quantity: qty,\n requestId: orderCode ?? `gwt-uid-931-${crypto.randomUUID()}`,\n timeInForce: tif,\n ...(expireDate != null && { expireDate }),\n ...(metadata != null && { metadata }),\n };\n\n if (price != null && orderType !== ORDER_TYPE.MARKET) {\n orderData[priceParam] = price;\n }\n\n if (stopLoss) {\n orderData.stopLoss = {\n ...(stopLoss.offset != null && { fixedOffset: stopLoss.offset }),\n ...(stopLoss.price != null && { fixedPrice: stopLoss.price }),\n priceFixed: stopLoss.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.STOP,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n if (takeProfit) {\n orderData.takeProfit = {\n ...(takeProfit.offset != null && { fixedOffset: takeProfit.offset }),\n ...(takeProfit.price != null && { fixedPrice: takeProfit.price }),\n priceFixed: takeProfit.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.LIMIT,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n try {\n // Open WS listener BEFORE submitting so we don't miss the response\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const listener = createOrderListener(wsUrl, cookieStr, 30_000, ctx.debug);\n await listener.ready;\n\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.submitOrder(ctx.broker),\n data: orderData,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n ctx.callbacks.onOrderPlaced?.(response.data as Order.Response);\n\n const orderUpdate = await listener.promise;\n\n ctx.callbacks.onOrderUpdate?.(orderUpdate);\n return orderUpdate;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, baseHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Symbol } from \".\";\n\nexport async function getSymbolSuggestions(ctx: ClientContext, text: string): Promise<Symbol.Suggestion[]> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.suggest(ctx.broker, text),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n const suggests = response.data?.suggests;\n if (!suggests?.length) {\n ctx.throwError(\"NO_SUGGESTIONS\", \"No symbol suggestions found\");\n }\n return suggests as Symbol.Suggestion[];\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SUGGEST_ERROR\", `Error getting symbol suggestions: ${message}`);\n }\n}\n\nexport async function getSymbolInfo(ctx: ClientContext, symbol: string): Promise<Symbol.Info> {\n ctx.ensureSession();\n\n try {\n const offsetMinutes = Math.abs(new Date().getTimezoneOffset());\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.instrumentInfo(ctx.broker, symbol, offsetMinutes),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (!response.data) {\n ctx.throwError(\"NO_SYMBOL_INFO\", \"No symbol info returned\");\n }\n return response.data as Symbol.Info;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SYMBOL_INFO_ERROR\", `Error getting symbol info: ${message}`);\n }\n}\n\nexport async function getSymbolLimits(ctx: ClientContext, timeout = 30_000): Promise<Symbol.Limits[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"LIMITS_TIMEOUT\", \"Symbol limits request timed out\"));\n }, timeout);\n\n let limits: Symbol.Limits[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.LIMITS) {\n const batch = msg.body as Symbol.Limits[];\n if (batch.length === 0) return;\n\n limits.push(...batch);\n\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(limits);\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.POSITIONS) {\n clearTimeout(timer);\n ws.close();\n resolve();\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket handshake error: ${error.message}`));\n });\n });\n}\n\nexport async function login(ctx: ClientContext): Promise<void> {\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.login(ctx.broker),\n data: {\n username: ctx.config.username,\n password: ctx.config.password,\n domain: ctx.config.broker,\n },\n headers: { \"Content-Type\": \"application/json\" },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n ctx.callbacks.onLogin?.();\n } else {\n ctx.throwError(\"LOGIN_FAILED\", `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"LOGIN_ERROR\", `Login error: ${message}`);\n }\n}\n\nexport async function fetchCsrf(ctx: ClientContext): Promise<void> {\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: ctx.broker,\n headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.broker },\n },\n ctx.retries,\n );\n\n const csrfMatch = response.data?.match(/name=\"csrf\" content=\"([^\"]+)\"/);\n if (csrfMatch) {\n ctx.csrf = csrfMatch[1];\n } else {\n ctx.throwError(\"CSRF_NOT_FOUND\", \"CSRF token not found\");\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"CSRF_ERROR\", `CSRF fetch error: ${message}`);\n }\n}\n\nexport async function switchAccount(ctx: ClientContext, accountId: string): Promise<void> {\n ctx.ensureSession();\n\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.switchAccount(ctx.broker, accountId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n ctx.callbacks.onAccountSwitch?.(accountId);\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ACCOUNT_SWITCH_ERROR\", `Error switching account: ${message}`);\n }\n}\n\nexport async function connect(ctx: ClientContext): Promise<void> {\n await login(ctx);\n await fetchCsrf(ctx);\n if (ctx.debug) clearDebugLog();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\n getTradeJournal,\n} from \"@/domains\";\n\nexport class DxtradeClient {\n private _ctx: ClientContext;\n\n constructor(config: DxtradeConfig) {\n const callbacks = config.callbacks ?? {};\n\n this._ctx = {\n config,\n callbacks,\n cookies: {},\n csrf: null,\n broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() or connect() first.\");\n }\n },\n throwError(code: string, message: string): never {\n const error = new DxtradeError(code, message);\n callbacks.onError?.(error);\n throw error;\n },\n };\n }\n\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n public async getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n public async getSymbolInfo(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n public async getSymbolLimits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n\n public async submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n public async getAccountMetrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n public async getTradeJournal(params: { from: number; to: number }): Promise<any> {\n return getTradeJournal(this._ctx, params);\n }\n\n public async getInstruments(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n\n public async getAssessments(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","axios","WebSocket","import_ws","WebSocket","import_ws","import_ws","WebSocket","WebSocket","crypto","import_ws","WebSocket"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
// src/constants/brokers.ts
|
|
2
2
|
var BROKER = {
|
|
3
3
|
LARKFUNDING: "https://trade.gooeytrade.com",
|
|
4
|
-
EIGHTCAP: "https://trader.dx-eightcap.com"
|
|
4
|
+
EIGHTCAP: "https://trader.dx-eightcap.com",
|
|
5
|
+
FTMO: "https://dxtrade.ftmo.com"
|
|
5
6
|
};
|
|
6
|
-
function resolveBrokerUrl(broker, customUrls) {
|
|
7
|
-
if (customUrls?.[broker]) return customUrls[broker];
|
|
8
|
-
const key = broker.toUpperCase();
|
|
9
|
-
if (BROKER[key]) {
|
|
10
|
-
return BROKER[key];
|
|
11
|
-
}
|
|
12
|
-
return `https://dxtrade.${broker}.com`;
|
|
13
|
-
}
|
|
14
7
|
|
|
15
8
|
// src/constants/endpoints.ts
|
|
16
9
|
var websocketQuery = `?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.2-javascript&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true&sessionState=dx-new&guest-mode=false`;
|
|
@@ -21,7 +14,8 @@ var endpoints = {
|
|
|
21
14
|
instrumentInfo: (base, symbol, tzOffset) => `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,
|
|
22
15
|
submitOrder: (base) => `${base}/api/orders/single`,
|
|
23
16
|
assessments: (base) => `${base}/api/assessments`,
|
|
24
|
-
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery
|
|
17
|
+
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery,
|
|
18
|
+
tradeJournal: (base, params) => `${base}/api/tradejournal?from=${params.from}&to=${params.to}`
|
|
25
19
|
};
|
|
26
20
|
|
|
27
21
|
// src/constants/enums.ts
|
|
@@ -164,7 +158,7 @@ function parseWsData(data) {
|
|
|
164
158
|
// src/domains/account/account.ts
|
|
165
159
|
async function getAccountMetrics(ctx, timeout = 3e4) {
|
|
166
160
|
ctx.ensureSession();
|
|
167
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
161
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
168
162
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
169
163
|
return new Promise((resolve, reject) => {
|
|
170
164
|
const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });
|
|
@@ -190,6 +184,32 @@ async function getAccountMetrics(ctx, timeout = 3e4) {
|
|
|
190
184
|
});
|
|
191
185
|
});
|
|
192
186
|
}
|
|
187
|
+
async function getTradeJournal(ctx, params) {
|
|
188
|
+
ctx.ensureSession();
|
|
189
|
+
try {
|
|
190
|
+
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
191
|
+
const response = await retryRequest(
|
|
192
|
+
{
|
|
193
|
+
method: "GET",
|
|
194
|
+
url: endpoints.tradeJournal(ctx.broker, params),
|
|
195
|
+
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
196
|
+
},
|
|
197
|
+
ctx.retries
|
|
198
|
+
);
|
|
199
|
+
if (response.status === 200) {
|
|
200
|
+
const setCookies = response.headers["set-cookie"] ?? [];
|
|
201
|
+
const incoming = Cookies.parse(setCookies);
|
|
202
|
+
ctx.cookies = Cookies.merge(ctx.cookies, incoming);
|
|
203
|
+
return response.data;
|
|
204
|
+
} else {
|
|
205
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Login failed: ${response.status}`);
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (error instanceof DxtradeError) throw error;
|
|
209
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
210
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Trade journal error: ${message}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
193
213
|
|
|
194
214
|
// src/domains/assessments/assessments.ts
|
|
195
215
|
async function getAssessments(ctx, params) {
|
|
@@ -198,7 +218,7 @@ async function getAssessments(ctx, params) {
|
|
|
198
218
|
const response = await retryRequest(
|
|
199
219
|
{
|
|
200
220
|
method: "POST",
|
|
201
|
-
url: endpoints.assessments(ctx.
|
|
221
|
+
url: endpoints.assessments(ctx.broker),
|
|
202
222
|
data: {
|
|
203
223
|
from: params.from,
|
|
204
224
|
instrument: params.instrument,
|
|
@@ -221,7 +241,7 @@ async function getAssessments(ctx, params) {
|
|
|
221
241
|
import WebSocket2 from "ws";
|
|
222
242
|
async function getInstruments(ctx, params = {}, timeout = 3e4) {
|
|
223
243
|
ctx.ensureSession();
|
|
224
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
244
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
225
245
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
226
246
|
return new Promise((resolve, reject) => {
|
|
227
247
|
const ws = new WebSocket2(wsUrl, { headers: { Cookie: cookieStr } });
|
|
@@ -275,7 +295,7 @@ async function getSymbolSuggestions(ctx, text) {
|
|
|
275
295
|
const response = await retryRequest(
|
|
276
296
|
{
|
|
277
297
|
method: "GET",
|
|
278
|
-
url: endpoints.suggest(ctx.
|
|
298
|
+
url: endpoints.suggest(ctx.broker, text),
|
|
279
299
|
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
280
300
|
},
|
|
281
301
|
ctx.retries
|
|
@@ -299,7 +319,7 @@ async function getSymbolInfo(ctx, symbol) {
|
|
|
299
319
|
const response = await retryRequest(
|
|
300
320
|
{
|
|
301
321
|
method: "GET",
|
|
302
|
-
url: endpoints.instrumentInfo(ctx.
|
|
322
|
+
url: endpoints.instrumentInfo(ctx.broker, symbol, offsetMinutes),
|
|
303
323
|
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
304
324
|
},
|
|
305
325
|
ctx.retries
|
|
@@ -316,7 +336,7 @@ async function getSymbolInfo(ctx, symbol) {
|
|
|
316
336
|
}
|
|
317
337
|
async function getSymbolLimits(ctx, timeout = 3e4) {
|
|
318
338
|
ctx.ensureSession();
|
|
319
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
339
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
320
340
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
321
341
|
return new Promise((resolve, reject) => {
|
|
322
342
|
const ws = new WebSocket3(wsUrl, { headers: { Cookie: cookieStr } });
|
|
@@ -486,14 +506,14 @@ async function submitOrder(ctx, params) {
|
|
|
486
506
|
};
|
|
487
507
|
}
|
|
488
508
|
try {
|
|
489
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
509
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
490
510
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
491
511
|
const listener = createOrderListener(wsUrl, cookieStr, 3e4, ctx.debug);
|
|
492
512
|
await listener.ready;
|
|
493
513
|
const response = await retryRequest(
|
|
494
514
|
{
|
|
495
515
|
method: "POST",
|
|
496
|
-
url: endpoints.submitOrder(ctx.
|
|
516
|
+
url: endpoints.submitOrder(ctx.broker),
|
|
497
517
|
data: orderData,
|
|
498
518
|
headers: authHeaders(ctx.csrf, Cookies.serialize(ctx.cookies))
|
|
499
519
|
},
|
|
@@ -541,7 +561,7 @@ async function login(ctx) {
|
|
|
541
561
|
const response = await retryRequest(
|
|
542
562
|
{
|
|
543
563
|
method: "POST",
|
|
544
|
-
url: endpoints.login(ctx.
|
|
564
|
+
url: endpoints.login(ctx.broker),
|
|
545
565
|
data: {
|
|
546
566
|
username: ctx.config.username,
|
|
547
567
|
password: ctx.config.password,
|
|
@@ -571,8 +591,8 @@ async function fetchCsrf(ctx) {
|
|
|
571
591
|
const response = await retryRequest(
|
|
572
592
|
{
|
|
573
593
|
method: "GET",
|
|
574
|
-
url: ctx.
|
|
575
|
-
headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.
|
|
594
|
+
url: ctx.broker,
|
|
595
|
+
headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.broker }
|
|
576
596
|
},
|
|
577
597
|
ctx.retries
|
|
578
598
|
);
|
|
@@ -594,7 +614,7 @@ async function switchAccount(ctx, accountId) {
|
|
|
594
614
|
await retryRequest(
|
|
595
615
|
{
|
|
596
616
|
method: "POST",
|
|
597
|
-
url: endpoints.switchAccount(ctx.
|
|
617
|
+
url: endpoints.switchAccount(ctx.broker, accountId),
|
|
598
618
|
headers: authHeaders(ctx.csrf, Cookies.serialize(ctx.cookies))
|
|
599
619
|
},
|
|
600
620
|
ctx.retries
|
|
@@ -610,12 +630,12 @@ async function connect(ctx) {
|
|
|
610
630
|
await login(ctx);
|
|
611
631
|
await fetchCsrf(ctx);
|
|
612
632
|
if (ctx.debug) clearDebugLog();
|
|
613
|
-
const wsUrl = endpoints.websocket(ctx.
|
|
633
|
+
const wsUrl = endpoints.websocket(ctx.broker);
|
|
614
634
|
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
615
635
|
await waitForHandshake(wsUrl, cookieStr, 3e4, ctx.debug);
|
|
616
636
|
if (ctx.config.accountId) {
|
|
617
637
|
await switchAccount(ctx, ctx.config.accountId);
|
|
618
|
-
await waitForHandshake(endpoints.websocket(ctx.
|
|
638
|
+
await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 3e4, ctx.debug);
|
|
619
639
|
}
|
|
620
640
|
}
|
|
621
641
|
|
|
@@ -629,7 +649,7 @@ var DxtradeClient = class {
|
|
|
629
649
|
callbacks,
|
|
630
650
|
cookies: {},
|
|
631
651
|
csrf: null,
|
|
632
|
-
|
|
652
|
+
broker: config.broker,
|
|
633
653
|
retries: config.retries ?? 3,
|
|
634
654
|
debug: config.debug ?? false,
|
|
635
655
|
ensureSession() {
|
|
@@ -671,6 +691,9 @@ var DxtradeClient = class {
|
|
|
671
691
|
async getAccountMetrics() {
|
|
672
692
|
return getAccountMetrics(this._ctx);
|
|
673
693
|
}
|
|
694
|
+
async getTradeJournal(params) {
|
|
695
|
+
return getTradeJournal(this._ctx, params);
|
|
696
|
+
}
|
|
674
697
|
async getInstruments(params = {}) {
|
|
675
698
|
return getInstruments(this._ctx, params);
|
|
676
699
|
}
|
|
@@ -687,7 +710,6 @@ export {
|
|
|
687
710
|
SIDE,
|
|
688
711
|
TIF,
|
|
689
712
|
WS_MESSAGE,
|
|
690
|
-
endpoints
|
|
691
|
-
resolveBrokerUrl
|
|
713
|
+
endpoints
|
|
692
714
|
};
|
|
693
715
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants/brokers.ts","../src/constants/endpoints.ts","../src/constants/enums.ts","../src/constants/errors.ts","../src/domains/account/account.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts","../src/domains/assessments/assessments.ts","../src/domains/instrument/instrument.ts","../src/domains/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export const BROKER = {\n LARKFUNDING: \"https://trade.gooeytrade.com\",\n EIGHTCAP: \"https://trader.dx-eightcap.com\",\n} as const;\n\nexport function resolveBrokerUrl(broker: string, customUrls?: Record<string, string>): string {\n if (customUrls?.[broker]) return customUrls[broker];\n\n const key = broker.toUpperCase() as keyof typeof BROKER;\n if (BROKER[key]) {\n return BROKER[key];\n }\n\n return `https://dxtrade.${broker}.com`;\n}\n","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.2-javascript` +\n `&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true` +\n `&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true` +\n `&sessionState=dx-new&guest-mode=false`;\n\nexport const endpoints = {\n login: (base: string) => `${base}/api/auth/login`,\n\n switchAccount: (base: string, id: string) => `${base}/api/accounts/switch?accountId=${id}`,\n\n suggest: (base: string, text: string) => `${base}/api/suggest?text=${text}`,\n\n instrumentInfo: (base: string, symbol: string, tzOffset: number) =>\n `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,\n\n submitOrder: (base: string) => `${base}/api/orders/single`,\n\n assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n};\n","export enum ORDER_TYPE {\n MARKET = \"MARKET\",\n LIMIT = \"LIMIT\",\n STOP = \"STOP\",\n}\n\nexport enum SIDE {\n BUY = \"BUY\",\n SELL = \"SELL\",\n}\n\nexport enum ACTION {\n OPENING = \"OPENING\",\n CLOSING = \"CLOSING\",\n}\n\nexport enum TIF {\n GTC = \"GTC\",\n DAY = \"DAY\",\n GTD = \"GTD\",\n}\n\nexport enum WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\n}\n","export class DxtradeError extends Error {\n public code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = \"DxtradeError\";\n this.code = code;\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Account } from \".\";\n\nexport async function getAccountMetrics(ctx: ClientContext, timeout = 30_000): Promise<Account.Metrics> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_TIMEOUT\", \"Account metrics timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ACCOUNT_METRICS) {\n clearTimeout(timer);\n ws.close();\n const body = msg.body as { allMetrics: Account.Metrics };\n resolve(body.allMetrics);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\n });\n}\n","export class Cookies {\n static parse(setCookieHeaders: string[]): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n for (const cookie of setCookieHeaders) {\n const [nameValue] = cookie.split(\";\");\n const eqIndex = nameValue.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const name = nameValue.slice(0, eqIndex).trim();\n const value = nameValue.slice(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n return cookies;\n }\n\n static serialize(cookies: Record<string, string>): string {\n return Object.entries(cookies)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"; \");\n }\n\n static merge(existing: Record<string, string>, incoming: Record<string, string>): Record<string, string> {\n return { ...existing, ...incoming };\n }\n}\n","export function baseHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json; charset=UTF-8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n };\n}\n\nexport function authHeaders(csrf: string, cookieStr: string): Record<string, string> {\n return {\n ...baseHeaders(),\n \"X-CSRF-Token\": csrf,\n \"X-Requested-With\": \"XMLHttpRequest\",\n Accept: \"*/*\",\n Cookie: cookieStr,\n };\n}\n\nexport function cookieOnlyHeaders(cookieStr: string): Record<string, string> {\n return { Cookie: cookieStr };\n}\n","import axios, { type AxiosRequestConfig, type AxiosResponse } from \"axios\";\n\nexport async function retryRequest(config: AxiosRequestConfig, retries = 3): Promise<AxiosResponse> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await axios(config);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.warn(`[dxtrade-api] Attempt ${attempt} failed: ${message}`);\n if (attempt === retries) throw error;\n await new Promise((res) => setTimeout(res, 1000 * attempt));\n }\n }\n throw new Error(\"[dxtrade-api] Failed after retries\");\n}\n","import { appendFileSync, writeFileSync } from \"fs\";\nimport type WebSocket from \"ws\";\nimport type { WsPayload } from \"./websocket.types\";\n\nexport type { WsPayload } from \"./websocket.types\";\n\nconst DEBUG_LOG = \"debug.log\";\n\nexport function shouldLog(msg: WsPayload | string, debug: boolean | string): boolean {\n if (!debug) return false;\n if (debug === true || debug === \"true\") return true;\n if (typeof msg === \"string\") return false;\n const filters = (debug as string).split(\",\").map((s) => s.trim().toUpperCase());\n return filters.includes(msg.type);\n}\n\nexport function debugLog(msg: WsPayload | string): void {\n appendFileSync(DEBUG_LOG, JSON.stringify(msg) + \"\\n\");\n}\n\nexport function clearDebugLog(): void {\n writeFileSync(DEBUG_LOG, \"\");\n}\n\nexport function parseWsData(data: WebSocket.Data): WsPayload | string {\n const raw = data.toString();\n const pipeIndex = raw.indexOf(\"|\");\n if (pipeIndex === -1) return raw;\n\n try {\n return JSON.parse(raw.slice(pipeIndex + 1)) as WsPayload;\n } catch {\n return raw;\n }\n}\n","import { endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Assessments } from \".\";\n\nexport async function getAssessments(ctx: ClientContext, params: Assessments.Params): Promise<Assessments.Response> {\n ctx.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.assessments(ctx.baseUrl),\n data: {\n from: params.from,\n instrument: params.instrument,\n subtype: params.subtype ?? null,\n to: params.to,\n },\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n return response.data as Assessments.Response;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Instrument } from \".\";\n\nexport async function getInstruments(\n ctx: ClientContext,\n params: Partial<Instrument.Info> = {},\n timeout = 30_000,\n): Promise<Instrument.Info[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_TIMEOUT\", \"Instruments request timed out\"));\n }, timeout);\n\n let instruments: Instrument.Info[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.INSTRUMENTS) {\n instruments.push(...(msg.body as Instrument.Info[]));\n\n // Reset settle timer on each batch — resolve once no more arrive\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(\n instruments.filter((instrument) => {\n for (const key in params) {\n if (params[key as keyof Instrument.Info] !== instrument[key as keyof Instrument.Info]) {\n return false;\n }\n }\n return true;\n }),\n );\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport { getSymbolInfo } from \"../symbol/symbol\";\nimport type { Order, Message } from \".\";\n\nfunction createOrderListener(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): { promise: Promise<Order.Update>; ready: Promise<void> } {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let settled = false;\n\n const ready = new Promise<void>((resolve) => {\n ws.on(\"open\", resolve);\n });\n\n const promise = new Promise<Order.Update>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n ws.close();\n reject(new Error(\"[dxtrade-api] Order update timed out\"));\n }, timeout);\n\n function done(err: Error | null, result?: Order.Update) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n if (err) reject(err);\n else resolve(result!);\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Trade log messages (fills and rejections come through here)\n if (msg.type === WS_MESSAGE.MESSAGE) {\n const messages = msg.body as Message.Entry[];\n const orderMsg = messages?.findLast?.(\n (m) => m.messageCategory === \"TRADE_LOG\" && m.messageType === \"ORDER\" && !m.historyMessage,\n );\n if (!orderMsg) return;\n\n const params = orderMsg.parametersTO as Message.OrderParams;\n if (params.orderStatus === \"REJECTED\") {\n const reason = params.rejectReason?.key ?? \"Unknown reason\";\n done(new Error(`[dxtrade-api] Order rejected: ${reason}`));\n } else if (params.orderStatus === \"FILLED\") {\n done(null, {\n orderId: params.orderKey,\n status: params.orderStatus,\n symbol: params.symbol,\n filledQuantity: params.filledQuantity,\n filledPrice: params.filledPrice,\n });\n }\n return;\n }\n\n // Order updates (also carry fills)\n if (msg.type === WS_MESSAGE.ORDERS) {\n const body = (msg.body as Order.Update[])?.[0];\n if (!body?.orderId) return;\n\n if (body.status === \"REJECTED\") {\n done(new Error(`[dxtrade-api] Order rejected: ${body.statusDescription ?? \"Unknown reason\"}`));\n } else if (body.status === \"FILLED\") {\n done(null, body);\n }\n }\n });\n\n ws.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket order listener error: ${error.message}`));\n });\n });\n\n return { promise, ready };\n}\n\nexport async function submitOrder(ctx: ClientContext, params: Order.SubmitParams): Promise<Order.Update> {\n ctx.ensureSession();\n\n const {\n symbol,\n side,\n quantity,\n orderType,\n orderCode,\n price,\n instrumentId,\n stopLoss,\n takeProfit,\n positionEffect = ACTION.OPENING,\n positionCode,\n tif = \"GTC\",\n expireDate,\n metadata,\n } = params;\n const info = await getSymbolInfo(ctx, symbol);\n const units = Math.round(quantity * info.lotSize);\n const qty = side === SIDE.BUY ? units : -units;\n const priceParam = orderType === ORDER_TYPE.STOP ? \"stopPrice\" : \"limitPrice\";\n\n const orderData: Record<string, unknown> = {\n directExchange: false,\n legs: [\n {\n ...(instrumentId != null && { instrumentId }),\n ...(positionCode != null && { positionCode }),\n positionEffect,\n ratioQuantity: 1,\n symbol,\n },\n ],\n orderSide: side,\n orderType,\n quantity: qty,\n requestId: orderCode ?? `gwt-uid-931-${crypto.randomUUID()}`,\n timeInForce: tif,\n ...(expireDate != null && { expireDate }),\n ...(metadata != null && { metadata }),\n };\n\n if (price != null && orderType !== ORDER_TYPE.MARKET) {\n orderData[priceParam] = price;\n }\n\n if (stopLoss) {\n orderData.stopLoss = {\n ...(stopLoss.offset != null && { fixedOffset: stopLoss.offset }),\n ...(stopLoss.price != null && { fixedPrice: stopLoss.price }),\n priceFixed: stopLoss.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.STOP,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n if (takeProfit) {\n orderData.takeProfit = {\n ...(takeProfit.offset != null && { fixedOffset: takeProfit.offset }),\n ...(takeProfit.price != null && { fixedPrice: takeProfit.price }),\n priceFixed: takeProfit.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.LIMIT,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n try {\n // Open WS listener BEFORE submitting so we don't miss the response\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const listener = createOrderListener(wsUrl, cookieStr, 30_000, ctx.debug);\n await listener.ready;\n\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.submitOrder(ctx.baseUrl),\n data: orderData,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n ctx.callbacks.onOrderPlaced?.(response.data as Order.Response);\n\n const orderUpdate = await listener.promise;\n\n ctx.callbacks.onOrderUpdate?.(orderUpdate);\n return orderUpdate;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, baseHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Symbol } from \".\";\n\nexport async function getSymbolSuggestions(ctx: ClientContext, text: string): Promise<Symbol.Suggestion[]> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.suggest(ctx.baseUrl, text),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n const suggests = response.data?.suggests;\n if (!suggests?.length) {\n ctx.throwError(\"NO_SUGGESTIONS\", \"No symbol suggestions found\");\n }\n return suggests as Symbol.Suggestion[];\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SUGGEST_ERROR\", `Error getting symbol suggestions: ${message}`);\n }\n}\n\nexport async function getSymbolInfo(ctx: ClientContext, symbol: string): Promise<Symbol.Info> {\n ctx.ensureSession();\n\n try {\n const offsetMinutes = Math.abs(new Date().getTimezoneOffset());\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.instrumentInfo(ctx.baseUrl, symbol, offsetMinutes),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (!response.data) {\n ctx.throwError(\"NO_SYMBOL_INFO\", \"No symbol info returned\");\n }\n return response.data as Symbol.Info;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SYMBOL_INFO_ERROR\", `Error getting symbol info: ${message}`);\n }\n}\n\nexport async function getSymbolLimits(ctx: ClientContext, timeout = 30_000): Promise<Symbol.Limits[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"LIMITS_TIMEOUT\", \"Symbol limits request timed out\"));\n }, timeout);\n\n let limits: Symbol.Limits[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.LIMITS) {\n const batch = msg.body as Symbol.Limits[];\n if (batch.length === 0) return;\n\n limits.push(...batch);\n\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(limits);\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.POSITIONS) {\n clearTimeout(timer);\n ws.close();\n resolve();\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket handshake error: ${error.message}`));\n });\n });\n}\n\nexport async function login(ctx: ClientContext): Promise<void> {\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.login(ctx.baseUrl),\n data: {\n username: ctx.config.username,\n password: ctx.config.password,\n domain: ctx.config.broker,\n },\n headers: { \"Content-Type\": \"application/json\" },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n ctx.callbacks.onLogin?.();\n } else {\n ctx.throwError(\"LOGIN_FAILED\", `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"LOGIN_ERROR\", `Login error: ${message}`);\n }\n}\n\nexport async function fetchCsrf(ctx: ClientContext): Promise<void> {\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: ctx.baseUrl,\n headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.baseUrl },\n },\n ctx.retries,\n );\n\n const csrfMatch = response.data?.match(/name=\"csrf\" content=\"([^\"]+)\"/);\n if (csrfMatch) {\n ctx.csrf = csrfMatch[1];\n } else {\n ctx.throwError(\"CSRF_NOT_FOUND\", \"CSRF token not found\");\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"CSRF_ERROR\", `CSRF fetch error: ${message}`);\n }\n}\n\nexport async function switchAccount(ctx: ClientContext, accountId: string): Promise<void> {\n ctx.ensureSession();\n\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.switchAccount(ctx.baseUrl, accountId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n ctx.callbacks.onAccountSwitch?.(accountId);\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ACCOUNT_SWITCH_ERROR\", `Error switching account: ${message}`);\n }\n}\n\nexport async function connect(ctx: ClientContext): Promise<void> {\n await login(ctx);\n await fetchCsrf(ctx);\n if (ctx.debug) clearDebugLog();\n\n const wsUrl = endpoints.websocket(ctx.baseUrl);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.baseUrl), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { resolveBrokerUrl, DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\n} from \"@/domains\";\n\nexport class DxtradeClient {\n private _ctx: ClientContext;\n\n constructor(config: DxtradeConfig) {\n const callbacks = config.callbacks ?? {};\n\n this._ctx = {\n config,\n callbacks,\n cookies: {},\n csrf: null,\n baseUrl: resolveBrokerUrl(config.broker, config.brokerUrls),\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() or connect() first.\");\n }\n },\n throwError(code: string, message: string): never {\n const error = new DxtradeError(code, message);\n callbacks.onError?.(error);\n throw error;\n },\n };\n }\n\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n public async getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n public async getSymbolInfo(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n public async getSymbolLimits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n\n public async submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n public async getAccountMetrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n public async getInstruments(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n\n public async getAssessments(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants/brokers.ts","../src/constants/endpoints.ts","../src/constants/enums.ts","../src/constants/errors.ts","../src/domains/account/account.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts","../src/domains/assessments/assessments.ts","../src/domains/instrument/instrument.ts","../src/domains/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export const BROKER = {\n LARKFUNDING: \"https://trade.gooeytrade.com\",\n EIGHTCAP: \"https://trader.dx-eightcap.com\",\n FTMO: \"https://dxtrade.ftmo.com\",\n} as const;\n","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.2-javascript` +\n `&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true` +\n `&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true` +\n `&sessionState=dx-new&guest-mode=false`;\n\nexport const endpoints = {\n login: (base: string) => `${base}/api/auth/login`,\n\n switchAccount: (base: string, id: string) => `${base}/api/accounts/switch?accountId=${id}`,\n\n suggest: (base: string, text: string) => `${base}/api/suggest?text=${text}`,\n\n instrumentInfo: (base: string, symbol: string, tzOffset: number) =>\n `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,\n\n submitOrder: (base: string) => `${base}/api/orders/single`,\n\n assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\n};\n","export enum ORDER_TYPE {\n MARKET = \"MARKET\",\n LIMIT = \"LIMIT\",\n STOP = \"STOP\",\n}\n\nexport enum SIDE {\n BUY = \"BUY\",\n SELL = \"SELL\",\n}\n\nexport enum ACTION {\n OPENING = \"OPENING\",\n CLOSING = \"CLOSING\",\n}\n\nexport enum TIF {\n GTC = \"GTC\",\n DAY = \"DAY\",\n GTD = \"GTD\",\n}\n\nexport enum WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\n}\n","export class DxtradeError extends Error {\n public code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = \"DxtradeError\";\n this.code = code;\n }\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog, retryRequest, baseHeaders } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Account } from \".\";\n\nexport async function getAccountMetrics(ctx: ClientContext, timeout = 30_000): Promise<Account.Metrics> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_TIMEOUT\", \"Account metrics timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ACCOUNT_METRICS) {\n clearTimeout(timer);\n ws.close();\n const body = msg.body as { allMetrics: Account.Metrics };\n resolve(body.allMetrics);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\n });\n}\n\nexport async function getTradeJournal(ctx: ClientContext, params: { from: number; to: number }): Promise<any> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.tradeJournal(ctx.broker, params),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n return response.data;\n } else {\n ctx.throwError(\"TRADE_JOURNAL_ERROR\", `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"TRADE_JOURNAL_ERROR\", `Trade journal error: ${message}`);\n }\n}\n","export class Cookies {\n static parse(setCookieHeaders: string[]): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n for (const cookie of setCookieHeaders) {\n const [nameValue] = cookie.split(\";\");\n const eqIndex = nameValue.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const name = nameValue.slice(0, eqIndex).trim();\n const value = nameValue.slice(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n return cookies;\n }\n\n static serialize(cookies: Record<string, string>): string {\n return Object.entries(cookies)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"; \");\n }\n\n static merge(existing: Record<string, string>, incoming: Record<string, string>): Record<string, string> {\n return { ...existing, ...incoming };\n }\n}\n","export function baseHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json; charset=UTF-8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n };\n}\n\nexport function authHeaders(csrf: string, cookieStr: string): Record<string, string> {\n return {\n ...baseHeaders(),\n \"X-CSRF-Token\": csrf,\n \"X-Requested-With\": \"XMLHttpRequest\",\n Accept: \"*/*\",\n Cookie: cookieStr,\n };\n}\n\nexport function cookieOnlyHeaders(cookieStr: string): Record<string, string> {\n return { Cookie: cookieStr };\n}\n","import axios, { type AxiosRequestConfig, type AxiosResponse } from \"axios\";\n\nexport async function retryRequest(config: AxiosRequestConfig, retries = 3): Promise<AxiosResponse> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await axios(config);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.warn(`[dxtrade-api] Attempt ${attempt} failed: ${message}`);\n if (attempt === retries) throw error;\n await new Promise((res) => setTimeout(res, 1000 * attempt));\n }\n }\n throw new Error(\"[dxtrade-api] Failed after retries\");\n}\n","import { appendFileSync, writeFileSync } from \"fs\";\nimport type WebSocket from \"ws\";\nimport type { WsPayload } from \"./websocket.types\";\n\nexport type { WsPayload } from \"./websocket.types\";\n\nconst DEBUG_LOG = \"debug.log\";\n\nexport function shouldLog(msg: WsPayload | string, debug: boolean | string): boolean {\n if (!debug) return false;\n if (debug === true || debug === \"true\") return true;\n if (typeof msg === \"string\") return false;\n const filters = (debug as string).split(\",\").map((s) => s.trim().toUpperCase());\n return filters.includes(msg.type);\n}\n\nexport function debugLog(msg: WsPayload | string): void {\n appendFileSync(DEBUG_LOG, JSON.stringify(msg) + \"\\n\");\n}\n\nexport function clearDebugLog(): void {\n writeFileSync(DEBUG_LOG, \"\");\n}\n\nexport function parseWsData(data: WebSocket.Data): WsPayload | string {\n const raw = data.toString();\n const pipeIndex = raw.indexOf(\"|\");\n if (pipeIndex === -1) return raw;\n\n try {\n return JSON.parse(raw.slice(pipeIndex + 1)) as WsPayload;\n } catch {\n return raw;\n }\n}\n","import { endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Assessments } from \".\";\n\nexport async function getAssessments(ctx: ClientContext, params: Assessments.Params): Promise<Assessments.Response> {\n ctx.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.assessments(ctx.broker),\n data: {\n from: params.from,\n instrument: params.instrument,\n subtype: params.subtype ?? null,\n to: params.to,\n },\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n return response.data as Assessments.Response;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Instrument } from \".\";\n\nexport async function getInstruments(\n ctx: ClientContext,\n params: Partial<Instrument.Info> = {},\n timeout = 30_000,\n): Promise<Instrument.Info[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_TIMEOUT\", \"Instruments request timed out\"));\n }, timeout);\n\n let instruments: Instrument.Info[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.INSTRUMENTS) {\n instruments.push(...(msg.body as Instrument.Info[]));\n\n // Reset settle timer on each batch — resolve once no more arrive\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(\n instruments.filter((instrument) => {\n for (const key in params) {\n if (params[key as keyof Instrument.Info] !== instrument[key as keyof Instrument.Info]) {\n return false;\n }\n }\n return true;\n }),\n );\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport { getSymbolInfo } from \"../symbol/symbol\";\nimport type { Order, Message } from \".\";\n\nfunction createOrderListener(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): { promise: Promise<Order.Update>; ready: Promise<void> } {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let settled = false;\n\n const ready = new Promise<void>((resolve) => {\n ws.on(\"open\", resolve);\n });\n\n const promise = new Promise<Order.Update>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n ws.close();\n reject(new Error(\"[dxtrade-api] Order update timed out\"));\n }, timeout);\n\n function done(err: Error | null, result?: Order.Update) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n if (err) reject(err);\n else resolve(result!);\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Trade log messages (fills and rejections come through here)\n if (msg.type === WS_MESSAGE.MESSAGE) {\n const messages = msg.body as Message.Entry[];\n const orderMsg = messages?.findLast?.(\n (m) => m.messageCategory === \"TRADE_LOG\" && m.messageType === \"ORDER\" && !m.historyMessage,\n );\n if (!orderMsg) return;\n\n const params = orderMsg.parametersTO as Message.OrderParams;\n if (params.orderStatus === \"REJECTED\") {\n const reason = params.rejectReason?.key ?? \"Unknown reason\";\n done(new Error(`[dxtrade-api] Order rejected: ${reason}`));\n } else if (params.orderStatus === \"FILLED\") {\n done(null, {\n orderId: params.orderKey,\n status: params.orderStatus,\n symbol: params.symbol,\n filledQuantity: params.filledQuantity,\n filledPrice: params.filledPrice,\n });\n }\n return;\n }\n\n // Order updates (also carry fills)\n if (msg.type === WS_MESSAGE.ORDERS) {\n const body = (msg.body as Order.Update[])?.[0];\n if (!body?.orderId) return;\n\n if (body.status === \"REJECTED\") {\n done(new Error(`[dxtrade-api] Order rejected: ${body.statusDescription ?? \"Unknown reason\"}`));\n } else if (body.status === \"FILLED\") {\n done(null, body);\n }\n }\n });\n\n ws.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket order listener error: ${error.message}`));\n });\n });\n\n return { promise, ready };\n}\n\nexport async function submitOrder(ctx: ClientContext, params: Order.SubmitParams): Promise<Order.Update> {\n ctx.ensureSession();\n\n const {\n symbol,\n side,\n quantity,\n orderType,\n orderCode,\n price,\n instrumentId,\n stopLoss,\n takeProfit,\n positionEffect = ACTION.OPENING,\n positionCode,\n tif = \"GTC\",\n expireDate,\n metadata,\n } = params;\n const info = await getSymbolInfo(ctx, symbol);\n const units = Math.round(quantity * info.lotSize);\n const qty = side === SIDE.BUY ? units : -units;\n const priceParam = orderType === ORDER_TYPE.STOP ? \"stopPrice\" : \"limitPrice\";\n\n const orderData: Record<string, unknown> = {\n directExchange: false,\n legs: [\n {\n ...(instrumentId != null && { instrumentId }),\n ...(positionCode != null && { positionCode }),\n positionEffect,\n ratioQuantity: 1,\n symbol,\n },\n ],\n orderSide: side,\n orderType,\n quantity: qty,\n requestId: orderCode ?? `gwt-uid-931-${crypto.randomUUID()}`,\n timeInForce: tif,\n ...(expireDate != null && { expireDate }),\n ...(metadata != null && { metadata }),\n };\n\n if (price != null && orderType !== ORDER_TYPE.MARKET) {\n orderData[priceParam] = price;\n }\n\n if (stopLoss) {\n orderData.stopLoss = {\n ...(stopLoss.offset != null && { fixedOffset: stopLoss.offset }),\n ...(stopLoss.price != null && { fixedPrice: stopLoss.price }),\n priceFixed: stopLoss.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.STOP,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n if (takeProfit) {\n orderData.takeProfit = {\n ...(takeProfit.offset != null && { fixedOffset: takeProfit.offset }),\n ...(takeProfit.price != null && { fixedPrice: takeProfit.price }),\n priceFixed: takeProfit.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.LIMIT,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n try {\n // Open WS listener BEFORE submitting so we don't miss the response\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const listener = createOrderListener(wsUrl, cookieStr, 30_000, ctx.debug);\n await listener.ready;\n\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.submitOrder(ctx.broker),\n data: orderData,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n ctx.callbacks.onOrderPlaced?.(response.data as Order.Response);\n\n const orderUpdate = await listener.promise;\n\n ctx.callbacks.onOrderUpdate?.(orderUpdate);\n return orderUpdate;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, baseHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Symbol } from \".\";\n\nexport async function getSymbolSuggestions(ctx: ClientContext, text: string): Promise<Symbol.Suggestion[]> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.suggest(ctx.broker, text),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n const suggests = response.data?.suggests;\n if (!suggests?.length) {\n ctx.throwError(\"NO_SUGGESTIONS\", \"No symbol suggestions found\");\n }\n return suggests as Symbol.Suggestion[];\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SUGGEST_ERROR\", `Error getting symbol suggestions: ${message}`);\n }\n}\n\nexport async function getSymbolInfo(ctx: ClientContext, symbol: string): Promise<Symbol.Info> {\n ctx.ensureSession();\n\n try {\n const offsetMinutes = Math.abs(new Date().getTimezoneOffset());\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.instrumentInfo(ctx.broker, symbol, offsetMinutes),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (!response.data) {\n ctx.throwError(\"NO_SYMBOL_INFO\", \"No symbol info returned\");\n }\n return response.data as Symbol.Info;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"SYMBOL_INFO_ERROR\", `Error getting symbol info: ${message}`);\n }\n}\n\nexport async function getSymbolLimits(ctx: ClientContext, timeout = 30_000): Promise<Symbol.Limits[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(\"LIMITS_TIMEOUT\", \"Symbol limits request timed out\"));\n }, timeout);\n\n let limits: Symbol.Limits[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.LIMITS) {\n const batch = msg.body as Symbol.Limits[];\n if (batch.length === 0) return;\n\n limits.push(...batch);\n\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(limits);\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.POSITIONS) {\n clearTimeout(timer);\n ws.close();\n resolve();\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket handshake error: ${error.message}`));\n });\n });\n}\n\nexport async function login(ctx: ClientContext): Promise<void> {\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.login(ctx.broker),\n data: {\n username: ctx.config.username,\n password: ctx.config.password,\n domain: ctx.config.broker,\n },\n headers: { \"Content-Type\": \"application/json\" },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n ctx.callbacks.onLogin?.();\n } else {\n ctx.throwError(\"LOGIN_FAILED\", `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"LOGIN_ERROR\", `Login error: ${message}`);\n }\n}\n\nexport async function fetchCsrf(ctx: ClientContext): Promise<void> {\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: ctx.broker,\n headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.broker },\n },\n ctx.retries,\n );\n\n const csrfMatch = response.data?.match(/name=\"csrf\" content=\"([^\"]+)\"/);\n if (csrfMatch) {\n ctx.csrf = csrfMatch[1];\n } else {\n ctx.throwError(\"CSRF_NOT_FOUND\", \"CSRF token not found\");\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"CSRF_ERROR\", `CSRF fetch error: ${message}`);\n }\n}\n\nexport async function switchAccount(ctx: ClientContext, accountId: string): Promise<void> {\n ctx.ensureSession();\n\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.switchAccount(ctx.broker, accountId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n ctx.callbacks.onAccountSwitch?.(accountId);\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(\"ACCOUNT_SWITCH_ERROR\", `Error switching account: ${message}`);\n }\n}\n\nexport async function connect(ctx: ClientContext): Promise<void> {\n await login(ctx);\n await fetchCsrf(ctx);\n if (ctx.debug) clearDebugLog();\n\n const wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\n getTradeJournal,\n} from \"@/domains\";\n\nexport class DxtradeClient {\n private _ctx: ClientContext;\n\n constructor(config: DxtradeConfig) {\n const callbacks = config.callbacks ?? {};\n\n this._ctx = {\n config,\n callbacks,\n cookies: {},\n csrf: null,\n broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() or connect() first.\");\n }\n },\n throwError(code: string, message: string): never {\n const error = new DxtradeError(code, message);\n callbacks.onError?.(error);\n throw error;\n },\n };\n }\n\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n public async getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n public async getSymbolInfo(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n public async getSymbolLimits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n\n public async submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n public async getAccountMetrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n public async getTradeJournal(params: { from: number; to: number }): Promise<any> {\n return getTradeJournal(this._ctx, params);\n }\n\n public async getInstruments(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n\n public async getAssessments(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielgroen/dxtrade-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "DXtrade trading API client library",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"=============== Examples ===============": "",
|
|
25
25
|
"example:debug": "tsx examples/debug.ts",
|
|
26
26
|
"example:account": "tsx examples/account-metrics.ts",
|
|
27
|
+
"example:trade-journal": "tsx examples/trade-journal.ts",
|
|
27
28
|
"example:connect": "tsx examples/connect.ts",
|
|
28
29
|
"example:order": "tsx examples/submit-order.ts",
|
|
29
30
|
"example:assessments": "tsx examples/get-assessments.ts",
|