@danielgroen/dxtrade-api 1.0.7 → 1.0.8
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 +8 -8
- package/dist/index.d.mts +143 -66
- package/dist/index.d.ts +143 -66
- package/dist/index.js +411 -326
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +409 -326
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -7
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/client.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts"],"sourcesContent":["export const BROKER = {\n LARK: \"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]) {\n return customUrls[broker];\n }\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","export 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) =>\n `wss://${base.split(\"//\")[1]}/client/connector`\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};\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","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 crypto from \"crypto\";\nimport {\n endpoints,\n ORDER_TYPE,\n SIDE,\n ACTION,\n DxtradeError,\n resolveBrokerUrl,\n} from \"@/constants\";\nimport {\n parseCookies,\n serializeCookies,\n mergeCookies,\n baseHeaders,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n waitForHandshake,\n waitForOrderUpdate,\n} from \"@/utils\";\n\nexport class DxtradeClient {\n private config: DxtradeConfig;\n private callbacks: DxtradeCallbacks;\n private cookies: Record<string, string> = {};\n private csrf: string | null = null;\n private baseUrl: string;\n private retries: number;\n private debug: boolean;\n\n constructor(config: DxtradeConfig) {\n this.config = config;\n this.callbacks = config.callbacks ?? {};\n this.baseUrl = resolveBrokerUrl(config.broker, config.brokerUrls);\n this.retries = config.retries ?? 3;\n this.debug = config.debug ?? false;\n }\n\n // ── Session ─────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n async login(): Promise<void> {\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.login(this.baseUrl),\n data: {\n username: this.config.username,\n password: this.config.password,\n domain: this.config.broker,\n },\n headers: { \"Content-Type\": \"application/json\" },\n },\n this.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = parseCookies(setCookies);\n this.cookies = mergeCookies(this.cookies, incoming);\n this.callbacks.onLogin?.();\n } else {\n this.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 this.throwError(\"LOGIN_ERROR\", `Login error: ${message}`);\n }\n }\n\n async fetchCsrf(): Promise<void> {\n try {\n const cookieStr = serializeCookies(this.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: this.baseUrl,\n headers: { ...cookieOnlyHeaders(cookieStr), Referer: this.baseUrl },\n },\n this.retries,\n );\n\n const csrfMatch = response.data?.match(/name=\"csrf\" content=\"([^\"]+)\"/);\n if (csrfMatch) {\n this.csrf = csrfMatch[1];\n } else {\n this.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 this.throwError(\"CSRF_ERROR\", `CSRF fetch error: ${message}`);\n }\n }\n\n async switchAccount(accountId: string): Promise<void> {\n this.ensureSession();\n\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.switchAccount(this.baseUrl, accountId),\n headers: authHeaders(this.csrf!, serializeCookies(this.cookies)),\n },\n this.retries,\n );\n this.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 this.throwError(\n \"ACCOUNT_SWITCH_ERROR\",\n `Error switching account: ${message}`,\n );\n }\n }\n\n // ── Market Data ─────────────────────────────────────────────────────────────────────────────────────────────────────\n\n async getSymbolSuggestions(text: string): Promise<SymbolSuggestion[]> {\n this.ensureSession();\n\n try {\n const cookieStr = serializeCookies(this.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.suggest(this.baseUrl, text),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n this.retries,\n );\n\n const suggests = response.data?.suggests;\n if (!suggests?.length) {\n this.throwError(\"NO_SUGGESTIONS\", \"No symbol suggestions found\");\n }\n return suggests as SymbolSuggestion[];\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.throwError(\n \"SUGGEST_ERROR\",\n `Error getting symbol suggestions: ${message}`,\n );\n }\n }\n\n async getSymbolInfo(symbol: string): Promise<SymbolInfo> {\n this.ensureSession();\n\n try {\n const offsetMinutes = Math.abs(new Date().getTimezoneOffset());\n const cookieStr = serializeCookies(this.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.instrumentInfo(this.baseUrl, symbol, offsetMinutes),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n this.retries,\n );\n\n if (!response.data) {\n this.throwError(\"NO_SYMBOL_INFO\", \"No symbol info returned\");\n }\n return response.data as SymbolInfo;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.throwError(\n \"SYMBOL_INFO_ERROR\",\n `Error getting symbol info: ${message}`,\n );\n }\n }\n\n // ── Trading ─────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n async submitOrder(params: SubmitOrderParams): Promise<OrderUpdate> {\n this.ensureSession();\n\n const {\n symbol,\n side,\n quantity,\n orderType,\n price,\n instrumentId,\n stopLoss,\n takeProfit,\n positionEffect = ACTION.OPENING,\n } = params;\n const qty = side === SIDE.BUY ? Math.abs(quantity) : -Math.abs(quantity);\n const priceParam =\n orderType === ORDER_TYPE.STOP ? \"stopPrice\" : \"limitPrice\";\n\n const orderData: Record<string, unknown> = {\n directExchange: false,\n legs: [\n {\n ...(instrumentId != null && { instrumentId }),\n positionEffect,\n ratioQuantity: 1,\n symbol,\n },\n ],\n orderSide: side,\n orderType,\n quantity: qty,\n requestId: `gwt-uid-931-${crypto.randomUUID()}`,\n timeInForce: \"GTC\",\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 const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.submitOrder(this.baseUrl),\n data: orderData,\n headers: authHeaders(this.csrf!, serializeCookies(this.cookies)),\n },\n this.retries,\n );\n\n if (response.status !== 200) {\n this.throwError(\n \"ORDER_SUBMIT_FAILED\",\n `Order submission failed with status: ${response.status}`,\n );\n }\n\n this.callbacks.onOrderPlaced?.({\n status: response.status,\n data: response.data,\n });\n\n const wsUrl = endpoints.websocket(this.baseUrl);\n const cookieStr = serializeCookies(this.cookies);\n const orderUpdate = await waitForOrderUpdate(\n wsUrl,\n cookieStr,\n 30_000,\n this.debug,\n );\n\n this.callbacks.onOrderUpdate?.(orderUpdate);\n return orderUpdate;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error\n ? ((error as any).response?.data?.message ?? error.message)\n : \"Unknown error\";\n this.throwError(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n }\n\n // ── Analytics ───────────────────────────────────────────────────────────────────────────────────────────────────────\n\n async getAssessments(\n params: AssessmentsParams,\n ): Promise<AssessmentsResponse> {\n this.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.assessments(this.baseUrl),\n data: {\n from: params.from,\n instrument: params.instrument,\n subtype: params.subtype ?? null,\n to: params.to,\n },\n headers: authHeaders(this.csrf!, serializeCookies(this.cookies)),\n },\n this.retries,\n );\n\n return response.data as AssessmentsResponse;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.throwError(\n \"ASSESSMENTS_ERROR\",\n `Error fetching assessments: ${message}`,\n );\n }\n }\n\n // ── Convenience ─────────────────────────────────────────────────────────────────────────────────────────────────────\n\n async connect(): Promise<void> {\n await this.login();\n await this.fetchCsrf();\n\n const wsUrl = endpoints.websocket(this.baseUrl);\n const cookieStr = serializeCookies(this.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, this.debug);\n\n if (this.config.accountId) {\n await this.switchAccount(this.config.accountId);\n await waitForHandshake(\n endpoints.websocket(this.baseUrl),\n serializeCookies(this.cookies),\n 30_000,\n this.debug,\n );\n }\n }\n\n // ── Internals ───────────────────────────────────────────────────────────────────────────────────────────────────────\n\n private ensureSession(): void {\n if (!this.csrf) {\n throw new DxtradeError(\n \"NO_SESSION\",\n \"No active session. Call login() and fetchCsrf() or connect() first.\",\n );\n }\n }\n\n private throwError(code: string, message: string): never {\n const error = new DxtradeError(code, message);\n this.callbacks.onError?.(error);\n throw error;\n }\n}\n","export function parseCookies(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\nexport function serializeCookies(cookies: Record<string, string>): string {\n return Object.entries(cookies)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"; \");\n}\n\nexport function mergeCookies(existing: Record<string, string>, incoming: Record<string, string>): Record<string, string> {\n return { ...existing, ...incoming };\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 WebSocket from \"ws\";\n\nexport function waitForHandshake(wsUrl: string, cookieStr: string, timeout = 30_000, debug = false): 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 str = data.toString();\n if (debug) console.log(\"[dxtrade-api:ws]\", str);\n\n if (str.includes(`\"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 function waitForOrderUpdate(wsUrl: string, cookieStr: string, timeout = 30_000, debug = false): Promise<OrderUpdate> {\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] Order update timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const str = data.toString();\n if (debug) console.log(\"[dxtrade-api:ws]\", str);\n\n if (!str.includes(`\"ORDERS\"`)) return;\n if (!str.includes(`orderId`)) return;\n\n const json = str.replace(/^.*?\\{/, \"{\");\n if (!json.includes(\"{\")) return;\n\n try {\n const response = JSON.parse(json);\n const body = response.body?.[0] as OrderUpdate | undefined;\n if (!body) return;\n\n clearTimeout(timer);\n ws.close();\n\n if (body.status === \"REJECTED\") {\n reject(new Error(`[dxtrade-api] Order rejected: ${body.statusDescription ?? \"Unknown reason\"}`));\n } else {\n resolve(body);\n }\n } catch {\n // ignore parse errors, wait for next message\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket order listener error: ${error.message}`));\n });\n });\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants/brokers.ts","../src/constants/endpoints.ts","../src/constants/enums.ts","../src/constants/errors.ts","../src/domains/session/session.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts","../src/domains/symbol/symbol.ts","../src/domains/order/order.ts","../src/domains/assessments/assessments.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 ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\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 {\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","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, baseHeaders, retryRequest } 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","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 { 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 { resolveBrokerUrl, DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Assessments, Order, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\n getAssessments,\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 submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(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"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielgroen/dxtrade-api",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.8",
|
|
4
|
+
"description": "DXtrade trading API client library",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -16,14 +16,23 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"
|
|
20
|
-
"build": "
|
|
21
|
-
"dev": "
|
|
19
|
+
"================ Build ===============": "",
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"dev": "tsup --watch",
|
|
22
|
+
"================ Tests ================": "",
|
|
23
|
+
"test": "echo \"no test specified\";",
|
|
24
|
+
"=============== Examples ===============": "",
|
|
22
25
|
"example:connect": "tsx examples/connect.ts",
|
|
23
26
|
"example:order": "tsx examples/submit-order.ts",
|
|
24
27
|
"example:assessments": "tsx examples/get-assessments.ts",
|
|
28
|
+
"example:assessments:btc": "tsx examples/get-assessments.ts BTCUSD",
|
|
25
29
|
"example:symbol": "tsx examples/symbol-info.ts",
|
|
26
|
-
"example:symbol:btc": "tsx examples/symbol-info.ts BTCUSD"
|
|
30
|
+
"example:symbol:btc": "tsx examples/symbol-info.ts BTCUSD",
|
|
31
|
+
"========== Linting & Formatting ==========": "",
|
|
32
|
+
"lint": "eslint \"src/**/*.ts\" \"examples/**/*.ts\"",
|
|
33
|
+
"lint:fix": "eslint --fix \"src/**/*.ts\" \"examples/**/*.ts\"",
|
|
34
|
+
"format": "prettier --write \"src/**/*.ts\" \"examples/**/*.ts\"",
|
|
35
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"examples/**/*.ts\""
|
|
27
36
|
},
|
|
28
37
|
"dependencies": {
|
|
29
38
|
"axios": "^1.7.9",
|
|
@@ -31,7 +40,12 @@
|
|
|
31
40
|
},
|
|
32
41
|
"devDependencies": {
|
|
33
42
|
"@types/ws": "^8.5.14",
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "^8.55.0",
|
|
44
|
+
"@typescript-eslint/parser": "^8.55.0",
|
|
34
45
|
"dotenv": "^16.4.7",
|
|
46
|
+
"eslint": "^9.39.2",
|
|
47
|
+
"eslint-config-prettier": "^10.1.8",
|
|
48
|
+
"prettier": "^3.8.1",
|
|
35
49
|
"tsup": "^8.3.6",
|
|
36
50
|
"tsx": "^4.19.2",
|
|
37
51
|
"typescript": "^5.7.3"
|
|
@@ -41,4 +55,4 @@
|
|
|
41
55
|
"type": "git",
|
|
42
56
|
"url": "git+https://github.com/danielgroen/dxtrade-api.git"
|
|
43
57
|
}
|
|
44
|
-
}
|
|
58
|
+
}
|