@pipsend/sdk 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -428,7 +428,7 @@ var WebSocketManager = class {
|
|
|
428
428
|
return;
|
|
429
429
|
}
|
|
430
430
|
try {
|
|
431
|
-
this.ws.send(JSON.stringify({
|
|
431
|
+
this.ws.send(JSON.stringify({ action: "ping" }));
|
|
432
432
|
} catch (error) {
|
|
433
433
|
console.error("\u274C Failed to send ping:", error);
|
|
434
434
|
}
|
|
@@ -454,7 +454,7 @@ var WebSocketManager = class {
|
|
|
454
454
|
this.handleError(message);
|
|
455
455
|
break;
|
|
456
456
|
default:
|
|
457
|
-
console.warn(
|
|
457
|
+
console.warn(message.op);
|
|
458
458
|
}
|
|
459
459
|
this.emit("*", message);
|
|
460
460
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types/index.ts","../src/core/auth.ts","../src/core/websocket.ts","../src/api/http-client.ts","../src/api/accounts.ts","../src/api/trading-groups.ts","../src/api/market-data.ts","../src/api/positions.ts","../src/api/orders.ts","../src/api/trades.ts","../src/core/client.ts"],"sourcesContent":["// Export types\nexport type {\n PipsendConfig,\n TokenInfo,\n OrderData,\n AuthResponse,\n WebSocketConfig,\n WebSocketMessage,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketEventType,\n WebSocketCallback,\n // API types\n PaginationParams,\n PaginatedResponse,\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n ChangePasswordRequest,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n UpdatePositionRequest,\n Order,\n OrdersListParams,\n OrderStatistics,\n UpdateOrderRequest,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './types';\n\n// Export errors\nexport {\n PipsendError,\n AuthenticationError,\n ConfigurationError,\n WebSocketError\n} from './types';\n\n// Export client\nexport { PipsendClient } from './core/client';\n\n// Export creation function (main API)\nimport { PipsendClient } from './core/client';\nimport type { PipsendConfig } from './types';\n\n/**\n * Creates a new instance of the Pipsend client\n *\n * @example\n * ```typescript\n * import { createClient } from '@pipsend/sdk';\n *\n * const client = createClient({\n * server: 'https://api.pipsend.com',\n * login: 'your-username',\n * password: 'your-password',\n * timezone: 'America/New_York' // optional\n * });\n *\n * // The SDK handles authentication automatically\n * await client.orders.send({\n * symbol: 'EURUSD',\n * volume: 0.1\n * });\n * ```\n */\nexport function createClient(config: PipsendConfig): PipsendClient {\n return new PipsendClient(config);\n}\n\n// Export default for compatibility\nconst sdk = {\n createClient,\n PipsendClient\n};\n\nexport default sdk;\n","import type { WebSocketConfig } from './websocket';\n\n/**\n * Required configuration to initialize the Pipsend client\n */\nexport interface PipsendConfig {\n /** Pipsend server URL (required) */\n server: string;\n /** User credentials for SDK authentication (optional, for future use) */\n login?: string;\n /** User password for SDK authentication (optional, for future use) */\n password?: string;\n /** Timezone for operations (optional, default: UTC) */\n timezone?: string;\n /** Enable auto-refresh of tokens (default: true) */\n autoRefresh?: boolean;\n /** Safety margin for refresh in minutes (default: 5) */\n refreshMarginMinutes?: number;\n /** WebSocket configuration (optional) */\n websocket?: WebSocketConfig;\n}\n\n/**\n * Authentication token information\n */\nexport interface TokenInfo {\n token: string;\n refreshToken?: string;\n expiresAt: Date;\n issuedAt: Date;\n}\n\n/**\n * Trading order data\n */\nexport interface OrderData {\n symbol: string;\n volume: number;\n type?: 'buy' | 'sell';\n price?: number;\n stopLoss?: number;\n takeProfit?: number;\n}\n\n/**\n * Server authentication response from /api/v1/auth/login\n */\nexport interface AuthResponse {\n access_token: string;\n refresh_token: string;\n expires_in: number; // seconds (10800 = 180 minutes)\n token_type: string; // \"Bearer\"\n user: {\n login: number;\n email: string;\n first_name: string;\n last_name: string;\n balance: number;\n };\n logged_with: string; // \"master\" | \"investor\"\n}\n\n/**\n * Server refresh token response from /api/v1/auth/refresh\n */\nexport interface RefreshTokenResponse {\n access_token: string;\n expires_in: number;\n token_type: string;\n}\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\n/**\n * Custom SDK errors\n */\nexport class PipsendError extends Error {\n public errors?: ValidationError[];\n public response?: any;\n\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n errors?: ValidationError[],\n response?: any\n ) {\n super(message);\n this.name = 'PipsendError';\n this.errors = errors;\n this.response = response;\n }\n\n /**\n * Get formatted error message with validation details\n */\n getDetailedMessage(): string {\n if (!this.errors || this.errors.length === 0) {\n return this.message;\n }\n\n const errorDetails = this.errors\n .map(err => ` - ${err.field}: ${err.message}`)\n .join('\\n');\n\n return `${this.message}\\n${errorDetails}`;\n }\n\n /**\n * Check if this is a validation error\n */\n isValidationError(): boolean {\n return this.statusCode === 422 || this.code === 'VALIDATION_ERROR';\n }\n}\n\nexport class AuthenticationError extends PipsendError {\n constructor(message: string) {\n super(message, 'AUTH_ERROR', 401);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ConfigurationError extends PipsendError {\n constructor(message: string) {\n super(message, 'CONFIG_ERROR');\n this.name = 'ConfigurationError';\n }\n}\n\nexport class WebSocketError extends PipsendError {\n constructor(message: string) {\n super(message, 'WEBSOCKET_ERROR');\n this.name = 'WebSocketError';\n }\n}\n\n// Re-export WebSocket types\nexport type {\n WebSocketConfig,\n WebSocketMessage,\n WebSocketChannel,\n WebSocketOperation,\n PositionEventType,\n ConnectedMessage,\n SubscriptionSuccessMessage,\n UnsubscriptionSuccessMessage,\n ErrorMessage,\n PositionData,\n PositionEvent,\n BalanceEvent,\n SubscribeAction,\n UnsubscribeAction,\n WebSocketEventType,\n WebSocketCallback,\n // Legacy types (deprecated)\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate\n} from './websocket';\n\n// Re-export common types\nexport type {\n PaginationParams,\n PaginatedResponse\n} from './common';\n\n// Re-export all API types\nexport type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatus,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse,\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './api';\n","import type { PipsendConfig, TokenInfo, AuthResponse, RefreshTokenResponse } from '../types';\nimport { AuthenticationError } from '../types';\n\n/**\n * Authentication manager with auto-refresh tokens\n */\nexport class AuthManager {\n private tokenInfo?: TokenInfo;\n private refreshMarginMs: number;\n\n constructor(\n private config: PipsendConfig\n ) {\n const marginMinutes = config.refreshMarginMinutes ?? 5;\n this.refreshMarginMs = marginMinutes * 60 * 1000;\n }\n\n /**\n * Checks if a valid token is available\n */\n public isAuthenticated(): boolean {\n return !!this.tokenInfo && !this.isTokenExpired();\n }\n\n /**\n * Gets the current token (if it exists and is valid)\n */\n public getToken(): string | undefined {\n if (this.isAuthenticated()) {\n return this.tokenInfo?.token;\n }\n return undefined;\n }\n\n /**\n * Ensures a valid token exists, authenticating if necessary\n */\n public async ensureAuthenticated(): Promise<string> {\n if (!this.isAuthenticated()) {\n await this.authenticate();\n }\n return this.tokenInfo!.token;\n }\n\n /**\n * Performs authentication with the server\n */\n private async authenticate(): Promise<void> {\n if (!this.config.login || !this.config.password) {\n throw new AuthenticationError(\n 'Login and password are required for authentication. Please provide them in the config.'\n );\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n login: this.config.login,\n password: this.config.password\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as any;\n throw new AuthenticationError(\n errorData.message || `Authentication failed: ${response.status} ${response.statusText}`\n );\n }\n\n const data = await response.json() as AuthResponse;\n this.setTokenInfo(data);\n\n console.log('✅ Authentication successful');\n console.log(` User: ${data.user.first_name} ${data.user.last_name} (${data.user.email})`);\n console.log(` Login: ${data.user.login}`);\n console.log(` Balance: $${data.user.balance.toFixed(2)}`);\n console.log(` Logged with: ${data.logged_with}`);\n } catch (error) {\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `Authentication error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Refreshes the access token using the refresh token\n */\n public async refreshToken(): Promise<void> {\n if (!this.tokenInfo?.refreshToken) {\n console.log('⚠️ No refresh token available, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/refresh`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n refresh_token: this.tokenInfo.refreshToken\n })\n });\n\n if (!response.ok) {\n console.log('⚠️ Refresh token failed, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n const data = await response.json() as RefreshTokenResponse;\n \n // Update token info, keeping the same refresh token\n const now = new Date();\n const expiresAt = new Date(now.getTime() + data.expires_in * 1000);\n\n this.tokenInfo = {\n token: data.access_token,\n refreshToken: this.tokenInfo.refreshToken, // Keep the same refresh token\n issuedAt: now,\n expiresAt\n };\n\n console.log('✅ Token refreshed successfully');\n } catch (error) {\n console.error('❌ Error refreshing token:', error);\n this.tokenInfo = undefined;\n await this.authenticate();\n }\n }\n\n /**\n * Clears the current token\n */\n public clearToken(): void {\n this.tokenInfo = undefined;\n }\n\n /**\n * Checks if the token is expired or about to expire\n */\n private isTokenExpired(): boolean {\n if (!this.tokenInfo) return true;\n\n const now = Date.now();\n const expiryWithMargin = this.tokenInfo.expiresAt.getTime() - this.refreshMarginMs;\n\n return now >= expiryWithMargin;\n }\n\n /**\n * Stores the received token information\n */\n private setTokenInfo(response: AuthResponse): void {\n const now = new Date();\n const expiresAt = new Date(now.getTime() + response.expires_in * 1000);\n\n this.tokenInfo = {\n token: response.access_token,\n refreshToken: response.refresh_token,\n issuedAt: now,\n expiresAt\n };\n }\n}\n","import type { \n PipsendConfig, \n WebSocketMessage, \n WebSocketEventType,\n WebSocketCallback,\n WebSocketChannel,\n SubscribeAction,\n UnsubscribeAction,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport { WebSocketError } from '../types';\nimport { AuthManager } from './auth';\n\n/**\n * WebSocket manager for real-time updates\n * Handles connection, reconnection, subscriptions, and event dispatching\n */\nexport class WebSocketManager {\n private ws?: any; // WebSocket instance (browser or ws package)\n private reconnectAttempts = 0;\n private heartbeatTimer?: NodeJS.Timeout;\n private listeners = new Map<string, Set<WebSocketCallback>>();\n private isConnected = false;\n private subscribedChannels: WebSocketChannel[] = [];\n private isReconnecting = false;\n\n constructor(\n private config: PipsendConfig,\n private authManager: AuthManager\n ) {}\n\n /**\n * Connects to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.isConnected) {\n console.log('⚠️ WebSocket already connected');\n return;\n }\n\n if (this.isReconnecting) {\n console.log('⚠️ WebSocket reconnection in progress');\n return;\n }\n\n // Get token first\n const token = await this.authManager.ensureAuthenticated();\n \n // Build WebSocket URL with token as query parameter\n const baseWsUrl = this.buildWebSocketUrl();\n const wsUrl = `${baseWsUrl}${baseWsUrl.includes('?') ? '&' : '?'}token=${encodeURIComponent(token)}`;\n\n return new Promise((resolve, reject) => {\n try {\n const WS = this.getWebSocketConstructor();\n this.ws = new WS(wsUrl);\n\n this.ws.onopen = () => {\n console.log('✅ WebSocket connected');\n this.isConnected = true;\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n\n // Emit connected event\n this.emit('connected', { timestamp: Date.now() });\n\n // Resubscribe to channels if reconnecting\n if (this.subscribedChannels.length > 0) {\n console.log('🔄 Resubscribing to channels:', this.subscribedChannels);\n this.subscribe(this.subscribedChannels);\n }\n\n // Start heartbeat\n this.startHeartbeat();\n\n resolve();\n };\n\n this.ws.onmessage = (event: any) => {\n try {\n const data = JSON.parse(event.data);\n this.handleMessage(data);\n } catch (error) {\n console.error('❌ Failed to parse WebSocket message:', error);\n }\n };\n\n this.ws.onerror = (error: any) => {\n console.error('❌ WebSocket error:', error);\n this.emit('error', error);\n \n if (!this.isConnected) {\n reject(new WebSocketError('Failed to connect to WebSocket server'));\n }\n };\n\n this.ws.onclose = (event: any) => {\n console.log('WebSocket disconnected', event.code, event.reason);\n this.isConnected = false;\n this.stopHeartbeat();\n this.emit('disconnected', { \n code: event.code, \n reason: event.reason,\n timestamp: Date.now()\n });\n this.handleReconnect();\n };\n\n } catch (error) {\n reject(new WebSocketError(\n `Failed to create WebSocket: ${error instanceof Error ? error.message : 'Unknown error'}`\n ));\n }\n });\n }\n\n /**\n * Subscribes to WebSocket channels\n */\n subscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n throw new WebSocketError('WebSocket not connected. Call connect() first.');\n }\n\n // Add to subscribed channels (avoid duplicates)\n this.subscribedChannels = [...new Set([...this.subscribedChannels, ...channels])];\n\n // Send subscription message with correct format\n const message: SubscribeAction = {\n action: 'subscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Subscribed to channels:', channels);\n }\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n console.warn('WebSocket not connected, cannot unsubscribe');\n return;\n }\n\n // Remove from subscribed channels\n this.subscribedChannels = this.subscribedChannels.filter(\n ch => !channels.includes(ch)\n );\n\n // Send unsubscription message with correct format\n const message: UnsubscribeAction = {\n action: 'unsubscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Unsubscribed from channels:', channels);\n }\n\n /**\n * Registers an event listener\n */\n on(event: WebSocketEventType, callback: WebSocketCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback);\n }\n\n /**\n * Removes an event listener\n */\n off(event: WebSocketEventType, callback?: WebSocketCallback): void {\n if (!callback) {\n // Remove all listeners for this event\n this.listeners.delete(event);\n } else {\n // Remove specific listener\n this.listeners.get(event)?.delete(callback);\n }\n }\n\n /**\n * Disconnects from WebSocket\n */\n disconnect(): void {\n console.log('👋 Disconnecting WebSocket...');\n this.stopHeartbeat();\n \n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n \n this.isConnected = false;\n this.isReconnecting = false;\n this.subscribedChannels = [];\n this.listeners.clear();\n }\n\n /**\n * Checks if WebSocket is connected\n */\n isWebSocketConnected(): boolean {\n return this.isConnected;\n }\n\n /**\n * Gets list of subscribed channels\n */\n getSubscribedChannels(): WebSocketChannel[] {\n return [...this.subscribedChannels];\n }\n\n // Private methods\n\n /**\n * Builds WebSocket URL from HTTP(S) server URL\n */\n private buildWebSocketUrl(): string {\n try {\n const url = new URL(this.config.server);\n \n // Convert https:// to wss:// or http:// to ws://\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n \n // Add WebSocket path (default to /api/v1/ws for Pipsend API)\n const wsPath = this.config.websocket?.path || '/api/v1/ws';\n url.pathname = wsPath;\n \n return url.toString();\n } catch (error) {\n throw new WebSocketError('Invalid server URL for WebSocket connection');\n }\n }\n\n /**\n * Gets WebSocket constructor (browser or Node.js)\n */\n private getWebSocketConstructor(): any {\n // Browser environment\n if (typeof WebSocket !== 'undefined') {\n return WebSocket;\n }\n \n // Node.js environment - try to load 'ws' package\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require('ws');\n } catch {\n throw new WebSocketError(\n 'WebSocket not available. Install \"ws\" package for Node.js: npm install ws'\n );\n }\n }\n\n /**\n * Sends an action message through WebSocket\n */\n private sendAction(message: SubscribeAction | UnsubscribeAction): void {\n if (!this.ws || !this.isConnected) {\n console.warn('⚠️ WebSocket not ready, message not sent:', message.action);\n return;\n }\n\n try {\n const payload = JSON.stringify(message);\n this.ws.send(payload);\n } catch (error) {\n console.error('❌ Failed to send WebSocket message:', error);\n }\n }\n\n /**\n * Sends a ping message (for heartbeat)\n */\n private sendPing(): void {\n if (!this.ws || !this.isConnected) {\n return;\n }\n\n try {\n this.ws.send(JSON.stringify({ type: 'ping' }));\n } catch (error) {\n console.error('❌ Failed to send ping:', error);\n }\n }\n\n /**\n * Handles incoming WebSocket messages\n */\n private handleMessage(message: WebSocketMessage): void {\n switch (message.op) {\n case 'connected':\n this.handleConnected(message);\n break;\n \n case 'subscription_success':\n this.handleSubscriptionSuccess(message);\n break;\n \n case 'unsubscription_success':\n this.handleUnsubscriptionSuccess(message);\n break;\n \n case 'push':\n this.handlePushEvent(message);\n break;\n \n case 'error':\n this.handleError(message);\n break;\n \n default:\n console.warn('Unknown WebSocket operation:', message.op);\n }\n\n // Emit to wildcard listeners (listen to all events)\n this.emit('*', message);\n }\n\n /**\n * Handles connected message from server\n */\n private handleConnected(message: WebSocketMessage): void {\n console.log('✅ WebSocket connected:', message.data.message);\n console.log(' Available channels:', message.data.available_channels);\n this.emit('connected', message.data);\n }\n\n /**\n * Handles subscription success\n */\n private handleSubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Subscription successful:', message.data.subscribed);\n this.emit('subscription_success', message.data);\n }\n\n /**\n * Handles unsubscription success\n */\n private handleUnsubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Unsubscription successful:', message.data.unsubscribed);\n this.emit('unsubscription_success', message.data);\n }\n\n /**\n * Handles push events (actual data events)\n */\n private handlePushEvent(message: WebSocketMessage): void {\n const eventData = message.data;\n const eventType = eventData.type;\n \n switch (eventType) {\n case 'position.opened':\n this.emit('position:opened', eventData as PositionEvent);\n break;\n \n case 'position.closed':\n case 'position.partially_closed':\n this.emit('position:closed', eventData as PositionEvent);\n break;\n \n case 'position.updated':\n this.emit('position:updated', eventData as PositionEvent);\n break;\n \n default:\n // Balance update (doesn't have 'type' field)\n if (message.topic?.startsWith('balance:')) {\n this.emit('balance:updated', eventData as BalanceEvent);\n } else {\n console.warn('Unknown event type:', eventType);\n }\n }\n }\n\n /**\n * Handles error messages from server\n */\n private handleError(message: WebSocketMessage): void {\n console.error('❌ WebSocket error:', message.data.message);\n if (message.data.error) {\n console.error(' Error details:', message.data.error);\n }\n this.emit('error', message.data);\n }\n\n /**\n * Emits an event to all registered listeners\n */\n private emit(event: WebSocketEventType, data: any): void {\n const listeners = this.listeners.get(event);\n if (listeners && listeners.size > 0) {\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`❌ Error in WebSocket listener for \"${event}\":`, error);\n }\n });\n }\n }\n\n /**\n * Handles reconnection logic with exponential backoff\n */\n private handleReconnect(): void {\n const autoReconnect = this.config.websocket?.autoReconnect ?? true;\n const maxAttempts = this.config.websocket?.maxReconnectAttempts ?? 5;\n\n if (!autoReconnect) {\n console.log('Auto-reconnect disabled');\n return;\n }\n\n if (this.reconnectAttempts >= maxAttempts) {\n console.log(`❌ Max reconnection attempts (${maxAttempts}) reached. Giving up.`);\n this.emit('error', new WebSocketError('Max reconnection attempts reached'));\n return;\n }\n\n // Exponential backoff: 1s, 2s, 4s, 8s, 16s, max 30s\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n console.log(\n `🔄 Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts + 1}/${maxAttempts})...`\n );\n\n this.isReconnecting = true;\n\n setTimeout(() => {\n this.reconnectAttempts++;\n this.connect().catch(error => {\n console.error('❌ Reconnection failed:', error);\n });\n }, delay);\n }\n\n /**\n * Starts heartbeat to keep connection alive\n */\n private startHeartbeat(): void {\n const interval = this.config.websocket?.heartbeatInterval || 30000;\n \n this.heartbeatTimer = setInterval(() => {\n if (this.isConnected) {\n this.sendPing();\n }\n }, interval);\n }\n\n /**\n * Stops heartbeat timer\n */\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = undefined;\n }\n }\n}\n","import { PipsendError } from '../types';\nimport type { AuthManager } from '../core/auth';\n\n/**\n * HTTP client for making requests to the Pipsend API\n */\nexport class HttpClient {\n constructor(\n private baseUrl: string,\n private authManager?: AuthManager\n ) {}\n\n /**\n * Makes an HTTP request\n */\n async request<T>(\n endpoint: string,\n options: RequestInit = {},\n retryOn401 = true\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n try {\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {})\n };\n\n // Add Authorization header if authManager is available\n if (this.authManager) {\n const token = await this.authManager.ensureAuthenticated();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, {\n ...options,\n headers\n });\n\n // Handle 401 Unauthorized - try to refresh token and retry\n if (response.status === 401 && this.authManager && retryOn401) {\n console.log('⚠️ Received 401, attempting to refresh token...');\n await this.authManager.refreshToken();\n \n // Retry the request with new token (but don't retry again if it fails)\n return this.request<T>(endpoint, options, false);\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = `HTTP ${response.status}: ${errorText || response.statusText}`;\n let errorCode = 'HTTP_ERROR';\n let validationErrors;\n let errorResponse;\n \n // Try to parse error as JSON for better error messages\n try {\n const errorJson = JSON.parse(errorText);\n errorResponse = errorJson;\n \n // Extract message\n if (errorJson.message) {\n errorMessage = errorJson.message;\n }\n \n // Extract error code\n if (errorJson.status_code) {\n errorCode = errorJson.status_code;\n }\n \n // Extract validation errors (422 responses)\n if (errorJson.errors && Array.isArray(errorJson.errors)) {\n validationErrors = errorJson.errors;\n }\n } catch {\n // Keep the original error message if JSON parsing fails\n }\n\n throw new PipsendError(\n errorMessage,\n errorCode,\n response.status,\n validationErrors,\n errorResponse\n );\n }\n\n // Handle empty responses\n const text = await response.text();\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n } catch (error) {\n if (error instanceof PipsendError) {\n throw error;\n }\n throw new PipsendError(\n `Request failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n );\n }\n }\n\n /**\n * GET request\n */\n async get<T>(endpoint: string, params?: Record<string, any>): Promise<T> {\n const queryString = params ? this.buildQueryString(params) : '';\n const url = queryString ? `${endpoint}?${queryString}` : endpoint;\n return this.request<T>(url, { method: 'GET' });\n }\n\n /**\n * POST request\n */\n async post<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * PUT request\n */\n async put<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * Builds query string from params object\n */\n private buildQueryString(params: Record<string, any>): string {\n const filtered = Object.entries(params)\n .filter(([_, value]) => value !== undefined && value !== null && value !== '')\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n \n return filtered.join('&');\n }\n}\n","import type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse\n} from '../types/api/accounts';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Accounts API\n */\nexport class AccountsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a new trading account\n */\n async create(request: CreateAccountRequest): Promise<CreateAccountResponse> {\n return this.http.post<CreateAccountResponse>('/api/v1/accounts', request);\n }\n\n /**\n * List all accounts with optional filters and pagination\n */\n async list(params?: AccountsListParams): Promise<PaginatedResponse<Account> | Account[]> {\n return this.http.get<PaginatedResponse<Account> | Account[]>('/api/v1/accounts', params);\n }\n\n /**\n * Get all account logins\n */\n async getLogins(): Promise<number[]> {\n return this.http.get<number[]>('/api/v1/accounts/logins');\n }\n\n /**\n * Get account status/metrics (balance, equity, credit, margin)\n */\n async getStatus(login: number): Promise<AccountStatusResponse> {\n return this.http.get<AccountStatusResponse>(`/api/v1/accounts/${login}/status`);\n }\n\n /**\n * Get account statistics with optional filters\n */\n async getStatistics(params?: AccountStatisticsParams): Promise<AccountStatistics> {\n return this.http.get<AccountStatistics>('/api/v1/accounts/statistics', params);\n }\n\n /**\n * Change master password for an account\n */\n async changeMasterPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/master`, request);\n }\n\n /**\n * Change investor password for an account\n */\n async changeInvestorPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/investor`, request);\n }\n\n /**\n * Archive an account\n */\n async archive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/archive`);\n }\n\n /**\n * Unarchive an account\n */\n async unarchive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/unarchive`);\n }\n\n /**\n * Update account information (partial update)\n * All fields are optional, only send the ones you want to update\n */\n async update(login: number, request: UpdateAccountRequest): Promise<UpdateAccountResponse> {\n return this.http.put<UpdateAccountResponse>(`/api/v1/accounts/${login}`, request);\n }\n\n /**\n * Adjust balance or credit for an account\n * The adjustment is relative: amount is added or subtracted from current value\n */\n async balance(login: number, request: AdjustBalanceRequest): Promise<AdjustBalanceResponse> {\n return this.http.put<AdjustBalanceResponse>(`/api/v1/accounts/${login}/adjust`, request);\n }\n}\n","import type {\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics\n} from '../types/api/trading-groups';\nimport { HttpClient } from './http-client';\n\n/**\n * Trading Groups API\n */\nexport class TradingGroupsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List all trading groups with optional filters\n */\n async list(params?: TradingGroupsListParams): Promise<TradingGroup[]> {\n return this.http.get<TradingGroup[]>('/api/v1/trading-groups', params);\n }\n\n /**\n * Get trading group by name\n */\n async getByName(name: string): Promise<TradingGroup> {\n return this.http.get<TradingGroup>(`/api/v1/trading-groups/${encodeURIComponent(name)}`);\n }\n\n /**\n * Get all trading group names\n */\n async getNames(): Promise<string[]> {\n return this.http.get<string[]>('/api/v1/trading-groups/names');\n }\n\n /**\n * Get trading group statistics\n */\n async getStatistics(type?: string): Promise<TradingGroupStatistics> {\n return this.http.get<TradingGroupStatistics>('/api/v1/trading-groups/statistics', type ? { type } : undefined);\n }\n}\n","import type {\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams\n} from '../types/api/market-data';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Market Data API\n * \n * Note: All data has a minimum age of 1 hour (no real-time data)\n */\nexport class MarketDataAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Get historical OHLCV candles\n * \n * @param params - Candles parameters (symbol and timeframe are required)\n * @returns Paginated candles or array of candles\n * \n * @example\n * ```ts\n * // Get last 100 candles\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD',\n * timeframe: '1m',\n * limit: 100,\n * order: 'desc'\n * });\n * \n * // Get candles with time range\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD,ETHUSD',\n * timeframe: '1h',\n * from: '2025-11-01T00:00:00Z',\n * to: '2025-11-02T00:00:00Z'\n * });\n * ```\n */\n async getCandles(params: CandlesParams): Promise<PaginatedResponse<Candle> | Candle[]> {\n return this.http.get<PaginatedResponse<Candle> | Candle[]>('/api/v1/candles', params);\n }\n\n /**\n * Get available symbols with metadata\n * \n * @param params - Optional filters for symbols\n * @returns Paginated symbols or array of symbols\n * \n * @example\n * ```ts\n * // Get all symbols\n * const symbols = await client.marketData.getSymbols();\n * \n * // Filter by group\n * const cryptoSymbols = await client.marketData.getSymbols({\n * group: 'CRYPTO_MAJOR',\n * has_data: true\n * });\n * ```\n */\n async getSymbols(params?: SymbolsParams): Promise<PaginatedResponse<Symbol> | Symbol[]> {\n return this.http.get<PaginatedResponse<Symbol> | Symbol[]>('/api/v1/symbols', params);\n }\n\n /**\n * Get symbol groups hierarchy\n * \n * Note: This endpoint never uses pagination\n * \n * @param params - Optional filters for groups\n * @returns Array of groups\n * \n * @example\n * ```ts\n * // Get all groups\n * const groups = await client.marketData.getGroups();\n * \n * // Get only root groups\n * const rootGroups = await client.marketData.getGroups({\n * root_only: true\n * });\n * ```\n */\n async getGroups(params?: GroupsParams): Promise<Group[]> {\n return this.http.get<Group[]>('/api/v1/groups', params);\n }\n}\n","import type {\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse\n} from '../types/api/positions';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Positions API\n */\nexport class PositionsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List positions with optional filters and pagination\n */\n async list(params?: PositionsListParams): Promise<PaginatedResponse<Position> | Position[]> {\n return this.http.get<PaginatedResponse<Position> | Position[]>('/api/v1/positions', params);\n }\n\n /**\n * Get position statistics with optional filters and grouping\n */\n async getStats(params?: PositionStatsParams): Promise<PositionStatistics | PositionStatisticsGrouped[]> {\n return this.http.get<PositionStatistics | PositionStatisticsGrouped[]>('/api/v1/positions/stats', params);\n }\n\n /**\n * Get position totals with dynamic grouping\n */\n async getTotals(params: PositionTotalsParams): Promise<PositionTotals[]> {\n return this.http.get<PositionTotals[]>('/api/v1/positions/totals', params);\n }\n\n /**\n * Update position (modify SL/TP)\n */\n async update(id: number, request: UpdatePositionRequest): Promise<UpdatePositionResponse> {\n return this.http.put<UpdatePositionResponse>(`/api/v1/positions/${id}`, request);\n }\n\n /**\n * Delete (close) position\n */\n async delete(id: number, params: DeletePositionParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/positions/${id}?login=${params.login}`);\n }\n\n /**\n * Check and recalculate positions\n */\n async check(request: CheckPositionsRequest): Promise<CheckPositionsResponse> {\n return this.http.post<CheckPositionsResponse>('/api/v1/positions/check', request);\n }\n}\n","import type {\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse\n} from '../types/api/orders';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Orders API\n */\nexport class OrdersAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List orders with optional filters and pagination\n */\n async list(params?: OrdersListParams): Promise<PaginatedResponse<Order> | Order[]> {\n return this.http.get<PaginatedResponse<Order> | Order[]>('/api/v1/orders', params);\n }\n\n /**\n * Get order statistics with optional filters and grouping\n */\n async getStats(params?: OrderStatsParams): Promise<OrderStatistics | OrderStatisticsGrouped[]> {\n return this.http.get<OrderStatistics | OrderStatisticsGrouped[]>('/api/v1/orders/stats', params);\n }\n\n /**\n * Get order totals with dynamic grouping\n */\n async getTotals(params: OrderTotalsParams): Promise<OrderTotals[]> {\n return this.http.get<OrderTotals[]>('/api/v1/orders/totals', params);\n }\n\n /**\n * Update order (modify SL/TP)\n */\n async update(id: number, request: UpdateOrderRequest): Promise<UpdateOrderResponse> {\n return this.http.put<UpdateOrderResponse>(`/api/v1/orders/${id}`, request);\n }\n\n /**\n * Delete (cancel) order\n */\n async delete(id: number, params: DeleteOrderParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/orders/${id}?login=${params.login}`);\n }\n\n /**\n * Check and validate pending orders\n */\n async check(request: CheckOrdersRequest): Promise<CheckOrdersResponse> {\n return this.http.post<CheckOrdersResponse>('/api/v1/orders/check', request);\n }\n}\n","import type {\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse\n} from '../types/api/trades';\nimport { HttpClient } from './http-client';\n\n/**\n * Trades API\n */\nexport class TradesAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Open a new trade (market or pending order)\n */\n async open(request: OpenTradeRequest): Promise<OpenTradeResponse> {\n return this.http.post<OpenTradeResponse>('/api/v1/trades/open', request);\n }\n\n /**\n * Close a trade (full or partial)\n */\n async close(request: CloseTradeRequest): Promise<CloseTradeResponse> {\n return this.http.post<CloseTradeResponse>('/api/v1/trades/close', request);\n }\n\n /**\n * Modify trade Stop Loss and/or Take Profit\n */\n async modify(request: ModifyTradeRequest): Promise<ModifyTradeResponse> {\n return this.http.put<ModifyTradeResponse>('/api/v1/trades/modify', request);\n }\n\n /**\n * Check if there's sufficient margin for a trade\n */\n async checkMargin(request: CheckMarginRequest): Promise<CheckMarginResponse> {\n return this.http.post<CheckMarginResponse>('/api/v1/trades/check-margin', request);\n }\n\n /**\n * Calculate potential profit for a trade\n */\n async calculateProfit(request: CalculateProfitRequest): Promise<CalculateProfitResponse> {\n return this.http.post<CalculateProfitResponse>('/api/v1/trades/calc-profit', request);\n }\n}\n","import type { \n PipsendConfig,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketCallback,\n WebSocketChannel,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport type { HealthCheckResponse } from '../types/api/health';\nimport { ConfigurationError, WebSocketError } from '../types';\nimport { AuthManager } from './auth';\nimport { WebSocketManager } from './websocket';\nimport { \n HttpClient,\n AccountsAPI,\n TradingGroupsAPI,\n MarketDataAPI,\n PositionsAPI,\n OrdersAPI,\n TradesAPI\n} from '../api';\n\n/**\n * Main Pipsend SDK client\n */\nexport class PipsendClient {\n private authManager: AuthManager;\n private wsManager?: WebSocketManager;\n private config: PipsendConfig;\n private http: HttpClient;\n\n // API modules\n public readonly accounts: AccountsAPI;\n public readonly tradingGroups: TradingGroupsAPI;\n public readonly marketData: MarketDataAPI;\n public readonly positions: PositionsAPI;\n public readonly orders: OrdersAPI;\n public readonly trades: TradesAPI;\n\n constructor(config: PipsendConfig) {\n this.validateConfig(config);\n this.config = {\n ...config,\n autoRefresh: config.autoRefresh ?? true,\n refreshMarginMinutes: config.refreshMarginMinutes ?? 5,\n timezone: config.timezone ?? 'UTC'\n };\n this.authManager = new AuthManager(this.config);\n\n // Initialize HTTP client with auth manager\n this.http = new HttpClient(this.config.server, this.authManager);\n\n // Initialize API modules\n this.accounts = new AccountsAPI(this.http);\n this.tradingGroups = new TradingGroupsAPI(this.http);\n this.marketData = new MarketDataAPI(this.http);\n this.positions = new PositionsAPI(this.http);\n this.orders = new OrdersAPI(this.http);\n this.trades = new TradesAPI(this.http);\n\n // Initialize WebSocket if enabled\n if (config.websocket?.enabled) {\n this.wsManager = new WebSocketManager(this.config, this.authManager);\n \n // Auto-connect if configured\n if (config.websocket.autoConnect) {\n this.wsManager.connect().catch(error => {\n console.error('Failed to auto-connect WebSocket:', error);\n });\n }\n }\n }\n\n /**\n * Validates the initial configuration\n */\n private validateConfig(config: PipsendConfig): void {\n if (!config.server) {\n throw new ConfigurationError('The \"server\" parameter is required');\n }\n\n // Validate URL format\n try {\n new URL(config.server);\n } catch {\n throw new ConfigurationError('The \"server\" parameter must be a valid URL');\n }\n\n // Note: login and password are optional for now (will be required when auth is implemented)\n }\n\n /**\n * Authentication API\n * TODO: Implement when authentication is available\n */\n public auth = {\n /**\n * Forces a token refresh\n */\n refresh: async (): Promise<void> => {\n await this.authManager.refreshToken();\n },\n\n /**\n * Checks if the client is authenticated\n */\n isAuthenticated: (): boolean => {\n return this.authManager.isAuthenticated();\n },\n\n /**\n * Gets the current token (if it exists)\n */\n getToken: (): string | undefined => {\n return this.authManager.getToken();\n },\n\n /**\n * Logs out by clearing the token\n */\n logout: (): void => {\n this.authManager.clearToken();\n }\n };\n\n /**\n * WebSocket streaming API\n * Provides real-time updates for prices, orders, positions, etc.\n */\n public stream = {\n /**\n * Connects to WebSocket server\n */\n connect: async (): Promise<void> => {\n if (!this.wsManager) {\n throw new WebSocketError(\n 'WebSocket not enabled. Set websocket.enabled: true in config'\n );\n }\n await this.wsManager.connect();\n },\n\n /**\n * Disconnects from WebSocket server\n */\n disconnect: (): void => {\n this.wsManager?.disconnect();\n },\n\n /**\n * Checks if WebSocket is connected\n */\n isConnected: (): boolean => {\n return this.wsManager?.isWebSocketConnected() ?? false;\n },\n\n /**\n * Subscribes to WebSocket channels\n * @example\n * client.stream.subscribe(['positions:new', 'positions:closed']);\n */\n subscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.subscribe(channels);\n },\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.unsubscribe(channels);\n },\n\n /**\n * Gets list of subscribed channels\n */\n getSubscriptions: (): WebSocketChannel[] => {\n return this.wsManager?.getSubscribedChannels() ?? [];\n },\n\n /**\n * Listens to position opened events\n */\n onPositionOpened: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:opened', callback);\n },\n\n /**\n * Listens to position closed events (includes partial closes)\n */\n onPositionClosed: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:closed', callback);\n },\n\n /**\n * Listens to position updated events (throttled to max 1 per 2 seconds)\n */\n onPositionUpdated: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback);\n },\n\n /**\n * Listens to balance updated events\n */\n onBalanceUpdated: (callback: WebSocketCallback<BalanceEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback);\n },\n\n // Legacy methods (deprecated but kept for compatibility)\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPriceUpdate: (callback: WebSocketCallback<PriceUpdate>): void => {\n console.warn('⚠️ onPriceUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new event for backward compatibility\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onPositionOpened/onPositionClosed instead\n */\n onOrderUpdate: (callback: WebSocketCallback<OrderUpdate>): void => {\n console.warn('⚠️ onOrderUpdate is deprecated. Use onPositionOpened/onPositionClosed instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new events for backward compatibility\n this.wsManager.on('position:opened', callback as any);\n },\n\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPositionUpdate: (callback: WebSocketCallback<PositionUpdate>): void => {\n console.warn('⚠️ onPositionUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onBalanceUpdated instead\n */\n onBalanceUpdate: (callback: WebSocketCallback<BalanceUpdate>): void => {\n console.warn('⚠️ onBalanceUpdate is deprecated. Use onBalanceUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback as any);\n },\n\n /**\n * Listens to connection events\n */\n onConnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('connected', callback);\n },\n\n /**\n * Listens to disconnection events\n */\n onDisconnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('disconnected', callback);\n },\n\n /**\n * Listens to error events\n */\n onError: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('error', callback);\n },\n\n /**\n * Removes event listener\n */\n off: (event: string, callback?: WebSocketCallback): void => {\n this.wsManager?.off(event as any, callback);\n }\n };\n\n /**\n * Health check\n */\n async ping(): Promise<HealthCheckResponse> {\n return this.http.get<HealthCheckResponse>('/ping');\n }\n\n /**\n * Client information\n */\n public getConfig(): Readonly<PipsendConfig> {\n return { ...this.config };\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types/index.ts","../src/core/auth.ts","../src/core/websocket.ts","../src/api/http-client.ts","../src/api/accounts.ts","../src/api/trading-groups.ts","../src/api/market-data.ts","../src/api/positions.ts","../src/api/orders.ts","../src/api/trades.ts","../src/core/client.ts"],"sourcesContent":["// Export types\nexport type {\n PipsendConfig,\n TokenInfo,\n OrderData,\n AuthResponse,\n WebSocketConfig,\n WebSocketMessage,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketEventType,\n WebSocketCallback,\n // API types\n PaginationParams,\n PaginatedResponse,\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n ChangePasswordRequest,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n UpdatePositionRequest,\n Order,\n OrdersListParams,\n OrderStatistics,\n UpdateOrderRequest,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './types';\n\n// Export errors\nexport {\n PipsendError,\n AuthenticationError,\n ConfigurationError,\n WebSocketError\n} from './types';\n\n// Export client\nexport { PipsendClient } from './core/client';\n\n// Export creation function (main API)\nimport { PipsendClient } from './core/client';\nimport type { PipsendConfig } from './types';\n\n/**\n * Creates a new instance of the Pipsend client\n *\n * @example\n * ```typescript\n * import { createClient } from '@pipsend/sdk';\n *\n * const client = createClient({\n * server: 'https://api.pipsend.com',\n * login: 'your-username',\n * password: 'your-password',\n * timezone: 'America/New_York' // optional\n * });\n *\n * // The SDK handles authentication automatically\n * await client.orders.send({\n * symbol: 'EURUSD',\n * volume: 0.1\n * });\n * ```\n */\nexport function createClient(config: PipsendConfig): PipsendClient {\n return new PipsendClient(config);\n}\n\n// Export default for compatibility\nconst sdk = {\n createClient,\n PipsendClient\n};\n\nexport default sdk;\n","import type { WebSocketConfig } from './websocket';\n\n/**\n * Required configuration to initialize the Pipsend client\n */\nexport interface PipsendConfig {\n /** Pipsend server URL (required) */\n server: string;\n /** User credentials for SDK authentication (optional, for future use) */\n login?: string;\n /** User password for SDK authentication (optional, for future use) */\n password?: string;\n /** Timezone for operations (optional, default: UTC) */\n timezone?: string;\n /** Enable auto-refresh of tokens (default: true) */\n autoRefresh?: boolean;\n /** Safety margin for refresh in minutes (default: 5) */\n refreshMarginMinutes?: number;\n /** WebSocket configuration (optional) */\n websocket?: WebSocketConfig;\n}\n\n/**\n * Authentication token information\n */\nexport interface TokenInfo {\n token: string;\n refreshToken?: string;\n expiresAt: Date;\n issuedAt: Date;\n}\n\n/**\n * Trading order data\n */\nexport interface OrderData {\n symbol: string;\n volume: number;\n type?: 'buy' | 'sell';\n price?: number;\n stopLoss?: number;\n takeProfit?: number;\n}\n\n/**\n * Server authentication response from /api/v1/auth/login\n */\nexport interface AuthResponse {\n access_token: string;\n refresh_token: string;\n expires_in: number; // seconds (10800 = 180 minutes)\n token_type: string; // \"Bearer\"\n user: {\n login: number;\n email: string;\n first_name: string;\n last_name: string;\n balance: number;\n };\n logged_with: string; // \"master\" | \"investor\"\n}\n\n/**\n * Server refresh token response from /api/v1/auth/refresh\n */\nexport interface RefreshTokenResponse {\n access_token: string;\n expires_in: number;\n token_type: string;\n}\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\n/**\n * Custom SDK errors\n */\nexport class PipsendError extends Error {\n public errors?: ValidationError[];\n public response?: any;\n\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n errors?: ValidationError[],\n response?: any\n ) {\n super(message);\n this.name = 'PipsendError';\n this.errors = errors;\n this.response = response;\n }\n\n /**\n * Get formatted error message with validation details\n */\n getDetailedMessage(): string {\n if (!this.errors || this.errors.length === 0) {\n return this.message;\n }\n\n const errorDetails = this.errors\n .map(err => ` - ${err.field}: ${err.message}`)\n .join('\\n');\n\n return `${this.message}\\n${errorDetails}`;\n }\n\n /**\n * Check if this is a validation error\n */\n isValidationError(): boolean {\n return this.statusCode === 422 || this.code === 'VALIDATION_ERROR';\n }\n}\n\nexport class AuthenticationError extends PipsendError {\n constructor(message: string) {\n super(message, 'AUTH_ERROR', 401);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ConfigurationError extends PipsendError {\n constructor(message: string) {\n super(message, 'CONFIG_ERROR');\n this.name = 'ConfigurationError';\n }\n}\n\nexport class WebSocketError extends PipsendError {\n constructor(message: string) {\n super(message, 'WEBSOCKET_ERROR');\n this.name = 'WebSocketError';\n }\n}\n\n// Re-export WebSocket types\nexport type {\n WebSocketConfig,\n WebSocketMessage,\n WebSocketChannel,\n WebSocketOperation,\n PositionEventType,\n ConnectedMessage,\n SubscriptionSuccessMessage,\n UnsubscriptionSuccessMessage,\n ErrorMessage,\n PositionData,\n PositionEvent,\n BalanceEvent,\n SubscribeAction,\n UnsubscribeAction,\n WebSocketEventType,\n WebSocketCallback,\n // Legacy types (deprecated)\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate\n} from './websocket';\n\n// Re-export common types\nexport type {\n PaginationParams,\n PaginatedResponse\n} from './common';\n\n// Re-export all API types\nexport type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatus,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse,\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './api';\n","import type { PipsendConfig, TokenInfo, AuthResponse, RefreshTokenResponse } from '../types';\nimport { AuthenticationError } from '../types';\n\n/**\n * Authentication manager with auto-refresh tokens\n */\nexport class AuthManager {\n private tokenInfo?: TokenInfo;\n private refreshMarginMs: number;\n\n constructor(\n private config: PipsendConfig\n ) {\n const marginMinutes = config.refreshMarginMinutes ?? 5;\n this.refreshMarginMs = marginMinutes * 60 * 1000;\n }\n\n /**\n * Checks if a valid token is available\n */\n public isAuthenticated(): boolean {\n return !!this.tokenInfo && !this.isTokenExpired();\n }\n\n /**\n * Gets the current token (if it exists and is valid)\n */\n public getToken(): string | undefined {\n if (this.isAuthenticated()) {\n return this.tokenInfo?.token;\n }\n return undefined;\n }\n\n /**\n * Ensures a valid token exists, authenticating if necessary\n */\n public async ensureAuthenticated(): Promise<string> {\n if (!this.isAuthenticated()) {\n await this.authenticate();\n }\n return this.tokenInfo!.token;\n }\n\n /**\n * Performs authentication with the server\n */\n private async authenticate(): Promise<void> {\n if (!this.config.login || !this.config.password) {\n throw new AuthenticationError(\n 'Login and password are required for authentication. Please provide them in the config.'\n );\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n login: this.config.login,\n password: this.config.password\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as any;\n throw new AuthenticationError(\n errorData.message || `Authentication failed: ${response.status} ${response.statusText}`\n );\n }\n\n const data = await response.json() as AuthResponse;\n this.setTokenInfo(data);\n\n console.log('✅ Authentication successful');\n console.log(` User: ${data.user.first_name} ${data.user.last_name} (${data.user.email})`);\n console.log(` Login: ${data.user.login}`);\n console.log(` Balance: $${data.user.balance.toFixed(2)}`);\n console.log(` Logged with: ${data.logged_with}`);\n } catch (error) {\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `Authentication error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Refreshes the access token using the refresh token\n */\n public async refreshToken(): Promise<void> {\n if (!this.tokenInfo?.refreshToken) {\n console.log('⚠️ No refresh token available, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/refresh`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n refresh_token: this.tokenInfo.refreshToken\n })\n });\n\n if (!response.ok) {\n console.log('⚠️ Refresh token failed, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n const data = await response.json() as RefreshTokenResponse;\n \n // Update token info, keeping the same refresh token\n const now = new Date();\n const expiresAt = new Date(now.getTime() + data.expires_in * 1000);\n\n this.tokenInfo = {\n token: data.access_token,\n refreshToken: this.tokenInfo.refreshToken, // Keep the same refresh token\n issuedAt: now,\n expiresAt\n };\n\n console.log('✅ Token refreshed successfully');\n } catch (error) {\n console.error('❌ Error refreshing token:', error);\n this.tokenInfo = undefined;\n await this.authenticate();\n }\n }\n\n /**\n * Clears the current token\n */\n public clearToken(): void {\n this.tokenInfo = undefined;\n }\n\n /**\n * Checks if the token is expired or about to expire\n */\n private isTokenExpired(): boolean {\n if (!this.tokenInfo) return true;\n\n const now = Date.now();\n const expiryWithMargin = this.tokenInfo.expiresAt.getTime() - this.refreshMarginMs;\n\n return now >= expiryWithMargin;\n }\n\n /**\n * Stores the received token information\n */\n private setTokenInfo(response: AuthResponse): void {\n const now = new Date();\n const expiresAt = new Date(now.getTime() + response.expires_in * 1000);\n\n this.tokenInfo = {\n token: response.access_token,\n refreshToken: response.refresh_token,\n issuedAt: now,\n expiresAt\n };\n }\n}\n","import type { \n PipsendConfig, \n WebSocketMessage, \n WebSocketEventType,\n WebSocketCallback,\n WebSocketChannel,\n SubscribeAction,\n UnsubscribeAction,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport { WebSocketError } from '../types';\nimport { AuthManager } from './auth';\n\n/**\n * WebSocket manager for real-time updates\n * Handles connection, reconnection, subscriptions, and event dispatching\n */\nexport class WebSocketManager {\n private ws?: any; // WebSocket instance (browser or ws package)\n private reconnectAttempts = 0;\n private heartbeatTimer?: NodeJS.Timeout;\n private listeners = new Map<string, Set<WebSocketCallback>>();\n private isConnected = false;\n private subscribedChannels: WebSocketChannel[] = [];\n private isReconnecting = false;\n\n constructor(\n private config: PipsendConfig,\n private authManager: AuthManager\n ) {}\n\n /**\n * Connects to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.isConnected) {\n console.log('⚠️ WebSocket already connected');\n return;\n }\n\n if (this.isReconnecting) {\n console.log('⚠️ WebSocket reconnection in progress');\n return;\n }\n\n // Get token first\n const token = await this.authManager.ensureAuthenticated();\n \n // Build WebSocket URL with token as query parameter\n const baseWsUrl = this.buildWebSocketUrl();\n const wsUrl = `${baseWsUrl}${baseWsUrl.includes('?') ? '&' : '?'}token=${encodeURIComponent(token)}`;\n\n return new Promise((resolve, reject) => {\n try {\n const WS = this.getWebSocketConstructor();\n this.ws = new WS(wsUrl);\n\n this.ws.onopen = () => {\n console.log('✅ WebSocket connected');\n this.isConnected = true;\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n\n // Emit connected event\n this.emit('connected', { timestamp: Date.now() });\n\n // Resubscribe to channels if reconnecting\n if (this.subscribedChannels.length > 0) {\n console.log('🔄 Resubscribing to channels:', this.subscribedChannels);\n this.subscribe(this.subscribedChannels);\n }\n\n // Start heartbeat\n this.startHeartbeat();\n\n resolve();\n };\n\n this.ws.onmessage = (event: any) => {\n try {\n const data = JSON.parse(event.data);\n this.handleMessage(data);\n } catch (error) {\n console.error('❌ Failed to parse WebSocket message:', error);\n }\n };\n\n this.ws.onerror = (error: any) => {\n console.error('❌ WebSocket error:', error);\n this.emit('error', error);\n \n if (!this.isConnected) {\n reject(new WebSocketError('Failed to connect to WebSocket server'));\n }\n };\n\n this.ws.onclose = (event: any) => {\n console.log('WebSocket disconnected', event.code, event.reason);\n this.isConnected = false;\n this.stopHeartbeat();\n this.emit('disconnected', { \n code: event.code, \n reason: event.reason,\n timestamp: Date.now()\n });\n this.handleReconnect();\n };\n\n } catch (error) {\n reject(new WebSocketError(\n `Failed to create WebSocket: ${error instanceof Error ? error.message : 'Unknown error'}`\n ));\n }\n });\n }\n\n /**\n * Subscribes to WebSocket channels\n */\n subscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n throw new WebSocketError('WebSocket not connected. Call connect() first.');\n }\n\n // Add to subscribed channels (avoid duplicates)\n this.subscribedChannels = [...new Set([...this.subscribedChannels, ...channels])];\n\n // Send subscription message with correct format\n const message: SubscribeAction = {\n action: 'subscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Subscribed to channels:', channels);\n }\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n console.warn('WebSocket not connected, cannot unsubscribe');\n return;\n }\n\n // Remove from subscribed channels\n this.subscribedChannels = this.subscribedChannels.filter(\n ch => !channels.includes(ch)\n );\n\n // Send unsubscription message with correct format\n const message: UnsubscribeAction = {\n action: 'unsubscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Unsubscribed from channels:', channels);\n }\n\n /**\n * Registers an event listener\n */\n on(event: WebSocketEventType, callback: WebSocketCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback);\n }\n\n /**\n * Removes an event listener\n */\n off(event: WebSocketEventType, callback?: WebSocketCallback): void {\n if (!callback) {\n // Remove all listeners for this event\n this.listeners.delete(event);\n } else {\n // Remove specific listener\n this.listeners.get(event)?.delete(callback);\n }\n }\n\n /**\n * Disconnects from WebSocket\n */\n disconnect(): void {\n console.log('👋 Disconnecting WebSocket...');\n this.stopHeartbeat();\n \n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n \n this.isConnected = false;\n this.isReconnecting = false;\n this.subscribedChannels = [];\n this.listeners.clear();\n }\n\n /**\n * Checks if WebSocket is connected\n */\n isWebSocketConnected(): boolean {\n return this.isConnected;\n }\n\n /**\n * Gets list of subscribed channels\n */\n getSubscribedChannels(): WebSocketChannel[] {\n return [...this.subscribedChannels];\n }\n\n // Private methods\n\n /**\n * Builds WebSocket URL from HTTP(S) server URL\n */\n private buildWebSocketUrl(): string {\n try {\n const url = new URL(this.config.server);\n \n // Convert https:// to wss:// or http:// to ws://\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n \n // Add WebSocket path (default to /api/v1/ws for Pipsend API)\n const wsPath = this.config.websocket?.path || '/api/v1/ws';\n url.pathname = wsPath;\n \n return url.toString();\n } catch (error) {\n throw new WebSocketError('Invalid server URL for WebSocket connection');\n }\n }\n\n /**\n * Gets WebSocket constructor (browser or Node.js)\n */\n private getWebSocketConstructor(): any {\n // Browser environment\n if (typeof WebSocket !== 'undefined') {\n return WebSocket;\n }\n \n // Node.js environment - try to load 'ws' package\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require('ws');\n } catch {\n throw new WebSocketError(\n 'WebSocket not available. Install \"ws\" package for Node.js: npm install ws'\n );\n }\n }\n\n /**\n * Sends an action message through WebSocket\n */\n private sendAction(message: SubscribeAction | UnsubscribeAction): void {\n if (!this.ws || !this.isConnected) {\n console.warn('⚠️ WebSocket not ready, message not sent:', message.action);\n return;\n }\n\n try {\n const payload = JSON.stringify(message);\n this.ws.send(payload);\n } catch (error) {\n console.error('❌ Failed to send WebSocket message:', error);\n }\n }\n\n /**\n * Sends a ping message (for heartbeat)\n */\n private sendPing(): void {\n if (!this.ws || !this.isConnected) {\n return;\n }\n\n try {\n this.ws.send(JSON.stringify({ action: 'ping' }));\n } catch (error) {\n console.error('❌ Failed to send ping:', error);\n }\n }\n\n /**\n * Handles incoming WebSocket messages\n */\n private handleMessage(message: WebSocketMessage): void {\n switch (message.op) {\n case 'connected':\n this.handleConnected(message);\n break;\n \n case 'subscription_success':\n this.handleSubscriptionSuccess(message);\n break;\n \n case 'unsubscription_success':\n this.handleUnsubscriptionSuccess(message);\n break;\n \n case 'push':\n this.handlePushEvent(message);\n break;\n \n case 'error':\n this.handleError(message);\n break;\n \n default:\n console.warn(message.op);\n }\n\n // Emit to wildcard listeners (listen to all events)\n this.emit('*', message);\n }\n\n /**\n * Handles connected message from server\n */\n private handleConnected(message: WebSocketMessage): void {\n console.log('✅ WebSocket connected:', message.data.message);\n console.log(' Available channels:', message.data.available_channels);\n this.emit('connected', message.data);\n }\n\n /**\n * Handles subscription success\n */\n private handleSubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Subscription successful:', message.data.subscribed);\n this.emit('subscription_success', message.data);\n }\n\n /**\n * Handles unsubscription success\n */\n private handleUnsubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Unsubscription successful:', message.data.unsubscribed);\n this.emit('unsubscription_success', message.data);\n }\n\n /**\n * Handles push events (actual data events)\n */\n private handlePushEvent(message: WebSocketMessage): void {\n const eventData = message.data;\n const eventType = eventData.type;\n \n switch (eventType) {\n case 'position.opened':\n this.emit('position:opened', eventData as PositionEvent);\n break;\n \n case 'position.closed':\n case 'position.partially_closed':\n this.emit('position:closed', eventData as PositionEvent);\n break;\n \n case 'position.updated':\n this.emit('position:updated', eventData as PositionEvent);\n break;\n \n default:\n // Balance update (doesn't have 'type' field)\n if (message.topic?.startsWith('balance:')) {\n this.emit('balance:updated', eventData as BalanceEvent);\n } else {\n console.warn('Unknown event type:', eventType);\n }\n }\n }\n\n /**\n * Handles error messages from server\n */\n private handleError(message: WebSocketMessage): void {\n console.error('❌ WebSocket error:', message.data.message);\n if (message.data.error) {\n console.error(' Error details:', message.data.error);\n }\n this.emit('error', message.data);\n }\n\n /**\n * Emits an event to all registered listeners\n */\n private emit(event: WebSocketEventType, data: any): void {\n const listeners = this.listeners.get(event);\n if (listeners && listeners.size > 0) {\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`❌ Error in WebSocket listener for \"${event}\":`, error);\n }\n });\n }\n }\n\n /**\n * Handles reconnection logic with exponential backoff\n */\n private handleReconnect(): void {\n const autoReconnect = this.config.websocket?.autoReconnect ?? true;\n const maxAttempts = this.config.websocket?.maxReconnectAttempts ?? 5;\n\n if (!autoReconnect) {\n console.log('Auto-reconnect disabled');\n return;\n }\n\n if (this.reconnectAttempts >= maxAttempts) {\n console.log(`❌ Max reconnection attempts (${maxAttempts}) reached. Giving up.`);\n this.emit('error', new WebSocketError('Max reconnection attempts reached'));\n return;\n }\n\n // Exponential backoff: 1s, 2s, 4s, 8s, 16s, max 30s\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n console.log(\n `🔄 Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts + 1}/${maxAttempts})...`\n );\n\n this.isReconnecting = true;\n\n setTimeout(() => {\n this.reconnectAttempts++;\n this.connect().catch(error => {\n console.error('❌ Reconnection failed:', error);\n });\n }, delay);\n }\n\n /**\n * Starts heartbeat to keep connection alive\n */\n private startHeartbeat(): void {\n const interval = this.config.websocket?.heartbeatInterval || 30000;\n \n this.heartbeatTimer = setInterval(() => {\n if (this.isConnected) {\n this.sendPing();\n }\n }, interval);\n }\n\n /**\n * Stops heartbeat timer\n */\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = undefined;\n }\n }\n}\n","import { PipsendError } from '../types';\nimport type { AuthManager } from '../core/auth';\n\n/**\n * HTTP client for making requests to the Pipsend API\n */\nexport class HttpClient {\n constructor(\n private baseUrl: string,\n private authManager?: AuthManager\n ) {}\n\n /**\n * Makes an HTTP request\n */\n async request<T>(\n endpoint: string,\n options: RequestInit = {},\n retryOn401 = true\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n try {\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {})\n };\n\n // Add Authorization header if authManager is available\n if (this.authManager) {\n const token = await this.authManager.ensureAuthenticated();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, {\n ...options,\n headers\n });\n\n // Handle 401 Unauthorized - try to refresh token and retry\n if (response.status === 401 && this.authManager && retryOn401) {\n console.log('⚠️ Received 401, attempting to refresh token...');\n await this.authManager.refreshToken();\n \n // Retry the request with new token (but don't retry again if it fails)\n return this.request<T>(endpoint, options, false);\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = `HTTP ${response.status}: ${errorText || response.statusText}`;\n let errorCode = 'HTTP_ERROR';\n let validationErrors;\n let errorResponse;\n \n // Try to parse error as JSON for better error messages\n try {\n const errorJson = JSON.parse(errorText);\n errorResponse = errorJson;\n \n // Extract message\n if (errorJson.message) {\n errorMessage = errorJson.message;\n }\n \n // Extract error code\n if (errorJson.status_code) {\n errorCode = errorJson.status_code;\n }\n \n // Extract validation errors (422 responses)\n if (errorJson.errors && Array.isArray(errorJson.errors)) {\n validationErrors = errorJson.errors;\n }\n } catch {\n // Keep the original error message if JSON parsing fails\n }\n\n throw new PipsendError(\n errorMessage,\n errorCode,\n response.status,\n validationErrors,\n errorResponse\n );\n }\n\n // Handle empty responses\n const text = await response.text();\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n } catch (error) {\n if (error instanceof PipsendError) {\n throw error;\n }\n throw new PipsendError(\n `Request failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n );\n }\n }\n\n /**\n * GET request\n */\n async get<T>(endpoint: string, params?: Record<string, any>): Promise<T> {\n const queryString = params ? this.buildQueryString(params) : '';\n const url = queryString ? `${endpoint}?${queryString}` : endpoint;\n return this.request<T>(url, { method: 'GET' });\n }\n\n /**\n * POST request\n */\n async post<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * PUT request\n */\n async put<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * Builds query string from params object\n */\n private buildQueryString(params: Record<string, any>): string {\n const filtered = Object.entries(params)\n .filter(([_, value]) => value !== undefined && value !== null && value !== '')\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n \n return filtered.join('&');\n }\n}\n","import type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse\n} from '../types/api/accounts';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Accounts API\n */\nexport class AccountsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a new trading account\n */\n async create(request: CreateAccountRequest): Promise<CreateAccountResponse> {\n return this.http.post<CreateAccountResponse>('/api/v1/accounts', request);\n }\n\n /**\n * List all accounts with optional filters and pagination\n */\n async list(params?: AccountsListParams): Promise<PaginatedResponse<Account> | Account[]> {\n return this.http.get<PaginatedResponse<Account> | Account[]>('/api/v1/accounts', params);\n }\n\n /**\n * Get all account logins\n */\n async getLogins(): Promise<number[]> {\n return this.http.get<number[]>('/api/v1/accounts/logins');\n }\n\n /**\n * Get account status/metrics (balance, equity, credit, margin)\n */\n async getStatus(login: number): Promise<AccountStatusResponse> {\n return this.http.get<AccountStatusResponse>(`/api/v1/accounts/${login}/status`);\n }\n\n /**\n * Get account statistics with optional filters\n */\n async getStatistics(params?: AccountStatisticsParams): Promise<AccountStatistics> {\n return this.http.get<AccountStatistics>('/api/v1/accounts/statistics', params);\n }\n\n /**\n * Change master password for an account\n */\n async changeMasterPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/master`, request);\n }\n\n /**\n * Change investor password for an account\n */\n async changeInvestorPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/investor`, request);\n }\n\n /**\n * Archive an account\n */\n async archive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/archive`);\n }\n\n /**\n * Unarchive an account\n */\n async unarchive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/unarchive`);\n }\n\n /**\n * Update account information (partial update)\n * All fields are optional, only send the ones you want to update\n */\n async update(login: number, request: UpdateAccountRequest): Promise<UpdateAccountResponse> {\n return this.http.put<UpdateAccountResponse>(`/api/v1/accounts/${login}`, request);\n }\n\n /**\n * Adjust balance or credit for an account\n * The adjustment is relative: amount is added or subtracted from current value\n */\n async balance(login: number, request: AdjustBalanceRequest): Promise<AdjustBalanceResponse> {\n return this.http.put<AdjustBalanceResponse>(`/api/v1/accounts/${login}/adjust`, request);\n }\n}\n","import type {\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics\n} from '../types/api/trading-groups';\nimport { HttpClient } from './http-client';\n\n/**\n * Trading Groups API\n */\nexport class TradingGroupsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List all trading groups with optional filters\n */\n async list(params?: TradingGroupsListParams): Promise<TradingGroup[]> {\n return this.http.get<TradingGroup[]>('/api/v1/trading-groups', params);\n }\n\n /**\n * Get trading group by name\n */\n async getByName(name: string): Promise<TradingGroup> {\n return this.http.get<TradingGroup>(`/api/v1/trading-groups/${encodeURIComponent(name)}`);\n }\n\n /**\n * Get all trading group names\n */\n async getNames(): Promise<string[]> {\n return this.http.get<string[]>('/api/v1/trading-groups/names');\n }\n\n /**\n * Get trading group statistics\n */\n async getStatistics(type?: string): Promise<TradingGroupStatistics> {\n return this.http.get<TradingGroupStatistics>('/api/v1/trading-groups/statistics', type ? { type } : undefined);\n }\n}\n","import type {\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams\n} from '../types/api/market-data';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Market Data API\n * \n * Note: All data has a minimum age of 1 hour (no real-time data)\n */\nexport class MarketDataAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Get historical OHLCV candles\n * \n * @param params - Candles parameters (symbol and timeframe are required)\n * @returns Paginated candles or array of candles\n * \n * @example\n * ```ts\n * // Get last 100 candles\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD',\n * timeframe: '1m',\n * limit: 100,\n * order: 'desc'\n * });\n * \n * // Get candles with time range\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD,ETHUSD',\n * timeframe: '1h',\n * from: '2025-11-01T00:00:00Z',\n * to: '2025-11-02T00:00:00Z'\n * });\n * ```\n */\n async getCandles(params: CandlesParams): Promise<PaginatedResponse<Candle> | Candle[]> {\n return this.http.get<PaginatedResponse<Candle> | Candle[]>('/api/v1/candles', params);\n }\n\n /**\n * Get available symbols with metadata\n * \n * @param params - Optional filters for symbols\n * @returns Paginated symbols or array of symbols\n * \n * @example\n * ```ts\n * // Get all symbols\n * const symbols = await client.marketData.getSymbols();\n * \n * // Filter by group\n * const cryptoSymbols = await client.marketData.getSymbols({\n * group: 'CRYPTO_MAJOR',\n * has_data: true\n * });\n * ```\n */\n async getSymbols(params?: SymbolsParams): Promise<PaginatedResponse<Symbol> | Symbol[]> {\n return this.http.get<PaginatedResponse<Symbol> | Symbol[]>('/api/v1/symbols', params);\n }\n\n /**\n * Get symbol groups hierarchy\n * \n * Note: This endpoint never uses pagination\n * \n * @param params - Optional filters for groups\n * @returns Array of groups\n * \n * @example\n * ```ts\n * // Get all groups\n * const groups = await client.marketData.getGroups();\n * \n * // Get only root groups\n * const rootGroups = await client.marketData.getGroups({\n * root_only: true\n * });\n * ```\n */\n async getGroups(params?: GroupsParams): Promise<Group[]> {\n return this.http.get<Group[]>('/api/v1/groups', params);\n }\n}\n","import type {\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse\n} from '../types/api/positions';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Positions API\n */\nexport class PositionsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List positions with optional filters and pagination\n */\n async list(params?: PositionsListParams): Promise<PaginatedResponse<Position> | Position[]> {\n return this.http.get<PaginatedResponse<Position> | Position[]>('/api/v1/positions', params);\n }\n\n /**\n * Get position statistics with optional filters and grouping\n */\n async getStats(params?: PositionStatsParams): Promise<PositionStatistics | PositionStatisticsGrouped[]> {\n return this.http.get<PositionStatistics | PositionStatisticsGrouped[]>('/api/v1/positions/stats', params);\n }\n\n /**\n * Get position totals with dynamic grouping\n */\n async getTotals(params: PositionTotalsParams): Promise<PositionTotals[]> {\n return this.http.get<PositionTotals[]>('/api/v1/positions/totals', params);\n }\n\n /**\n * Update position (modify SL/TP)\n */\n async update(id: number, request: UpdatePositionRequest): Promise<UpdatePositionResponse> {\n return this.http.put<UpdatePositionResponse>(`/api/v1/positions/${id}`, request);\n }\n\n /**\n * Delete (close) position\n */\n async delete(id: number, params: DeletePositionParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/positions/${id}?login=${params.login}`);\n }\n\n /**\n * Check and recalculate positions\n */\n async check(request: CheckPositionsRequest): Promise<CheckPositionsResponse> {\n return this.http.post<CheckPositionsResponse>('/api/v1/positions/check', request);\n }\n}\n","import type {\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse\n} from '../types/api/orders';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Orders API\n */\nexport class OrdersAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List orders with optional filters and pagination\n */\n async list(params?: OrdersListParams): Promise<PaginatedResponse<Order> | Order[]> {\n return this.http.get<PaginatedResponse<Order> | Order[]>('/api/v1/orders', params);\n }\n\n /**\n * Get order statistics with optional filters and grouping\n */\n async getStats(params?: OrderStatsParams): Promise<OrderStatistics | OrderStatisticsGrouped[]> {\n return this.http.get<OrderStatistics | OrderStatisticsGrouped[]>('/api/v1/orders/stats', params);\n }\n\n /**\n * Get order totals with dynamic grouping\n */\n async getTotals(params: OrderTotalsParams): Promise<OrderTotals[]> {\n return this.http.get<OrderTotals[]>('/api/v1/orders/totals', params);\n }\n\n /**\n * Update order (modify SL/TP)\n */\n async update(id: number, request: UpdateOrderRequest): Promise<UpdateOrderResponse> {\n return this.http.put<UpdateOrderResponse>(`/api/v1/orders/${id}`, request);\n }\n\n /**\n * Delete (cancel) order\n */\n async delete(id: number, params: DeleteOrderParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/orders/${id}?login=${params.login}`);\n }\n\n /**\n * Check and validate pending orders\n */\n async check(request: CheckOrdersRequest): Promise<CheckOrdersResponse> {\n return this.http.post<CheckOrdersResponse>('/api/v1/orders/check', request);\n }\n}\n","import type {\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse\n} from '../types/api/trades';\nimport { HttpClient } from './http-client';\n\n/**\n * Trades API\n */\nexport class TradesAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Open a new trade (market or pending order)\n */\n async open(request: OpenTradeRequest): Promise<OpenTradeResponse> {\n return this.http.post<OpenTradeResponse>('/api/v1/trades/open', request);\n }\n\n /**\n * Close a trade (full or partial)\n */\n async close(request: CloseTradeRequest): Promise<CloseTradeResponse> {\n return this.http.post<CloseTradeResponse>('/api/v1/trades/close', request);\n }\n\n /**\n * Modify trade Stop Loss and/or Take Profit\n */\n async modify(request: ModifyTradeRequest): Promise<ModifyTradeResponse> {\n return this.http.put<ModifyTradeResponse>('/api/v1/trades/modify', request);\n }\n\n /**\n * Check if there's sufficient margin for a trade\n */\n async checkMargin(request: CheckMarginRequest): Promise<CheckMarginResponse> {\n return this.http.post<CheckMarginResponse>('/api/v1/trades/check-margin', request);\n }\n\n /**\n * Calculate potential profit for a trade\n */\n async calculateProfit(request: CalculateProfitRequest): Promise<CalculateProfitResponse> {\n return this.http.post<CalculateProfitResponse>('/api/v1/trades/calc-profit', request);\n }\n}\n","import type { \n PipsendConfig,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketCallback,\n WebSocketChannel,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport type { HealthCheckResponse } from '../types/api/health';\nimport { ConfigurationError, WebSocketError } from '../types';\nimport { AuthManager } from './auth';\nimport { WebSocketManager } from './websocket';\nimport { \n HttpClient,\n AccountsAPI,\n TradingGroupsAPI,\n MarketDataAPI,\n PositionsAPI,\n OrdersAPI,\n TradesAPI\n} from '../api';\n\n/**\n * Main Pipsend SDK client\n */\nexport class PipsendClient {\n private authManager: AuthManager;\n private wsManager?: WebSocketManager;\n private config: PipsendConfig;\n private http: HttpClient;\n\n // API modules\n public readonly accounts: AccountsAPI;\n public readonly tradingGroups: TradingGroupsAPI;\n public readonly marketData: MarketDataAPI;\n public readonly positions: PositionsAPI;\n public readonly orders: OrdersAPI;\n public readonly trades: TradesAPI;\n\n constructor(config: PipsendConfig) {\n this.validateConfig(config);\n this.config = {\n ...config,\n autoRefresh: config.autoRefresh ?? true,\n refreshMarginMinutes: config.refreshMarginMinutes ?? 5,\n timezone: config.timezone ?? 'UTC'\n };\n this.authManager = new AuthManager(this.config);\n\n // Initialize HTTP client with auth manager\n this.http = new HttpClient(this.config.server, this.authManager);\n\n // Initialize API modules\n this.accounts = new AccountsAPI(this.http);\n this.tradingGroups = new TradingGroupsAPI(this.http);\n this.marketData = new MarketDataAPI(this.http);\n this.positions = new PositionsAPI(this.http);\n this.orders = new OrdersAPI(this.http);\n this.trades = new TradesAPI(this.http);\n\n // Initialize WebSocket if enabled\n if (config.websocket?.enabled) {\n this.wsManager = new WebSocketManager(this.config, this.authManager);\n \n // Auto-connect if configured\n if (config.websocket.autoConnect) {\n this.wsManager.connect().catch(error => {\n console.error('Failed to auto-connect WebSocket:', error);\n });\n }\n }\n }\n\n /**\n * Validates the initial configuration\n */\n private validateConfig(config: PipsendConfig): void {\n if (!config.server) {\n throw new ConfigurationError('The \"server\" parameter is required');\n }\n\n // Validate URL format\n try {\n new URL(config.server);\n } catch {\n throw new ConfigurationError('The \"server\" parameter must be a valid URL');\n }\n\n // Note: login and password are optional for now (will be required when auth is implemented)\n }\n\n /**\n * Authentication API\n * TODO: Implement when authentication is available\n */\n public auth = {\n /**\n * Forces a token refresh\n */\n refresh: async (): Promise<void> => {\n await this.authManager.refreshToken();\n },\n\n /**\n * Checks if the client is authenticated\n */\n isAuthenticated: (): boolean => {\n return this.authManager.isAuthenticated();\n },\n\n /**\n * Gets the current token (if it exists)\n */\n getToken: (): string | undefined => {\n return this.authManager.getToken();\n },\n\n /**\n * Logs out by clearing the token\n */\n logout: (): void => {\n this.authManager.clearToken();\n }\n };\n\n /**\n * WebSocket streaming API\n * Provides real-time updates for prices, orders, positions, etc.\n */\n public stream = {\n /**\n * Connects to WebSocket server\n */\n connect: async (): Promise<void> => {\n if (!this.wsManager) {\n throw new WebSocketError(\n 'WebSocket not enabled. Set websocket.enabled: true in config'\n );\n }\n await this.wsManager.connect();\n },\n\n /**\n * Disconnects from WebSocket server\n */\n disconnect: (): void => {\n this.wsManager?.disconnect();\n },\n\n /**\n * Checks if WebSocket is connected\n */\n isConnected: (): boolean => {\n return this.wsManager?.isWebSocketConnected() ?? false;\n },\n\n /**\n * Subscribes to WebSocket channels\n * @example\n * client.stream.subscribe(['positions:new', 'positions:closed']);\n */\n subscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.subscribe(channels);\n },\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.unsubscribe(channels);\n },\n\n /**\n * Gets list of subscribed channels\n */\n getSubscriptions: (): WebSocketChannel[] => {\n return this.wsManager?.getSubscribedChannels() ?? [];\n },\n\n /**\n * Listens to position opened events\n */\n onPositionOpened: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:opened', callback);\n },\n\n /**\n * Listens to position closed events (includes partial closes)\n */\n onPositionClosed: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:closed', callback);\n },\n\n /**\n * Listens to position updated events (throttled to max 1 per 2 seconds)\n */\n onPositionUpdated: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback);\n },\n\n /**\n * Listens to balance updated events\n */\n onBalanceUpdated: (callback: WebSocketCallback<BalanceEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback);\n },\n\n // Legacy methods (deprecated but kept for compatibility)\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPriceUpdate: (callback: WebSocketCallback<PriceUpdate>): void => {\n console.warn('⚠️ onPriceUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new event for backward compatibility\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onPositionOpened/onPositionClosed instead\n */\n onOrderUpdate: (callback: WebSocketCallback<OrderUpdate>): void => {\n console.warn('⚠️ onOrderUpdate is deprecated. Use onPositionOpened/onPositionClosed instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new events for backward compatibility\n this.wsManager.on('position:opened', callback as any);\n },\n\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPositionUpdate: (callback: WebSocketCallback<PositionUpdate>): void => {\n console.warn('⚠️ onPositionUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onBalanceUpdated instead\n */\n onBalanceUpdate: (callback: WebSocketCallback<BalanceUpdate>): void => {\n console.warn('⚠️ onBalanceUpdate is deprecated. Use onBalanceUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback as any);\n },\n\n /**\n * Listens to connection events\n */\n onConnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('connected', callback);\n },\n\n /**\n * Listens to disconnection events\n */\n onDisconnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('disconnected', callback);\n },\n\n /**\n * Listens to error events\n */\n onError: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('error', callback);\n },\n\n /**\n * Removes event listener\n */\n off: (event: string, callback?: WebSocketCallback): void => {\n this.wsManager?.off(event as any, callback);\n }\n };\n\n /**\n * Health check\n */\n async ping(): Promise<HealthCheckResponse> {\n return this.http.get<HealthCheckResponse>('/ping');\n }\n\n /**\n * Client information\n */\n public getConfig(): Readonly<PipsendConfig> {\n return { ...this.config };\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -403,7 +403,7 @@ var WebSocketManager = class {
|
|
|
403
403
|
return;
|
|
404
404
|
}
|
|
405
405
|
try {
|
|
406
|
-
this.ws.send(JSON.stringify({
|
|
406
|
+
this.ws.send(JSON.stringify({ action: "ping" }));
|
|
407
407
|
} catch (error) {
|
|
408
408
|
console.error("\u274C Failed to send ping:", error);
|
|
409
409
|
}
|
|
@@ -429,7 +429,7 @@ var WebSocketManager = class {
|
|
|
429
429
|
this.handleError(message);
|
|
430
430
|
break;
|
|
431
431
|
default:
|
|
432
|
-
console.warn(
|
|
432
|
+
console.warn(message.op);
|
|
433
433
|
}
|
|
434
434
|
this.emit("*", message);
|
|
435
435
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/index.ts","../src/core/auth.ts","../src/core/websocket.ts","../src/api/http-client.ts","../src/api/accounts.ts","../src/api/trading-groups.ts","../src/api/market-data.ts","../src/api/positions.ts","../src/api/orders.ts","../src/api/trades.ts","../src/core/client.ts","../src/index.ts"],"sourcesContent":["import type { WebSocketConfig } from './websocket';\n\n/**\n * Required configuration to initialize the Pipsend client\n */\nexport interface PipsendConfig {\n /** Pipsend server URL (required) */\n server: string;\n /** User credentials for SDK authentication (optional, for future use) */\n login?: string;\n /** User password for SDK authentication (optional, for future use) */\n password?: string;\n /** Timezone for operations (optional, default: UTC) */\n timezone?: string;\n /** Enable auto-refresh of tokens (default: true) */\n autoRefresh?: boolean;\n /** Safety margin for refresh in minutes (default: 5) */\n refreshMarginMinutes?: number;\n /** WebSocket configuration (optional) */\n websocket?: WebSocketConfig;\n}\n\n/**\n * Authentication token information\n */\nexport interface TokenInfo {\n token: string;\n refreshToken?: string;\n expiresAt: Date;\n issuedAt: Date;\n}\n\n/**\n * Trading order data\n */\nexport interface OrderData {\n symbol: string;\n volume: number;\n type?: 'buy' | 'sell';\n price?: number;\n stopLoss?: number;\n takeProfit?: number;\n}\n\n/**\n * Server authentication response from /api/v1/auth/login\n */\nexport interface AuthResponse {\n access_token: string;\n refresh_token: string;\n expires_in: number; // seconds (10800 = 180 minutes)\n token_type: string; // \"Bearer\"\n user: {\n login: number;\n email: string;\n first_name: string;\n last_name: string;\n balance: number;\n };\n logged_with: string; // \"master\" | \"investor\"\n}\n\n/**\n * Server refresh token response from /api/v1/auth/refresh\n */\nexport interface RefreshTokenResponse {\n access_token: string;\n expires_in: number;\n token_type: string;\n}\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\n/**\n * Custom SDK errors\n */\nexport class PipsendError extends Error {\n public errors?: ValidationError[];\n public response?: any;\n\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n errors?: ValidationError[],\n response?: any\n ) {\n super(message);\n this.name = 'PipsendError';\n this.errors = errors;\n this.response = response;\n }\n\n /**\n * Get formatted error message with validation details\n */\n getDetailedMessage(): string {\n if (!this.errors || this.errors.length === 0) {\n return this.message;\n }\n\n const errorDetails = this.errors\n .map(err => ` - ${err.field}: ${err.message}`)\n .join('\\n');\n\n return `${this.message}\\n${errorDetails}`;\n }\n\n /**\n * Check if this is a validation error\n */\n isValidationError(): boolean {\n return this.statusCode === 422 || this.code === 'VALIDATION_ERROR';\n }\n}\n\nexport class AuthenticationError extends PipsendError {\n constructor(message: string) {\n super(message, 'AUTH_ERROR', 401);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ConfigurationError extends PipsendError {\n constructor(message: string) {\n super(message, 'CONFIG_ERROR');\n this.name = 'ConfigurationError';\n }\n}\n\nexport class WebSocketError extends PipsendError {\n constructor(message: string) {\n super(message, 'WEBSOCKET_ERROR');\n this.name = 'WebSocketError';\n }\n}\n\n// Re-export WebSocket types\nexport type {\n WebSocketConfig,\n WebSocketMessage,\n WebSocketChannel,\n WebSocketOperation,\n PositionEventType,\n ConnectedMessage,\n SubscriptionSuccessMessage,\n UnsubscriptionSuccessMessage,\n ErrorMessage,\n PositionData,\n PositionEvent,\n BalanceEvent,\n SubscribeAction,\n UnsubscribeAction,\n WebSocketEventType,\n WebSocketCallback,\n // Legacy types (deprecated)\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate\n} from './websocket';\n\n// Re-export common types\nexport type {\n PaginationParams,\n PaginatedResponse\n} from './common';\n\n// Re-export all API types\nexport type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatus,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse,\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './api';\n","import type { PipsendConfig, TokenInfo, AuthResponse, RefreshTokenResponse } from '../types';\nimport { AuthenticationError } from '../types';\n\n/**\n * Authentication manager with auto-refresh tokens\n */\nexport class AuthManager {\n private tokenInfo?: TokenInfo;\n private refreshMarginMs: number;\n\n constructor(\n private config: PipsendConfig\n ) {\n const marginMinutes = config.refreshMarginMinutes ?? 5;\n this.refreshMarginMs = marginMinutes * 60 * 1000;\n }\n\n /**\n * Checks if a valid token is available\n */\n public isAuthenticated(): boolean {\n return !!this.tokenInfo && !this.isTokenExpired();\n }\n\n /**\n * Gets the current token (if it exists and is valid)\n */\n public getToken(): string | undefined {\n if (this.isAuthenticated()) {\n return this.tokenInfo?.token;\n }\n return undefined;\n }\n\n /**\n * Ensures a valid token exists, authenticating if necessary\n */\n public async ensureAuthenticated(): Promise<string> {\n if (!this.isAuthenticated()) {\n await this.authenticate();\n }\n return this.tokenInfo!.token;\n }\n\n /**\n * Performs authentication with the server\n */\n private async authenticate(): Promise<void> {\n if (!this.config.login || !this.config.password) {\n throw new AuthenticationError(\n 'Login and password are required for authentication. Please provide them in the config.'\n );\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n login: this.config.login,\n password: this.config.password\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as any;\n throw new AuthenticationError(\n errorData.message || `Authentication failed: ${response.status} ${response.statusText}`\n );\n }\n\n const data = await response.json() as AuthResponse;\n this.setTokenInfo(data);\n\n console.log('✅ Authentication successful');\n console.log(` User: ${data.user.first_name} ${data.user.last_name} (${data.user.email})`);\n console.log(` Login: ${data.user.login}`);\n console.log(` Balance: $${data.user.balance.toFixed(2)}`);\n console.log(` Logged with: ${data.logged_with}`);\n } catch (error) {\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `Authentication error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Refreshes the access token using the refresh token\n */\n public async refreshToken(): Promise<void> {\n if (!this.tokenInfo?.refreshToken) {\n console.log('⚠️ No refresh token available, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/refresh`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n refresh_token: this.tokenInfo.refreshToken\n })\n });\n\n if (!response.ok) {\n console.log('⚠️ Refresh token failed, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n const data = await response.json() as RefreshTokenResponse;\n \n // Update token info, keeping the same refresh token\n const now = new Date();\n const expiresAt = new Date(now.getTime() + data.expires_in * 1000);\n\n this.tokenInfo = {\n token: data.access_token,\n refreshToken: this.tokenInfo.refreshToken, // Keep the same refresh token\n issuedAt: now,\n expiresAt\n };\n\n console.log('✅ Token refreshed successfully');\n } catch (error) {\n console.error('❌ Error refreshing token:', error);\n this.tokenInfo = undefined;\n await this.authenticate();\n }\n }\n\n /**\n * Clears the current token\n */\n public clearToken(): void {\n this.tokenInfo = undefined;\n }\n\n /**\n * Checks if the token is expired or about to expire\n */\n private isTokenExpired(): boolean {\n if (!this.tokenInfo) return true;\n\n const now = Date.now();\n const expiryWithMargin = this.tokenInfo.expiresAt.getTime() - this.refreshMarginMs;\n\n return now >= expiryWithMargin;\n }\n\n /**\n * Stores the received token information\n */\n private setTokenInfo(response: AuthResponse): void {\n const now = new Date();\n const expiresAt = new Date(now.getTime() + response.expires_in * 1000);\n\n this.tokenInfo = {\n token: response.access_token,\n refreshToken: response.refresh_token,\n issuedAt: now,\n expiresAt\n };\n }\n}\n","import type { \n PipsendConfig, \n WebSocketMessage, \n WebSocketEventType,\n WebSocketCallback,\n WebSocketChannel,\n SubscribeAction,\n UnsubscribeAction,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport { WebSocketError } from '../types';\nimport { AuthManager } from './auth';\n\n/**\n * WebSocket manager for real-time updates\n * Handles connection, reconnection, subscriptions, and event dispatching\n */\nexport class WebSocketManager {\n private ws?: any; // WebSocket instance (browser or ws package)\n private reconnectAttempts = 0;\n private heartbeatTimer?: NodeJS.Timeout;\n private listeners = new Map<string, Set<WebSocketCallback>>();\n private isConnected = false;\n private subscribedChannels: WebSocketChannel[] = [];\n private isReconnecting = false;\n\n constructor(\n private config: PipsendConfig,\n private authManager: AuthManager\n ) {}\n\n /**\n * Connects to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.isConnected) {\n console.log('⚠️ WebSocket already connected');\n return;\n }\n\n if (this.isReconnecting) {\n console.log('⚠️ WebSocket reconnection in progress');\n return;\n }\n\n // Get token first\n const token = await this.authManager.ensureAuthenticated();\n \n // Build WebSocket URL with token as query parameter\n const baseWsUrl = this.buildWebSocketUrl();\n const wsUrl = `${baseWsUrl}${baseWsUrl.includes('?') ? '&' : '?'}token=${encodeURIComponent(token)}`;\n\n return new Promise((resolve, reject) => {\n try {\n const WS = this.getWebSocketConstructor();\n this.ws = new WS(wsUrl);\n\n this.ws.onopen = () => {\n console.log('✅ WebSocket connected');\n this.isConnected = true;\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n\n // Emit connected event\n this.emit('connected', { timestamp: Date.now() });\n\n // Resubscribe to channels if reconnecting\n if (this.subscribedChannels.length > 0) {\n console.log('🔄 Resubscribing to channels:', this.subscribedChannels);\n this.subscribe(this.subscribedChannels);\n }\n\n // Start heartbeat\n this.startHeartbeat();\n\n resolve();\n };\n\n this.ws.onmessage = (event: any) => {\n try {\n const data = JSON.parse(event.data);\n this.handleMessage(data);\n } catch (error) {\n console.error('❌ Failed to parse WebSocket message:', error);\n }\n };\n\n this.ws.onerror = (error: any) => {\n console.error('❌ WebSocket error:', error);\n this.emit('error', error);\n \n if (!this.isConnected) {\n reject(new WebSocketError('Failed to connect to WebSocket server'));\n }\n };\n\n this.ws.onclose = (event: any) => {\n console.log('WebSocket disconnected', event.code, event.reason);\n this.isConnected = false;\n this.stopHeartbeat();\n this.emit('disconnected', { \n code: event.code, \n reason: event.reason,\n timestamp: Date.now()\n });\n this.handleReconnect();\n };\n\n } catch (error) {\n reject(new WebSocketError(\n `Failed to create WebSocket: ${error instanceof Error ? error.message : 'Unknown error'}`\n ));\n }\n });\n }\n\n /**\n * Subscribes to WebSocket channels\n */\n subscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n throw new WebSocketError('WebSocket not connected. Call connect() first.');\n }\n\n // Add to subscribed channels (avoid duplicates)\n this.subscribedChannels = [...new Set([...this.subscribedChannels, ...channels])];\n\n // Send subscription message with correct format\n const message: SubscribeAction = {\n action: 'subscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Subscribed to channels:', channels);\n }\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n console.warn('WebSocket not connected, cannot unsubscribe');\n return;\n }\n\n // Remove from subscribed channels\n this.subscribedChannels = this.subscribedChannels.filter(\n ch => !channels.includes(ch)\n );\n\n // Send unsubscription message with correct format\n const message: UnsubscribeAction = {\n action: 'unsubscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Unsubscribed from channels:', channels);\n }\n\n /**\n * Registers an event listener\n */\n on(event: WebSocketEventType, callback: WebSocketCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback);\n }\n\n /**\n * Removes an event listener\n */\n off(event: WebSocketEventType, callback?: WebSocketCallback): void {\n if (!callback) {\n // Remove all listeners for this event\n this.listeners.delete(event);\n } else {\n // Remove specific listener\n this.listeners.get(event)?.delete(callback);\n }\n }\n\n /**\n * Disconnects from WebSocket\n */\n disconnect(): void {\n console.log('👋 Disconnecting WebSocket...');\n this.stopHeartbeat();\n \n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n \n this.isConnected = false;\n this.isReconnecting = false;\n this.subscribedChannels = [];\n this.listeners.clear();\n }\n\n /**\n * Checks if WebSocket is connected\n */\n isWebSocketConnected(): boolean {\n return this.isConnected;\n }\n\n /**\n * Gets list of subscribed channels\n */\n getSubscribedChannels(): WebSocketChannel[] {\n return [...this.subscribedChannels];\n }\n\n // Private methods\n\n /**\n * Builds WebSocket URL from HTTP(S) server URL\n */\n private buildWebSocketUrl(): string {\n try {\n const url = new URL(this.config.server);\n \n // Convert https:// to wss:// or http:// to ws://\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n \n // Add WebSocket path (default to /api/v1/ws for Pipsend API)\n const wsPath = this.config.websocket?.path || '/api/v1/ws';\n url.pathname = wsPath;\n \n return url.toString();\n } catch (error) {\n throw new WebSocketError('Invalid server URL for WebSocket connection');\n }\n }\n\n /**\n * Gets WebSocket constructor (browser or Node.js)\n */\n private getWebSocketConstructor(): any {\n // Browser environment\n if (typeof WebSocket !== 'undefined') {\n return WebSocket;\n }\n \n // Node.js environment - try to load 'ws' package\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require('ws');\n } catch {\n throw new WebSocketError(\n 'WebSocket not available. Install \"ws\" package for Node.js: npm install ws'\n );\n }\n }\n\n /**\n * Sends an action message through WebSocket\n */\n private sendAction(message: SubscribeAction | UnsubscribeAction): void {\n if (!this.ws || !this.isConnected) {\n console.warn('⚠️ WebSocket not ready, message not sent:', message.action);\n return;\n }\n\n try {\n const payload = JSON.stringify(message);\n this.ws.send(payload);\n } catch (error) {\n console.error('❌ Failed to send WebSocket message:', error);\n }\n }\n\n /**\n * Sends a ping message (for heartbeat)\n */\n private sendPing(): void {\n if (!this.ws || !this.isConnected) {\n return;\n }\n\n try {\n this.ws.send(JSON.stringify({ type: 'ping' }));\n } catch (error) {\n console.error('❌ Failed to send ping:', error);\n }\n }\n\n /**\n * Handles incoming WebSocket messages\n */\n private handleMessage(message: WebSocketMessage): void {\n switch (message.op) {\n case 'connected':\n this.handleConnected(message);\n break;\n \n case 'subscription_success':\n this.handleSubscriptionSuccess(message);\n break;\n \n case 'unsubscription_success':\n this.handleUnsubscriptionSuccess(message);\n break;\n \n case 'push':\n this.handlePushEvent(message);\n break;\n \n case 'error':\n this.handleError(message);\n break;\n \n default:\n console.warn('Unknown WebSocket operation:', message.op);\n }\n\n // Emit to wildcard listeners (listen to all events)\n this.emit('*', message);\n }\n\n /**\n * Handles connected message from server\n */\n private handleConnected(message: WebSocketMessage): void {\n console.log('✅ WebSocket connected:', message.data.message);\n console.log(' Available channels:', message.data.available_channels);\n this.emit('connected', message.data);\n }\n\n /**\n * Handles subscription success\n */\n private handleSubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Subscription successful:', message.data.subscribed);\n this.emit('subscription_success', message.data);\n }\n\n /**\n * Handles unsubscription success\n */\n private handleUnsubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Unsubscription successful:', message.data.unsubscribed);\n this.emit('unsubscription_success', message.data);\n }\n\n /**\n * Handles push events (actual data events)\n */\n private handlePushEvent(message: WebSocketMessage): void {\n const eventData = message.data;\n const eventType = eventData.type;\n \n switch (eventType) {\n case 'position.opened':\n this.emit('position:opened', eventData as PositionEvent);\n break;\n \n case 'position.closed':\n case 'position.partially_closed':\n this.emit('position:closed', eventData as PositionEvent);\n break;\n \n case 'position.updated':\n this.emit('position:updated', eventData as PositionEvent);\n break;\n \n default:\n // Balance update (doesn't have 'type' field)\n if (message.topic?.startsWith('balance:')) {\n this.emit('balance:updated', eventData as BalanceEvent);\n } else {\n console.warn('Unknown event type:', eventType);\n }\n }\n }\n\n /**\n * Handles error messages from server\n */\n private handleError(message: WebSocketMessage): void {\n console.error('❌ WebSocket error:', message.data.message);\n if (message.data.error) {\n console.error(' Error details:', message.data.error);\n }\n this.emit('error', message.data);\n }\n\n /**\n * Emits an event to all registered listeners\n */\n private emit(event: WebSocketEventType, data: any): void {\n const listeners = this.listeners.get(event);\n if (listeners && listeners.size > 0) {\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`❌ Error in WebSocket listener for \"${event}\":`, error);\n }\n });\n }\n }\n\n /**\n * Handles reconnection logic with exponential backoff\n */\n private handleReconnect(): void {\n const autoReconnect = this.config.websocket?.autoReconnect ?? true;\n const maxAttempts = this.config.websocket?.maxReconnectAttempts ?? 5;\n\n if (!autoReconnect) {\n console.log('Auto-reconnect disabled');\n return;\n }\n\n if (this.reconnectAttempts >= maxAttempts) {\n console.log(`❌ Max reconnection attempts (${maxAttempts}) reached. Giving up.`);\n this.emit('error', new WebSocketError('Max reconnection attempts reached'));\n return;\n }\n\n // Exponential backoff: 1s, 2s, 4s, 8s, 16s, max 30s\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n console.log(\n `🔄 Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts + 1}/${maxAttempts})...`\n );\n\n this.isReconnecting = true;\n\n setTimeout(() => {\n this.reconnectAttempts++;\n this.connect().catch(error => {\n console.error('❌ Reconnection failed:', error);\n });\n }, delay);\n }\n\n /**\n * Starts heartbeat to keep connection alive\n */\n private startHeartbeat(): void {\n const interval = this.config.websocket?.heartbeatInterval || 30000;\n \n this.heartbeatTimer = setInterval(() => {\n if (this.isConnected) {\n this.sendPing();\n }\n }, interval);\n }\n\n /**\n * Stops heartbeat timer\n */\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = undefined;\n }\n }\n}\n","import { PipsendError } from '../types';\nimport type { AuthManager } from '../core/auth';\n\n/**\n * HTTP client for making requests to the Pipsend API\n */\nexport class HttpClient {\n constructor(\n private baseUrl: string,\n private authManager?: AuthManager\n ) {}\n\n /**\n * Makes an HTTP request\n */\n async request<T>(\n endpoint: string,\n options: RequestInit = {},\n retryOn401 = true\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n try {\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {})\n };\n\n // Add Authorization header if authManager is available\n if (this.authManager) {\n const token = await this.authManager.ensureAuthenticated();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, {\n ...options,\n headers\n });\n\n // Handle 401 Unauthorized - try to refresh token and retry\n if (response.status === 401 && this.authManager && retryOn401) {\n console.log('⚠️ Received 401, attempting to refresh token...');\n await this.authManager.refreshToken();\n \n // Retry the request with new token (but don't retry again if it fails)\n return this.request<T>(endpoint, options, false);\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = `HTTP ${response.status}: ${errorText || response.statusText}`;\n let errorCode = 'HTTP_ERROR';\n let validationErrors;\n let errorResponse;\n \n // Try to parse error as JSON for better error messages\n try {\n const errorJson = JSON.parse(errorText);\n errorResponse = errorJson;\n \n // Extract message\n if (errorJson.message) {\n errorMessage = errorJson.message;\n }\n \n // Extract error code\n if (errorJson.status_code) {\n errorCode = errorJson.status_code;\n }\n \n // Extract validation errors (422 responses)\n if (errorJson.errors && Array.isArray(errorJson.errors)) {\n validationErrors = errorJson.errors;\n }\n } catch {\n // Keep the original error message if JSON parsing fails\n }\n\n throw new PipsendError(\n errorMessage,\n errorCode,\n response.status,\n validationErrors,\n errorResponse\n );\n }\n\n // Handle empty responses\n const text = await response.text();\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n } catch (error) {\n if (error instanceof PipsendError) {\n throw error;\n }\n throw new PipsendError(\n `Request failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n );\n }\n }\n\n /**\n * GET request\n */\n async get<T>(endpoint: string, params?: Record<string, any>): Promise<T> {\n const queryString = params ? this.buildQueryString(params) : '';\n const url = queryString ? `${endpoint}?${queryString}` : endpoint;\n return this.request<T>(url, { method: 'GET' });\n }\n\n /**\n * POST request\n */\n async post<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * PUT request\n */\n async put<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * Builds query string from params object\n */\n private buildQueryString(params: Record<string, any>): string {\n const filtered = Object.entries(params)\n .filter(([_, value]) => value !== undefined && value !== null && value !== '')\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n \n return filtered.join('&');\n }\n}\n","import type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse\n} from '../types/api/accounts';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Accounts API\n */\nexport class AccountsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a new trading account\n */\n async create(request: CreateAccountRequest): Promise<CreateAccountResponse> {\n return this.http.post<CreateAccountResponse>('/api/v1/accounts', request);\n }\n\n /**\n * List all accounts with optional filters and pagination\n */\n async list(params?: AccountsListParams): Promise<PaginatedResponse<Account> | Account[]> {\n return this.http.get<PaginatedResponse<Account> | Account[]>('/api/v1/accounts', params);\n }\n\n /**\n * Get all account logins\n */\n async getLogins(): Promise<number[]> {\n return this.http.get<number[]>('/api/v1/accounts/logins');\n }\n\n /**\n * Get account status/metrics (balance, equity, credit, margin)\n */\n async getStatus(login: number): Promise<AccountStatusResponse> {\n return this.http.get<AccountStatusResponse>(`/api/v1/accounts/${login}/status`);\n }\n\n /**\n * Get account statistics with optional filters\n */\n async getStatistics(params?: AccountStatisticsParams): Promise<AccountStatistics> {\n return this.http.get<AccountStatistics>('/api/v1/accounts/statistics', params);\n }\n\n /**\n * Change master password for an account\n */\n async changeMasterPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/master`, request);\n }\n\n /**\n * Change investor password for an account\n */\n async changeInvestorPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/investor`, request);\n }\n\n /**\n * Archive an account\n */\n async archive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/archive`);\n }\n\n /**\n * Unarchive an account\n */\n async unarchive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/unarchive`);\n }\n\n /**\n * Update account information (partial update)\n * All fields are optional, only send the ones you want to update\n */\n async update(login: number, request: UpdateAccountRequest): Promise<UpdateAccountResponse> {\n return this.http.put<UpdateAccountResponse>(`/api/v1/accounts/${login}`, request);\n }\n\n /**\n * Adjust balance or credit for an account\n * The adjustment is relative: amount is added or subtracted from current value\n */\n async balance(login: number, request: AdjustBalanceRequest): Promise<AdjustBalanceResponse> {\n return this.http.put<AdjustBalanceResponse>(`/api/v1/accounts/${login}/adjust`, request);\n }\n}\n","import type {\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics\n} from '../types/api/trading-groups';\nimport { HttpClient } from './http-client';\n\n/**\n * Trading Groups API\n */\nexport class TradingGroupsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List all trading groups with optional filters\n */\n async list(params?: TradingGroupsListParams): Promise<TradingGroup[]> {\n return this.http.get<TradingGroup[]>('/api/v1/trading-groups', params);\n }\n\n /**\n * Get trading group by name\n */\n async getByName(name: string): Promise<TradingGroup> {\n return this.http.get<TradingGroup>(`/api/v1/trading-groups/${encodeURIComponent(name)}`);\n }\n\n /**\n * Get all trading group names\n */\n async getNames(): Promise<string[]> {\n return this.http.get<string[]>('/api/v1/trading-groups/names');\n }\n\n /**\n * Get trading group statistics\n */\n async getStatistics(type?: string): Promise<TradingGroupStatistics> {\n return this.http.get<TradingGroupStatistics>('/api/v1/trading-groups/statistics', type ? { type } : undefined);\n }\n}\n","import type {\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams\n} from '../types/api/market-data';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Market Data API\n * \n * Note: All data has a minimum age of 1 hour (no real-time data)\n */\nexport class MarketDataAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Get historical OHLCV candles\n * \n * @param params - Candles parameters (symbol and timeframe are required)\n * @returns Paginated candles or array of candles\n * \n * @example\n * ```ts\n * // Get last 100 candles\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD',\n * timeframe: '1m',\n * limit: 100,\n * order: 'desc'\n * });\n * \n * // Get candles with time range\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD,ETHUSD',\n * timeframe: '1h',\n * from: '2025-11-01T00:00:00Z',\n * to: '2025-11-02T00:00:00Z'\n * });\n * ```\n */\n async getCandles(params: CandlesParams): Promise<PaginatedResponse<Candle> | Candle[]> {\n return this.http.get<PaginatedResponse<Candle> | Candle[]>('/api/v1/candles', params);\n }\n\n /**\n * Get available symbols with metadata\n * \n * @param params - Optional filters for symbols\n * @returns Paginated symbols or array of symbols\n * \n * @example\n * ```ts\n * // Get all symbols\n * const symbols = await client.marketData.getSymbols();\n * \n * // Filter by group\n * const cryptoSymbols = await client.marketData.getSymbols({\n * group: 'CRYPTO_MAJOR',\n * has_data: true\n * });\n * ```\n */\n async getSymbols(params?: SymbolsParams): Promise<PaginatedResponse<Symbol> | Symbol[]> {\n return this.http.get<PaginatedResponse<Symbol> | Symbol[]>('/api/v1/symbols', params);\n }\n\n /**\n * Get symbol groups hierarchy\n * \n * Note: This endpoint never uses pagination\n * \n * @param params - Optional filters for groups\n * @returns Array of groups\n * \n * @example\n * ```ts\n * // Get all groups\n * const groups = await client.marketData.getGroups();\n * \n * // Get only root groups\n * const rootGroups = await client.marketData.getGroups({\n * root_only: true\n * });\n * ```\n */\n async getGroups(params?: GroupsParams): Promise<Group[]> {\n return this.http.get<Group[]>('/api/v1/groups', params);\n }\n}\n","import type {\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse\n} from '../types/api/positions';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Positions API\n */\nexport class PositionsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List positions with optional filters and pagination\n */\n async list(params?: PositionsListParams): Promise<PaginatedResponse<Position> | Position[]> {\n return this.http.get<PaginatedResponse<Position> | Position[]>('/api/v1/positions', params);\n }\n\n /**\n * Get position statistics with optional filters and grouping\n */\n async getStats(params?: PositionStatsParams): Promise<PositionStatistics | PositionStatisticsGrouped[]> {\n return this.http.get<PositionStatistics | PositionStatisticsGrouped[]>('/api/v1/positions/stats', params);\n }\n\n /**\n * Get position totals with dynamic grouping\n */\n async getTotals(params: PositionTotalsParams): Promise<PositionTotals[]> {\n return this.http.get<PositionTotals[]>('/api/v1/positions/totals', params);\n }\n\n /**\n * Update position (modify SL/TP)\n */\n async update(id: number, request: UpdatePositionRequest): Promise<UpdatePositionResponse> {\n return this.http.put<UpdatePositionResponse>(`/api/v1/positions/${id}`, request);\n }\n\n /**\n * Delete (close) position\n */\n async delete(id: number, params: DeletePositionParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/positions/${id}?login=${params.login}`);\n }\n\n /**\n * Check and recalculate positions\n */\n async check(request: CheckPositionsRequest): Promise<CheckPositionsResponse> {\n return this.http.post<CheckPositionsResponse>('/api/v1/positions/check', request);\n }\n}\n","import type {\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse\n} from '../types/api/orders';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Orders API\n */\nexport class OrdersAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List orders with optional filters and pagination\n */\n async list(params?: OrdersListParams): Promise<PaginatedResponse<Order> | Order[]> {\n return this.http.get<PaginatedResponse<Order> | Order[]>('/api/v1/orders', params);\n }\n\n /**\n * Get order statistics with optional filters and grouping\n */\n async getStats(params?: OrderStatsParams): Promise<OrderStatistics | OrderStatisticsGrouped[]> {\n return this.http.get<OrderStatistics | OrderStatisticsGrouped[]>('/api/v1/orders/stats', params);\n }\n\n /**\n * Get order totals with dynamic grouping\n */\n async getTotals(params: OrderTotalsParams): Promise<OrderTotals[]> {\n return this.http.get<OrderTotals[]>('/api/v1/orders/totals', params);\n }\n\n /**\n * Update order (modify SL/TP)\n */\n async update(id: number, request: UpdateOrderRequest): Promise<UpdateOrderResponse> {\n return this.http.put<UpdateOrderResponse>(`/api/v1/orders/${id}`, request);\n }\n\n /**\n * Delete (cancel) order\n */\n async delete(id: number, params: DeleteOrderParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/orders/${id}?login=${params.login}`);\n }\n\n /**\n * Check and validate pending orders\n */\n async check(request: CheckOrdersRequest): Promise<CheckOrdersResponse> {\n return this.http.post<CheckOrdersResponse>('/api/v1/orders/check', request);\n }\n}\n","import type {\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse\n} from '../types/api/trades';\nimport { HttpClient } from './http-client';\n\n/**\n * Trades API\n */\nexport class TradesAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Open a new trade (market or pending order)\n */\n async open(request: OpenTradeRequest): Promise<OpenTradeResponse> {\n return this.http.post<OpenTradeResponse>('/api/v1/trades/open', request);\n }\n\n /**\n * Close a trade (full or partial)\n */\n async close(request: CloseTradeRequest): Promise<CloseTradeResponse> {\n return this.http.post<CloseTradeResponse>('/api/v1/trades/close', request);\n }\n\n /**\n * Modify trade Stop Loss and/or Take Profit\n */\n async modify(request: ModifyTradeRequest): Promise<ModifyTradeResponse> {\n return this.http.put<ModifyTradeResponse>('/api/v1/trades/modify', request);\n }\n\n /**\n * Check if there's sufficient margin for a trade\n */\n async checkMargin(request: CheckMarginRequest): Promise<CheckMarginResponse> {\n return this.http.post<CheckMarginResponse>('/api/v1/trades/check-margin', request);\n }\n\n /**\n * Calculate potential profit for a trade\n */\n async calculateProfit(request: CalculateProfitRequest): Promise<CalculateProfitResponse> {\n return this.http.post<CalculateProfitResponse>('/api/v1/trades/calc-profit', request);\n }\n}\n","import type { \n PipsendConfig,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketCallback,\n WebSocketChannel,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport type { HealthCheckResponse } from '../types/api/health';\nimport { ConfigurationError, WebSocketError } from '../types';\nimport { AuthManager } from './auth';\nimport { WebSocketManager } from './websocket';\nimport { \n HttpClient,\n AccountsAPI,\n TradingGroupsAPI,\n MarketDataAPI,\n PositionsAPI,\n OrdersAPI,\n TradesAPI\n} from '../api';\n\n/**\n * Main Pipsend SDK client\n */\nexport class PipsendClient {\n private authManager: AuthManager;\n private wsManager?: WebSocketManager;\n private config: PipsendConfig;\n private http: HttpClient;\n\n // API modules\n public readonly accounts: AccountsAPI;\n public readonly tradingGroups: TradingGroupsAPI;\n public readonly marketData: MarketDataAPI;\n public readonly positions: PositionsAPI;\n public readonly orders: OrdersAPI;\n public readonly trades: TradesAPI;\n\n constructor(config: PipsendConfig) {\n this.validateConfig(config);\n this.config = {\n ...config,\n autoRefresh: config.autoRefresh ?? true,\n refreshMarginMinutes: config.refreshMarginMinutes ?? 5,\n timezone: config.timezone ?? 'UTC'\n };\n this.authManager = new AuthManager(this.config);\n\n // Initialize HTTP client with auth manager\n this.http = new HttpClient(this.config.server, this.authManager);\n\n // Initialize API modules\n this.accounts = new AccountsAPI(this.http);\n this.tradingGroups = new TradingGroupsAPI(this.http);\n this.marketData = new MarketDataAPI(this.http);\n this.positions = new PositionsAPI(this.http);\n this.orders = new OrdersAPI(this.http);\n this.trades = new TradesAPI(this.http);\n\n // Initialize WebSocket if enabled\n if (config.websocket?.enabled) {\n this.wsManager = new WebSocketManager(this.config, this.authManager);\n \n // Auto-connect if configured\n if (config.websocket.autoConnect) {\n this.wsManager.connect().catch(error => {\n console.error('Failed to auto-connect WebSocket:', error);\n });\n }\n }\n }\n\n /**\n * Validates the initial configuration\n */\n private validateConfig(config: PipsendConfig): void {\n if (!config.server) {\n throw new ConfigurationError('The \"server\" parameter is required');\n }\n\n // Validate URL format\n try {\n new URL(config.server);\n } catch {\n throw new ConfigurationError('The \"server\" parameter must be a valid URL');\n }\n\n // Note: login and password are optional for now (will be required when auth is implemented)\n }\n\n /**\n * Authentication API\n * TODO: Implement when authentication is available\n */\n public auth = {\n /**\n * Forces a token refresh\n */\n refresh: async (): Promise<void> => {\n await this.authManager.refreshToken();\n },\n\n /**\n * Checks if the client is authenticated\n */\n isAuthenticated: (): boolean => {\n return this.authManager.isAuthenticated();\n },\n\n /**\n * Gets the current token (if it exists)\n */\n getToken: (): string | undefined => {\n return this.authManager.getToken();\n },\n\n /**\n * Logs out by clearing the token\n */\n logout: (): void => {\n this.authManager.clearToken();\n }\n };\n\n /**\n * WebSocket streaming API\n * Provides real-time updates for prices, orders, positions, etc.\n */\n public stream = {\n /**\n * Connects to WebSocket server\n */\n connect: async (): Promise<void> => {\n if (!this.wsManager) {\n throw new WebSocketError(\n 'WebSocket not enabled. Set websocket.enabled: true in config'\n );\n }\n await this.wsManager.connect();\n },\n\n /**\n * Disconnects from WebSocket server\n */\n disconnect: (): void => {\n this.wsManager?.disconnect();\n },\n\n /**\n * Checks if WebSocket is connected\n */\n isConnected: (): boolean => {\n return this.wsManager?.isWebSocketConnected() ?? false;\n },\n\n /**\n * Subscribes to WebSocket channels\n * @example\n * client.stream.subscribe(['positions:new', 'positions:closed']);\n */\n subscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.subscribe(channels);\n },\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.unsubscribe(channels);\n },\n\n /**\n * Gets list of subscribed channels\n */\n getSubscriptions: (): WebSocketChannel[] => {\n return this.wsManager?.getSubscribedChannels() ?? [];\n },\n\n /**\n * Listens to position opened events\n */\n onPositionOpened: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:opened', callback);\n },\n\n /**\n * Listens to position closed events (includes partial closes)\n */\n onPositionClosed: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:closed', callback);\n },\n\n /**\n * Listens to position updated events (throttled to max 1 per 2 seconds)\n */\n onPositionUpdated: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback);\n },\n\n /**\n * Listens to balance updated events\n */\n onBalanceUpdated: (callback: WebSocketCallback<BalanceEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback);\n },\n\n // Legacy methods (deprecated but kept for compatibility)\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPriceUpdate: (callback: WebSocketCallback<PriceUpdate>): void => {\n console.warn('⚠️ onPriceUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new event for backward compatibility\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onPositionOpened/onPositionClosed instead\n */\n onOrderUpdate: (callback: WebSocketCallback<OrderUpdate>): void => {\n console.warn('⚠️ onOrderUpdate is deprecated. Use onPositionOpened/onPositionClosed instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new events for backward compatibility\n this.wsManager.on('position:opened', callback as any);\n },\n\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPositionUpdate: (callback: WebSocketCallback<PositionUpdate>): void => {\n console.warn('⚠️ onPositionUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onBalanceUpdated instead\n */\n onBalanceUpdate: (callback: WebSocketCallback<BalanceUpdate>): void => {\n console.warn('⚠️ onBalanceUpdate is deprecated. Use onBalanceUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback as any);\n },\n\n /**\n * Listens to connection events\n */\n onConnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('connected', callback);\n },\n\n /**\n * Listens to disconnection events\n */\n onDisconnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('disconnected', callback);\n },\n\n /**\n * Listens to error events\n */\n onError: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('error', callback);\n },\n\n /**\n * Removes event listener\n */\n off: (event: string, callback?: WebSocketCallback): void => {\n this.wsManager?.off(event as any, callback);\n }\n };\n\n /**\n * Health check\n */\n async ping(): Promise<HealthCheckResponse> {\n return this.http.get<HealthCheckResponse>('/ping');\n }\n\n /**\n * Client information\n */\n public getConfig(): Readonly<PipsendConfig> {\n return { ...this.config };\n }\n}\n","// Export types\nexport type {\n PipsendConfig,\n TokenInfo,\n OrderData,\n AuthResponse,\n WebSocketConfig,\n WebSocketMessage,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketEventType,\n WebSocketCallback,\n // API types\n PaginationParams,\n PaginatedResponse,\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n ChangePasswordRequest,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n UpdatePositionRequest,\n Order,\n OrdersListParams,\n OrderStatistics,\n UpdateOrderRequest,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './types';\n\n// Export errors\nexport {\n PipsendError,\n AuthenticationError,\n ConfigurationError,\n WebSocketError\n} from './types';\n\n// Export client\nexport { PipsendClient } from './core/client';\n\n// Export creation function (main API)\nimport { PipsendClient } from './core/client';\nimport type { PipsendConfig } from './types';\n\n/**\n * Creates a new instance of the Pipsend client\n *\n * @example\n * ```typescript\n * import { createClient } from '@pipsend/sdk';\n *\n * const client = createClient({\n * server: 'https://api.pipsend.com',\n * login: 'your-username',\n * password: 'your-password',\n * timezone: 'America/New_York' // optional\n * });\n *\n * // The SDK handles authentication automatically\n * await client.orders.send({\n * symbol: 'EURUSD',\n * volume: 0.1\n * });\n * ```\n */\nexport function createClient(config: PipsendConfig): PipsendClient {\n return new PipsendClient(config);\n}\n\n// Export default for compatibility\nconst sdk = {\n createClient,\n PipsendClient\n};\n\nexport default sdk;\n"],"mappings":";;;;;;;;AAkFO,IAAM,eAAN,cAA2B,MAAM;AAAA,EAItC,YACE,SACO,MACA,YACP,QACA,UACA;AACA,UAAM,OAAO;AALN;AACA;AAKP,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,qBAA6B;AAC3B,QAAI,CAAC,KAAK,UAAU,KAAK,OAAO,WAAW,GAAG;AAC5C,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,eAAe,KAAK,OACvB,IAAI,SAAO,OAAO,IAAI,KAAK,KAAK,IAAI,OAAO,EAAE,EAC7C,KAAK,IAAI;AAEZ,WAAO,GAAG,KAAK,OAAO;AAAA,EAAK,YAAY;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA6B;AAC3B,WAAO,KAAK,eAAe,OAAO,KAAK,SAAS;AAAA,EAClD;AACF;AAEO,IAAM,sBAAN,cAAkC,aAAa;AAAA,EACpD,YAAY,SAAiB;AAC3B,UAAM,SAAS,cAAc,GAAG;AAChC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,qBAAN,cAAiC,aAAa;AAAA,EACnD,YAAY,SAAiB;AAC3B,UAAM,SAAS,cAAc;AAC7B,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EAC/C,YAAY,SAAiB;AAC3B,UAAM,SAAS,iBAAiB;AAChC,SAAK,OAAO;AAAA,EACd;AACF;;;ACvIO,IAAM,cAAN,MAAkB;AAAA,EAIvB,YACU,QACR;AADQ;AAER,UAAM,gBAAgB,OAAO,wBAAwB;AACrD,SAAK,kBAAkB,gBAAgB,KAAK;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKO,kBAA2B;AAChC,WAAO,CAAC,CAAC,KAAK,aAAa,CAAC,KAAK,eAAe;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKO,WAA+B;AACpC,QAAI,KAAK,gBAAgB,GAAG;AAC1B,aAAO,KAAK,WAAW;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,sBAAuC;AAClD,QAAI,CAAC,KAAK,gBAAgB,GAAG;AAC3B,YAAM,KAAK,aAAa;AAAA,IAC1B;AACA,WAAO,KAAK,UAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAA8B;AAC1C,QAAI,CAAC,KAAK,OAAO,SAAS,CAAC,KAAK,OAAO,UAAU;AAC/C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,KAAK,OAAO;AAAA,UACnB,UAAU,KAAK,OAAO;AAAA,QACxB,CAAC;AAAA,MACH,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,cAAM,IAAI;AAAA,UACR,UAAU,WAAW,0BAA0B,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,QACvF;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAK,aAAa,IAAI;AAEtB,cAAQ,IAAI,kCAA6B;AACzC,cAAQ,IAAI,YAAY,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,KAAK,GAAG;AAC1F,cAAQ,IAAI,aAAa,KAAK,KAAK,KAAK,EAAE;AAC1C,cAAQ,IAAI,gBAAgB,KAAK,KAAK,QAAQ,QAAQ,CAAC,CAAC,EAAE;AAC1D,cAAQ,IAAI,mBAAmB,KAAK,WAAW,EAAE;AAAA,IACnD,SAAS,OAAO;AACd,UAAI,iBAAiB,qBAAqB;AACxC,cAAM;AAAA,MACR;AACA,YAAM,IAAI;AAAA,QACR,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,eAA8B;AACzC,QAAI,CAAC,KAAK,WAAW,cAAc;AACjC,cAAQ,IAAI,yEAA+D;AAC3E,WAAK,YAAY;AACjB,YAAM,KAAK,aAAa;AACxB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,wBAAwB;AAAA,QACxE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU;AAAA,UACnB,eAAe,KAAK,UAAU;AAAA,QAChC,CAAC;AAAA,MACH,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,gBAAQ,IAAI,mEAAyD;AACrE,aAAK,YAAY;AACjB,cAAM,KAAK,aAAa;AACxB;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,YAAY,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,aAAa,GAAI;AAEjE,WAAK,YAAY;AAAA,QACf,OAAO,KAAK;AAAA,QACZ,cAAc,KAAK,UAAU;AAAA;AAAA,QAC7B,UAAU;AAAA,QACV;AAAA,MACF;AAEA,cAAQ,IAAI,qCAAgC;AAAA,IAC9C,SAAS,OAAO;AACd,cAAQ,MAAM,kCAA6B,KAAK;AAChD,WAAK,YAAY;AACjB,YAAM,KAAK,aAAa;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,aAAmB;AACxB,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAA0B;AAChC,QAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,mBAAmB,KAAK,UAAU,UAAU,QAAQ,IAAI,KAAK;AAEnE,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,UAA8B;AACjD,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,YAAY,IAAI,KAAK,IAAI,QAAQ,IAAI,SAAS,aAAa,GAAI;AAErE,SAAK,YAAY;AAAA,MACf,OAAO,SAAS;AAAA,MAChB,cAAc,SAAS;AAAA,MACvB,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;;;ACxJO,IAAM,mBAAN,MAAuB;AAAA,EAS5B,YACU,QACA,aACR;AAFQ;AACA;AATV;AAAA,SAAQ,oBAAoB;AAE5B,SAAQ,YAAY,oBAAI,IAAoC;AAC5D,SAAQ,cAAc;AACtB,SAAQ,qBAAyC,CAAC;AAClD,SAAQ,iBAAiB;AAAA,EAKtB;AAAA;AAAA;AAAA;AAAA,EAKH,MAAM,UAAyB;AAC7B,QAAI,KAAK,aAAa;AACpB,cAAQ,IAAI,0CAAgC;AAC5C;AAAA,IACF;AAEA,QAAI,KAAK,gBAAgB;AACvB,cAAQ,IAAI,iDAAuC;AACnD;AAAA,IACF;AAGA,UAAM,QAAQ,MAAM,KAAK,YAAY,oBAAoB;AAGzD,UAAM,YAAY,KAAK,kBAAkB;AACzC,UAAM,QAAQ,GAAG,SAAS,GAAG,UAAU,SAAS,GAAG,IAAI,MAAM,GAAG,SAAS,mBAAmB,KAAK,CAAC;AAElG,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAI;AACF,cAAM,KAAK,KAAK,wBAAwB;AACxC,aAAK,KAAK,IAAI,GAAG,KAAK;AAEtB,aAAK,GAAG,SAAS,MAAM;AACrB,kBAAQ,IAAI,4BAAuB;AACnC,eAAK,cAAc;AACnB,eAAK,iBAAiB;AACtB,eAAK,oBAAoB;AAGzB,eAAK,KAAK,aAAa,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC;AAGhD,cAAI,KAAK,mBAAmB,SAAS,GAAG;AACtC,oBAAQ,IAAI,wCAAiC,KAAK,kBAAkB;AACpE,iBAAK,UAAU,KAAK,kBAAkB;AAAA,UACxC;AAGA,eAAK,eAAe;AAEpB,kBAAQ;AAAA,QACV;AAEA,aAAK,GAAG,YAAY,CAAC,UAAe;AAClC,cAAI;AACF,kBAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAClC,iBAAK,cAAc,IAAI;AAAA,UACzB,SAAS,OAAO;AACd,oBAAQ,MAAM,6CAAwC,KAAK;AAAA,UAC7D;AAAA,QACF;AAEA,aAAK,GAAG,UAAU,CAAC,UAAe;AAChC,kBAAQ,MAAM,2BAAsB,KAAK;AACzC,eAAK,KAAK,SAAS,KAAK;AAExB,cAAI,CAAC,KAAK,aAAa;AACrB,mBAAO,IAAI,eAAe,uCAAuC,CAAC;AAAA,UACpE;AAAA,QACF;AAEA,aAAK,GAAG,UAAU,CAAC,UAAe;AAChC,kBAAQ,IAAI,0BAA0B,MAAM,MAAM,MAAM,MAAM;AAC9D,eAAK,cAAc;AACnB,eAAK,cAAc;AACnB,eAAK,KAAK,gBAAgB;AAAA,YACxB,MAAM,MAAM;AAAA,YACZ,QAAQ,MAAM;AAAA,YACd,WAAW,KAAK,IAAI;AAAA,UACtB,CAAC;AACD,eAAK,gBAAgB;AAAA,QACvB;AAAA,MAEF,SAAS,OAAO;AACd,eAAO,IAAI;AAAA,UACT,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACzF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,UAAoC;AAC5C,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,eAAe,gDAAgD;AAAA,IAC3E;AAGA,SAAK,qBAAqB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,KAAK,oBAAoB,GAAG,QAAQ,CAAC,CAAC;AAGhF,UAAM,UAA2B;AAAA,MAC/B,QAAQ;AAAA,MACR;AAAA,IACF;AAEA,SAAK,WAAW,OAAO;AACvB,YAAQ,IAAI,qCAA8B,QAAQ;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAAoC;AAC9C,QAAI,CAAC,KAAK,aAAa;AACrB,cAAQ,KAAK,6CAA6C;AAC1D;AAAA,IACF;AAGA,SAAK,qBAAqB,KAAK,mBAAmB;AAAA,MAChD,QAAM,CAAC,SAAS,SAAS,EAAE;AAAA,IAC7B;AAGA,UAAM,UAA6B;AAAA,MACjC,QAAQ;AAAA,MACR;AAAA,IACF;AAEA,SAAK,WAAW,OAAO;AACvB,YAAQ,IAAI,yCAAkC,QAAQ;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,GAAG,OAA2B,UAAmC;AAC/D,QAAI,CAAC,KAAK,UAAU,IAAI,KAAK,GAAG;AAC9B,WAAK,UAAU,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,IACrC;AACA,SAAK,UAAU,IAAI,KAAK,EAAG,IAAI,QAAQ;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAA2B,UAAoC;AACjE,QAAI,CAAC,UAAU;AAEb,WAAK,UAAU,OAAO,KAAK;AAAA,IAC7B,OAAO;AAEL,WAAK,UAAU,IAAI,KAAK,GAAG,OAAO,QAAQ;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAmB;AACjB,YAAQ,IAAI,sCAA+B;AAC3C,SAAK,cAAc;AAEnB,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AACd,WAAK,KAAK;AAAA,IACZ;AAEA,SAAK,cAAc;AACnB,SAAK,iBAAiB;AACtB,SAAK,qBAAqB,CAAC;AAC3B,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,wBAA4C;AAC1C,WAAO,CAAC,GAAG,KAAK,kBAAkB;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAA4B;AAClC,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,KAAK,OAAO,MAAM;AAGtC,UAAI,WAAW,IAAI,aAAa,WAAW,SAAS;AAGpD,YAAM,SAAS,KAAK,OAAO,WAAW,QAAQ;AAC9C,UAAI,WAAW;AAEf,aAAO,IAAI,SAAS;AAAA,IACtB,SAAS,OAAO;AACd,YAAM,IAAI,eAAe,6CAA6C;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAA+B;AAErC,QAAI,OAAO,cAAc,aAAa;AACpC,aAAO;AAAA,IACT;AAGA,QAAI;AAEF,aAAO,UAAQ,IAAI;AAAA,IACrB,QAAQ;AACN,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,SAAoD;AACrE,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,aAAa;AACjC,cAAQ,KAAK,uDAA6C,QAAQ,MAAM;AACxE;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,KAAK,UAAU,OAAO;AACtC,WAAK,GAAG,KAAK,OAAO;AAAA,IACtB,SAAS,OAAO;AACd,cAAQ,MAAM,4CAAuC,KAAK;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAiB;AACvB,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,aAAa;AACjC;AAAA,IACF;AAEA,QAAI;AACF,WAAK,GAAG,KAAK,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC;AAAA,IAC/C,SAAS,OAAO;AACd,cAAQ,MAAM,+BAA0B,KAAK;AAAA,IAC/C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,SAAiC;AACrD,YAAQ,QAAQ,IAAI;AAAA,MAClB,KAAK;AACH,aAAK,gBAAgB,OAAO;AAC5B;AAAA,MAEF,KAAK;AACH,aAAK,0BAA0B,OAAO;AACtC;AAAA,MAEF,KAAK;AACH,aAAK,4BAA4B,OAAO;AACxC;AAAA,MAEF,KAAK;AACH,aAAK,gBAAgB,OAAO;AAC5B;AAAA,MAEF,KAAK;AACH,aAAK,YAAY,OAAO;AACxB;AAAA,MAEF;AACE,gBAAQ,KAAK,gCAAgC,QAAQ,EAAE;AAAA,IAC3D;AAGA,SAAK,KAAK,KAAK,OAAO;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,SAAiC;AACvD,YAAQ,IAAI,+BAA0B,QAAQ,KAAK,OAAO;AAC1D,YAAQ,IAAI,0BAA0B,QAAQ,KAAK,kBAAkB;AACrE,SAAK,KAAK,aAAa,QAAQ,IAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAA0B,SAAiC;AACjE,YAAQ,IAAI,mCAA8B,QAAQ,KAAK,UAAU;AACjE,SAAK,KAAK,wBAAwB,QAAQ,IAAI;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKQ,4BAA4B,SAAiC;AACnE,YAAQ,IAAI,qCAAgC,QAAQ,KAAK,YAAY;AACrE,SAAK,KAAK,0BAA0B,QAAQ,IAAI;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,SAAiC;AACvD,UAAM,YAAY,QAAQ;AAC1B,UAAM,YAAY,UAAU;AAE5B,YAAQ,WAAW;AAAA,MACjB,KAAK;AACH,aAAK,KAAK,mBAAmB,SAA0B;AACvD;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,aAAK,KAAK,mBAAmB,SAA0B;AACvD;AAAA,MAEF,KAAK;AACH,aAAK,KAAK,oBAAoB,SAA0B;AACxD;AAAA,MAEF;AAEE,YAAI,QAAQ,OAAO,WAAW,UAAU,GAAG;AACzC,eAAK,KAAK,mBAAmB,SAAyB;AAAA,QACxD,OAAO;AACL,kBAAQ,KAAK,uBAAuB,SAAS;AAAA,QAC/C;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,SAAiC;AACnD,YAAQ,MAAM,2BAAsB,QAAQ,KAAK,OAAO;AACxD,QAAI,QAAQ,KAAK,OAAO;AACtB,cAAQ,MAAM,qBAAqB,QAAQ,KAAK,KAAK;AAAA,IACvD;AACA,SAAK,KAAK,SAAS,QAAQ,IAAI;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKQ,KAAK,OAA2B,MAAiB;AACvD,UAAM,YAAY,KAAK,UAAU,IAAI,KAAK;AAC1C,QAAI,aAAa,UAAU,OAAO,GAAG;AACnC,gBAAU,QAAQ,cAAY;AAC5B,YAAI;AACF,mBAAS,IAAI;AAAA,QACf,SAAS,OAAO;AACd,kBAAQ,MAAM,2CAAsC,KAAK,MAAM,KAAK;AAAA,QACtE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAwB;AAC9B,UAAM,gBAAgB,KAAK,OAAO,WAAW,iBAAiB;AAC9D,UAAM,cAAc,KAAK,OAAO,WAAW,wBAAwB;AAEnE,QAAI,CAAC,eAAe;AAClB,cAAQ,IAAI,yBAAyB;AACrC;AAAA,IACF;AAEA,QAAI,KAAK,qBAAqB,aAAa;AACzC,cAAQ,IAAI,qCAAgC,WAAW,uBAAuB;AAC9E,WAAK,KAAK,SAAS,IAAI,eAAe,mCAAmC,CAAC;AAC1E;AAAA,IACF;AAGA,UAAM,QAAQ,KAAK,IAAI,MAAO,KAAK,IAAI,GAAG,KAAK,iBAAiB,GAAG,GAAK;AAExE,YAAQ;AAAA,MACN,6BAAsB,KAAK,eAAe,KAAK,oBAAoB,CAAC,IAAI,WAAW;AAAA,IACrF;AAEA,SAAK,iBAAiB;AAEtB,eAAW,MAAM;AACf,WAAK;AACL,WAAK,QAAQ,EAAE,MAAM,WAAS;AAC5B,gBAAQ,MAAM,+BAA0B,KAAK;AAAA,MAC/C,CAAC;AAAA,IACH,GAAG,KAAK;AAAA,EACV;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAuB;AAC7B,UAAM,WAAW,KAAK,OAAO,WAAW,qBAAqB;AAE7D,SAAK,iBAAiB,YAAY,MAAM;AACtC,UAAI,KAAK,aAAa;AACpB,aAAK,SAAS;AAAA,MAChB;AAAA,IACF,GAAG,QAAQ;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAsB;AAC5B,QAAI,KAAK,gBAAgB;AACvB,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AACF;;;AC1cO,IAAM,aAAN,MAAiB;AAAA,EACtB,YACU,SACA,aACR;AAFQ;AACA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKH,MAAM,QACJ,UACA,UAAuB,CAAC,GACxB,aAAa,MACD;AACZ,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,QAAQ;AAEtC,QAAI;AAEF,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,GAAI,QAAQ,WAAqC,CAAC;AAAA,MACpD;AAGA,UAAI,KAAK,aAAa;AACpB,cAAM,QAAQ,MAAM,KAAK,YAAY,oBAAoB;AACzD,gBAAQ,eAAe,IAAI,UAAU,KAAK;AAAA,MAC5C;AAEA,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAGD,UAAI,SAAS,WAAW,OAAO,KAAK,eAAe,YAAY;AAC7D,gBAAQ,IAAI,2DAAiD;AAC7D,cAAM,KAAK,YAAY,aAAa;AAGpC,eAAO,KAAK,QAAW,UAAU,SAAS,KAAK;AAAA,MACjD;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,YAAI,eAAe,QAAQ,SAAS,MAAM,KAAK,aAAa,SAAS,UAAU;AAC/E,YAAI,YAAY;AAChB,YAAI;AACJ,YAAI;AAGJ,YAAI;AACF,gBAAM,YAAY,KAAK,MAAM,SAAS;AACtC,0BAAgB;AAGhB,cAAI,UAAU,SAAS;AACrB,2BAAe,UAAU;AAAA,UAC3B;AAGA,cAAI,UAAU,aAAa;AACzB,wBAAY,UAAU;AAAA,UACxB;AAGA,cAAI,UAAU,UAAU,MAAM,QAAQ,UAAU,MAAM,GAAG;AACvD,+BAAmB,UAAU;AAAA,UAC/B;AAAA,QACF,QAAQ;AAAA,QAER;AAEA,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAGA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAI,CAAC,MAAM;AACT,eAAO,CAAC;AAAA,MACV;AAEA,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,SAAS,OAAO;AACd,UAAI,iBAAiB,cAAc;AACjC,cAAM;AAAA,MACR;AACA,YAAM,IAAI;AAAA,QACR,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC3E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAO,UAAkB,QAA0C;AACvE,UAAM,cAAc,SAAS,KAAK,iBAAiB,MAAM,IAAI;AAC7D,UAAM,MAAM,cAAc,GAAG,QAAQ,IAAI,WAAW,KAAK;AACzD,WAAO,KAAK,QAAW,KAAK,EAAE,QAAQ,MAAM,CAAC;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAQ,UAAkB,MAAwB;AACtD,WAAO,KAAK,QAAW,UAAU;AAAA,MAC/B,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAO,UAAkB,MAAwB;AACrD,WAAO,KAAK,QAAW,UAAU;AAAA,MAC/B,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAU,UAA8B;AAC5C,WAAO,KAAK,QAAW,UAAU,EAAE,QAAQ,SAAS,CAAC;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,QAAqC;AAC5D,UAAM,WAAW,OAAO,QAAQ,MAAM,EACnC,OAAO,CAAC,CAAC,GAAG,KAAK,MAAM,UAAU,UAAa,UAAU,QAAQ,UAAU,EAAE,EAC5E,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,OAAO,KAAK,CAAC,CAAC,EAAE;AAE1F,WAAO,SAAS,KAAK,GAAG;AAAA,EAC1B;AACF;;;ACpIO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKvC,MAAM,OAAO,SAA+D;AAC1E,WAAO,KAAK,KAAK,KAA4B,oBAAoB,OAAO;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,QAA8E;AACvF,WAAO,KAAK,KAAK,IAA4C,oBAAoB,MAAM;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAA+B;AACnC,WAAO,KAAK,KAAK,IAAc,yBAAyB;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,OAA+C;AAC7D,WAAO,KAAK,KAAK,IAA2B,oBAAoB,KAAK,SAAS;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAA8D;AAChF,WAAO,KAAK,KAAK,IAAuB,+BAA+B,MAAM;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAqB,OAAe,SAA+C;AACvF,WAAO,KAAK,KAAK,IAAU,oBAAoB,KAAK,oBAAoB,OAAO;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAuB,OAAe,SAA+C;AACzF,WAAO,KAAK,KAAK,IAAU,oBAAoB,KAAK,sBAAsB,OAAO;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,OAA8B;AAC1C,WAAO,KAAK,KAAK,IAAU,oBAAoB,KAAK,UAAU;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,OAA8B;AAC5C,WAAO,KAAK,KAAK,IAAU,oBAAoB,KAAK,YAAY;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,OAAe,SAA+D;AACzF,WAAO,KAAK,KAAK,IAA2B,oBAAoB,KAAK,IAAI,OAAO;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,OAAe,SAA+D;AAC1F,WAAO,KAAK,KAAK,IAA2B,oBAAoB,KAAK,WAAW,OAAO;AAAA,EACzF;AACF;;;AC3FO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKvC,MAAM,KAAK,QAA2D;AACpE,WAAO,KAAK,KAAK,IAAoB,0BAA0B,MAAM;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,MAAqC;AACnD,WAAO,KAAK,KAAK,IAAkB,0BAA0B,mBAAmB,IAAI,CAAC,EAAE;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA8B;AAClC,WAAO,KAAK,KAAK,IAAc,8BAA8B;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,MAAgD;AAClE,WAAO,KAAK,KAAK,IAA4B,qCAAqC,OAAO,EAAE,KAAK,IAAI,MAAS;AAAA,EAC/G;AACF;;;ACxBO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BvC,MAAM,WAAW,QAAsE;AACrF,WAAO,KAAK,KAAK,IAA0C,mBAAmB,MAAM;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,WAAW,QAAuE;AACtF,WAAO,KAAK,KAAK,IAA0C,mBAAmB,MAAM;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,UAAU,QAAyC;AACvD,WAAO,KAAK,KAAK,IAAa,kBAAkB,MAAM;AAAA,EACxD;AACF;;;ACxEO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKvC,MAAM,KAAK,QAAiF;AAC1F,WAAO,KAAK,KAAK,IAA8C,qBAAqB,MAAM;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,QAAyF;AACtG,WAAO,KAAK,KAAK,IAAsD,2BAA2B,MAAM;AAAA,EAC1G;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,QAAyD;AACvE,WAAO,KAAK,KAAK,IAAsB,4BAA4B,MAAM;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,IAAY,SAAiE;AACxF,WAAO,KAAK,KAAK,IAA4B,qBAAqB,EAAE,IAAI,OAAO;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,IAAY,QAA6C;AACpE,WAAO,KAAK,KAAK,OAAa,qBAAqB,EAAE,UAAU,OAAO,KAAK,EAAE;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,SAAiE;AAC3E,WAAO,KAAK,KAAK,KAA6B,2BAA2B,OAAO;AAAA,EAClF;AACF;;;AC5CO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKvC,MAAM,KAAK,QAAwE;AACjF,WAAO,KAAK,KAAK,IAAwC,kBAAkB,MAAM;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,QAAgF;AAC7F,WAAO,KAAK,KAAK,IAAgD,wBAAwB,MAAM;AAAA,EACjG;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,QAAmD;AACjE,WAAO,KAAK,KAAK,IAAmB,yBAAyB,MAAM;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,IAAY,SAA2D;AAClF,WAAO,KAAK,KAAK,IAAyB,kBAAkB,EAAE,IAAI,OAAO;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,IAAY,QAA0C;AACjE,WAAO,KAAK,KAAK,OAAa,kBAAkB,EAAE,UAAU,OAAO,KAAK,EAAE;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,SAA2D;AACrE,WAAO,KAAK,KAAK,KAA0B,wBAAwB,OAAO;AAAA,EAC5E;AACF;;;AC/CO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKvC,MAAM,KAAK,SAAuD;AAChE,WAAO,KAAK,KAAK,KAAwB,uBAAuB,OAAO;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,SAAyD;AACnE,WAAO,KAAK,KAAK,KAAyB,wBAAwB,OAAO;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,SAA2D;AACtE,WAAO,KAAK,KAAK,IAAyB,yBAAyB,OAAO;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,SAA2D;AAC3E,WAAO,KAAK,KAAK,KAA0B,+BAA+B,OAAO;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,SAAmE;AACvF,WAAO,KAAK,KAAK,KAA8B,8BAA8B,OAAO;AAAA,EACtF;AACF;;;AC1BO,IAAM,gBAAN,MAAoB;AAAA,EAczB,YAAY,QAAuB;AAwDnC;AAAA;AAAA;AAAA;AAAA,SAAO,OAAO;AAAA;AAAA;AAAA;AAAA,MAIZ,SAAS,YAA2B;AAClC,cAAM,KAAK,YAAY,aAAa;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAiB,MAAe;AAC9B,eAAO,KAAK,YAAY,gBAAgB;AAAA,MAC1C;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU,MAA0B;AAClC,eAAO,KAAK,YAAY,SAAS;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,QAAQ,MAAY;AAClB,aAAK,YAAY,WAAW;AAAA,MAC9B;AAAA,IACF;AAMA;AAAA;AAAA;AAAA;AAAA,SAAO,SAAS;AAAA;AAAA;AAAA;AAAA,MAId,SAAS,YAA2B;AAClC,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,KAAK,UAAU,QAAQ;AAAA,MAC/B;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,MAAY;AACtB,aAAK,WAAW,WAAW;AAAA,MAC7B;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,MAAe;AAC1B,eAAO,KAAK,WAAW,qBAAqB,KAAK;AAAA,MACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,WAAW,CAAC,aAAuC;AACjD,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,UAAU,QAAQ;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,CAAC,aAAuC;AACnD,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,YAAY,QAAQ;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKA,kBAAkB,MAA0B;AAC1C,eAAO,KAAK,WAAW,sBAAsB,KAAK,CAAC;AAAA,MACrD;AAAA;AAAA;AAAA;AAAA,MAKA,kBAAkB,CAAC,aAAqD;AACtE,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,mBAAmB,QAAQ;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA,MAKA,kBAAkB,CAAC,aAAqD;AACtE,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,mBAAmB,QAAQ;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA,MAKA,mBAAmB,CAAC,aAAqD;AACvE,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,oBAAoB,QAAQ;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA,MAKA,kBAAkB,CAAC,aAAoD;AACrE,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,mBAAmB,QAAQ;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,eAAe,CAAC,aAAmD;AACjE,gBAAQ,KAAK,0EAAgE;AAC7E,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AAEA,aAAK,UAAU,GAAG,oBAAoB,QAAe;AAAA,MACvD;AAAA;AAAA;AAAA;AAAA,MAKA,eAAe,CAAC,aAAmD;AACjE,gBAAQ,KAAK,0FAAgF;AAC7F,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AAEA,aAAK,UAAU,GAAG,mBAAmB,QAAe;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA,MAKA,kBAAkB,CAAC,aAAsD;AACvE,gBAAQ,KAAK,6EAAmE;AAChF,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,oBAAoB,QAAe;AAAA,MACvD;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAiB,CAAC,aAAqD;AACrE,gBAAQ,KAAK,2EAAiE;AAC9E,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,mBAAmB,QAAe;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,CAAC,aAAsC;AAClD,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,aAAa,QAAQ;AAAA,MACzC;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAgB,CAAC,aAAsC;AACrD,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,gBAAgB,QAAQ;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA,MAKA,SAAS,CAAC,aAAsC;AAC9C,YAAI,CAAC,KAAK,WAAW;AACnB,gBAAM,IAAI,eAAe,uBAAuB;AAAA,QAClD;AACA,aAAK,UAAU,GAAG,SAAS,QAAQ;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,CAAC,OAAe,aAAuC;AAC1D,aAAK,WAAW,IAAI,OAAc,QAAQ;AAAA,MAC5C;AAAA,IACF;AA5QE,SAAK,eAAe,MAAM;AAC1B,SAAK,SAAS;AAAA,MACZ,GAAG;AAAA,MACH,aAAa,OAAO,eAAe;AAAA,MACnC,sBAAsB,OAAO,wBAAwB;AAAA,MACrD,UAAU,OAAO,YAAY;AAAA,IAC/B;AACA,SAAK,cAAc,IAAI,YAAY,KAAK,MAAM;AAG9C,SAAK,OAAO,IAAI,WAAW,KAAK,OAAO,QAAQ,KAAK,WAAW;AAG/D,SAAK,WAAW,IAAI,YAAY,KAAK,IAAI;AACzC,SAAK,gBAAgB,IAAI,iBAAiB,KAAK,IAAI;AACnD,SAAK,aAAa,IAAI,cAAc,KAAK,IAAI;AAC7C,SAAK,YAAY,IAAI,aAAa,KAAK,IAAI;AAC3C,SAAK,SAAS,IAAI,UAAU,KAAK,IAAI;AACrC,SAAK,SAAS,IAAI,UAAU,KAAK,IAAI;AAGrC,QAAI,OAAO,WAAW,SAAS;AAC7B,WAAK,YAAY,IAAI,iBAAiB,KAAK,QAAQ,KAAK,WAAW;AAGnE,UAAI,OAAO,UAAU,aAAa;AAChC,aAAK,UAAU,QAAQ,EAAE,MAAM,WAAS;AACtC,kBAAQ,MAAM,qCAAqC,KAAK;AAAA,QAC1D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,QAA6B;AAClD,QAAI,CAAC,OAAO,QAAQ;AAClB,YAAM,IAAI,mBAAmB,oCAAoC;AAAA,IACnE;AAGA,QAAI;AACF,UAAI,IAAI,OAAO,MAAM;AAAA,IACvB,QAAQ;AACN,YAAM,IAAI,mBAAmB,4CAA4C;AAAA,IAC3E;AAAA,EAGF;AAAA;AAAA;AAAA;AAAA,EAgOA,MAAM,OAAqC;AACzC,WAAO,KAAK,KAAK,IAAyB,OAAO;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKO,YAAqC;AAC1C,WAAO,EAAE,GAAG,KAAK,OAAO;AAAA,EAC1B;AACF;;;AC9OO,SAAS,aAAa,QAAsC;AACjE,SAAO,IAAI,cAAc,MAAM;AACjC;AAGA,IAAM,MAAM;AAAA,EACV;AAAA,EACA;AACF;AAEA,IAAO,gBAAQ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types/index.ts","../src/core/auth.ts","../src/core/websocket.ts","../src/api/http-client.ts","../src/api/accounts.ts","../src/api/trading-groups.ts","../src/api/market-data.ts","../src/api/positions.ts","../src/api/orders.ts","../src/api/trades.ts","../src/core/client.ts","../src/index.ts"],"sourcesContent":["import type { WebSocketConfig } from './websocket';\n\n/**\n * Required configuration to initialize the Pipsend client\n */\nexport interface PipsendConfig {\n /** Pipsend server URL (required) */\n server: string;\n /** User credentials for SDK authentication (optional, for future use) */\n login?: string;\n /** User password for SDK authentication (optional, for future use) */\n password?: string;\n /** Timezone for operations (optional, default: UTC) */\n timezone?: string;\n /** Enable auto-refresh of tokens (default: true) */\n autoRefresh?: boolean;\n /** Safety margin for refresh in minutes (default: 5) */\n refreshMarginMinutes?: number;\n /** WebSocket configuration (optional) */\n websocket?: WebSocketConfig;\n}\n\n/**\n * Authentication token information\n */\nexport interface TokenInfo {\n token: string;\n refreshToken?: string;\n expiresAt: Date;\n issuedAt: Date;\n}\n\n/**\n * Trading order data\n */\nexport interface OrderData {\n symbol: string;\n volume: number;\n type?: 'buy' | 'sell';\n price?: number;\n stopLoss?: number;\n takeProfit?: number;\n}\n\n/**\n * Server authentication response from /api/v1/auth/login\n */\nexport interface AuthResponse {\n access_token: string;\n refresh_token: string;\n expires_in: number; // seconds (10800 = 180 minutes)\n token_type: string; // \"Bearer\"\n user: {\n login: number;\n email: string;\n first_name: string;\n last_name: string;\n balance: number;\n };\n logged_with: string; // \"master\" | \"investor\"\n}\n\n/**\n * Server refresh token response from /api/v1/auth/refresh\n */\nexport interface RefreshTokenResponse {\n access_token: string;\n expires_in: number;\n token_type: string;\n}\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\n/**\n * Custom SDK errors\n */\nexport class PipsendError extends Error {\n public errors?: ValidationError[];\n public response?: any;\n\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n errors?: ValidationError[],\n response?: any\n ) {\n super(message);\n this.name = 'PipsendError';\n this.errors = errors;\n this.response = response;\n }\n\n /**\n * Get formatted error message with validation details\n */\n getDetailedMessage(): string {\n if (!this.errors || this.errors.length === 0) {\n return this.message;\n }\n\n const errorDetails = this.errors\n .map(err => ` - ${err.field}: ${err.message}`)\n .join('\\n');\n\n return `${this.message}\\n${errorDetails}`;\n }\n\n /**\n * Check if this is a validation error\n */\n isValidationError(): boolean {\n return this.statusCode === 422 || this.code === 'VALIDATION_ERROR';\n }\n}\n\nexport class AuthenticationError extends PipsendError {\n constructor(message: string) {\n super(message, 'AUTH_ERROR', 401);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ConfigurationError extends PipsendError {\n constructor(message: string) {\n super(message, 'CONFIG_ERROR');\n this.name = 'ConfigurationError';\n }\n}\n\nexport class WebSocketError extends PipsendError {\n constructor(message: string) {\n super(message, 'WEBSOCKET_ERROR');\n this.name = 'WebSocketError';\n }\n}\n\n// Re-export WebSocket types\nexport type {\n WebSocketConfig,\n WebSocketMessage,\n WebSocketChannel,\n WebSocketOperation,\n PositionEventType,\n ConnectedMessage,\n SubscriptionSuccessMessage,\n UnsubscriptionSuccessMessage,\n ErrorMessage,\n PositionData,\n PositionEvent,\n BalanceEvent,\n SubscribeAction,\n UnsubscribeAction,\n WebSocketEventType,\n WebSocketCallback,\n // Legacy types (deprecated)\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate\n} from './websocket';\n\n// Re-export common types\nexport type {\n PaginationParams,\n PaginatedResponse\n} from './common';\n\n// Re-export all API types\nexport type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatus,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse,\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './api';\n","import type { PipsendConfig, TokenInfo, AuthResponse, RefreshTokenResponse } from '../types';\nimport { AuthenticationError } from '../types';\n\n/**\n * Authentication manager with auto-refresh tokens\n */\nexport class AuthManager {\n private tokenInfo?: TokenInfo;\n private refreshMarginMs: number;\n\n constructor(\n private config: PipsendConfig\n ) {\n const marginMinutes = config.refreshMarginMinutes ?? 5;\n this.refreshMarginMs = marginMinutes * 60 * 1000;\n }\n\n /**\n * Checks if a valid token is available\n */\n public isAuthenticated(): boolean {\n return !!this.tokenInfo && !this.isTokenExpired();\n }\n\n /**\n * Gets the current token (if it exists and is valid)\n */\n public getToken(): string | undefined {\n if (this.isAuthenticated()) {\n return this.tokenInfo?.token;\n }\n return undefined;\n }\n\n /**\n * Ensures a valid token exists, authenticating if necessary\n */\n public async ensureAuthenticated(): Promise<string> {\n if (!this.isAuthenticated()) {\n await this.authenticate();\n }\n return this.tokenInfo!.token;\n }\n\n /**\n * Performs authentication with the server\n */\n private async authenticate(): Promise<void> {\n if (!this.config.login || !this.config.password) {\n throw new AuthenticationError(\n 'Login and password are required for authentication. Please provide them in the config.'\n );\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n login: this.config.login,\n password: this.config.password\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as any;\n throw new AuthenticationError(\n errorData.message || `Authentication failed: ${response.status} ${response.statusText}`\n );\n }\n\n const data = await response.json() as AuthResponse;\n this.setTokenInfo(data);\n\n console.log('✅ Authentication successful');\n console.log(` User: ${data.user.first_name} ${data.user.last_name} (${data.user.email})`);\n console.log(` Login: ${data.user.login}`);\n console.log(` Balance: $${data.user.balance.toFixed(2)}`);\n console.log(` Logged with: ${data.logged_with}`);\n } catch (error) {\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(\n `Authentication error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Refreshes the access token using the refresh token\n */\n public async refreshToken(): Promise<void> {\n if (!this.tokenInfo?.refreshToken) {\n console.log('⚠️ No refresh token available, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n try {\n const response = await fetch(`${this.config.server}/api/v1/auth/refresh`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n refresh_token: this.tokenInfo.refreshToken\n })\n });\n\n if (!response.ok) {\n console.log('⚠️ Refresh token failed, performing full authentication');\n this.tokenInfo = undefined;\n await this.authenticate();\n return;\n }\n\n const data = await response.json() as RefreshTokenResponse;\n \n // Update token info, keeping the same refresh token\n const now = new Date();\n const expiresAt = new Date(now.getTime() + data.expires_in * 1000);\n\n this.tokenInfo = {\n token: data.access_token,\n refreshToken: this.tokenInfo.refreshToken, // Keep the same refresh token\n issuedAt: now,\n expiresAt\n };\n\n console.log('✅ Token refreshed successfully');\n } catch (error) {\n console.error('❌ Error refreshing token:', error);\n this.tokenInfo = undefined;\n await this.authenticate();\n }\n }\n\n /**\n * Clears the current token\n */\n public clearToken(): void {\n this.tokenInfo = undefined;\n }\n\n /**\n * Checks if the token is expired or about to expire\n */\n private isTokenExpired(): boolean {\n if (!this.tokenInfo) return true;\n\n const now = Date.now();\n const expiryWithMargin = this.tokenInfo.expiresAt.getTime() - this.refreshMarginMs;\n\n return now >= expiryWithMargin;\n }\n\n /**\n * Stores the received token information\n */\n private setTokenInfo(response: AuthResponse): void {\n const now = new Date();\n const expiresAt = new Date(now.getTime() + response.expires_in * 1000);\n\n this.tokenInfo = {\n token: response.access_token,\n refreshToken: response.refresh_token,\n issuedAt: now,\n expiresAt\n };\n }\n}\n","import type { \n PipsendConfig, \n WebSocketMessage, \n WebSocketEventType,\n WebSocketCallback,\n WebSocketChannel,\n SubscribeAction,\n UnsubscribeAction,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport { WebSocketError } from '../types';\nimport { AuthManager } from './auth';\n\n/**\n * WebSocket manager for real-time updates\n * Handles connection, reconnection, subscriptions, and event dispatching\n */\nexport class WebSocketManager {\n private ws?: any; // WebSocket instance (browser or ws package)\n private reconnectAttempts = 0;\n private heartbeatTimer?: NodeJS.Timeout;\n private listeners = new Map<string, Set<WebSocketCallback>>();\n private isConnected = false;\n private subscribedChannels: WebSocketChannel[] = [];\n private isReconnecting = false;\n\n constructor(\n private config: PipsendConfig,\n private authManager: AuthManager\n ) {}\n\n /**\n * Connects to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.isConnected) {\n console.log('⚠️ WebSocket already connected');\n return;\n }\n\n if (this.isReconnecting) {\n console.log('⚠️ WebSocket reconnection in progress');\n return;\n }\n\n // Get token first\n const token = await this.authManager.ensureAuthenticated();\n \n // Build WebSocket URL with token as query parameter\n const baseWsUrl = this.buildWebSocketUrl();\n const wsUrl = `${baseWsUrl}${baseWsUrl.includes('?') ? '&' : '?'}token=${encodeURIComponent(token)}`;\n\n return new Promise((resolve, reject) => {\n try {\n const WS = this.getWebSocketConstructor();\n this.ws = new WS(wsUrl);\n\n this.ws.onopen = () => {\n console.log('✅ WebSocket connected');\n this.isConnected = true;\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n\n // Emit connected event\n this.emit('connected', { timestamp: Date.now() });\n\n // Resubscribe to channels if reconnecting\n if (this.subscribedChannels.length > 0) {\n console.log('🔄 Resubscribing to channels:', this.subscribedChannels);\n this.subscribe(this.subscribedChannels);\n }\n\n // Start heartbeat\n this.startHeartbeat();\n\n resolve();\n };\n\n this.ws.onmessage = (event: any) => {\n try {\n const data = JSON.parse(event.data);\n this.handleMessage(data);\n } catch (error) {\n console.error('❌ Failed to parse WebSocket message:', error);\n }\n };\n\n this.ws.onerror = (error: any) => {\n console.error('❌ WebSocket error:', error);\n this.emit('error', error);\n \n if (!this.isConnected) {\n reject(new WebSocketError('Failed to connect to WebSocket server'));\n }\n };\n\n this.ws.onclose = (event: any) => {\n console.log('WebSocket disconnected', event.code, event.reason);\n this.isConnected = false;\n this.stopHeartbeat();\n this.emit('disconnected', { \n code: event.code, \n reason: event.reason,\n timestamp: Date.now()\n });\n this.handleReconnect();\n };\n\n } catch (error) {\n reject(new WebSocketError(\n `Failed to create WebSocket: ${error instanceof Error ? error.message : 'Unknown error'}`\n ));\n }\n });\n }\n\n /**\n * Subscribes to WebSocket channels\n */\n subscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n throw new WebSocketError('WebSocket not connected. Call connect() first.');\n }\n\n // Add to subscribed channels (avoid duplicates)\n this.subscribedChannels = [...new Set([...this.subscribedChannels, ...channels])];\n\n // Send subscription message with correct format\n const message: SubscribeAction = {\n action: 'subscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Subscribed to channels:', channels);\n }\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe(channels: WebSocketChannel[]): void {\n if (!this.isConnected) {\n console.warn('WebSocket not connected, cannot unsubscribe');\n return;\n }\n\n // Remove from subscribed channels\n this.subscribedChannels = this.subscribedChannels.filter(\n ch => !channels.includes(ch)\n );\n\n // Send unsubscription message with correct format\n const message: UnsubscribeAction = {\n action: 'unsubscribe',\n channels\n };\n \n this.sendAction(message);\n console.log('📡 Unsubscribed from channels:', channels);\n }\n\n /**\n * Registers an event listener\n */\n on(event: WebSocketEventType, callback: WebSocketCallback): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(callback);\n }\n\n /**\n * Removes an event listener\n */\n off(event: WebSocketEventType, callback?: WebSocketCallback): void {\n if (!callback) {\n // Remove all listeners for this event\n this.listeners.delete(event);\n } else {\n // Remove specific listener\n this.listeners.get(event)?.delete(callback);\n }\n }\n\n /**\n * Disconnects from WebSocket\n */\n disconnect(): void {\n console.log('👋 Disconnecting WebSocket...');\n this.stopHeartbeat();\n \n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n \n this.isConnected = false;\n this.isReconnecting = false;\n this.subscribedChannels = [];\n this.listeners.clear();\n }\n\n /**\n * Checks if WebSocket is connected\n */\n isWebSocketConnected(): boolean {\n return this.isConnected;\n }\n\n /**\n * Gets list of subscribed channels\n */\n getSubscribedChannels(): WebSocketChannel[] {\n return [...this.subscribedChannels];\n }\n\n // Private methods\n\n /**\n * Builds WebSocket URL from HTTP(S) server URL\n */\n private buildWebSocketUrl(): string {\n try {\n const url = new URL(this.config.server);\n \n // Convert https:// to wss:// or http:// to ws://\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n \n // Add WebSocket path (default to /api/v1/ws for Pipsend API)\n const wsPath = this.config.websocket?.path || '/api/v1/ws';\n url.pathname = wsPath;\n \n return url.toString();\n } catch (error) {\n throw new WebSocketError('Invalid server URL for WebSocket connection');\n }\n }\n\n /**\n * Gets WebSocket constructor (browser or Node.js)\n */\n private getWebSocketConstructor(): any {\n // Browser environment\n if (typeof WebSocket !== 'undefined') {\n return WebSocket;\n }\n \n // Node.js environment - try to load 'ws' package\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require('ws');\n } catch {\n throw new WebSocketError(\n 'WebSocket not available. Install \"ws\" package for Node.js: npm install ws'\n );\n }\n }\n\n /**\n * Sends an action message through WebSocket\n */\n private sendAction(message: SubscribeAction | UnsubscribeAction): void {\n if (!this.ws || !this.isConnected) {\n console.warn('⚠️ WebSocket not ready, message not sent:', message.action);\n return;\n }\n\n try {\n const payload = JSON.stringify(message);\n this.ws.send(payload);\n } catch (error) {\n console.error('❌ Failed to send WebSocket message:', error);\n }\n }\n\n /**\n * Sends a ping message (for heartbeat)\n */\n private sendPing(): void {\n if (!this.ws || !this.isConnected) {\n return;\n }\n\n try {\n this.ws.send(JSON.stringify({ action: 'ping' }));\n } catch (error) {\n console.error('❌ Failed to send ping:', error);\n }\n }\n\n /**\n * Handles incoming WebSocket messages\n */\n private handleMessage(message: WebSocketMessage): void {\n switch (message.op) {\n case 'connected':\n this.handleConnected(message);\n break;\n \n case 'subscription_success':\n this.handleSubscriptionSuccess(message);\n break;\n \n case 'unsubscription_success':\n this.handleUnsubscriptionSuccess(message);\n break;\n \n case 'push':\n this.handlePushEvent(message);\n break;\n \n case 'error':\n this.handleError(message);\n break;\n \n default:\n console.warn(message.op);\n }\n\n // Emit to wildcard listeners (listen to all events)\n this.emit('*', message);\n }\n\n /**\n * Handles connected message from server\n */\n private handleConnected(message: WebSocketMessage): void {\n console.log('✅ WebSocket connected:', message.data.message);\n console.log(' Available channels:', message.data.available_channels);\n this.emit('connected', message.data);\n }\n\n /**\n * Handles subscription success\n */\n private handleSubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Subscription successful:', message.data.subscribed);\n this.emit('subscription_success', message.data);\n }\n\n /**\n * Handles unsubscription success\n */\n private handleUnsubscriptionSuccess(message: WebSocketMessage): void {\n console.log('✅ Unsubscription successful:', message.data.unsubscribed);\n this.emit('unsubscription_success', message.data);\n }\n\n /**\n * Handles push events (actual data events)\n */\n private handlePushEvent(message: WebSocketMessage): void {\n const eventData = message.data;\n const eventType = eventData.type;\n \n switch (eventType) {\n case 'position.opened':\n this.emit('position:opened', eventData as PositionEvent);\n break;\n \n case 'position.closed':\n case 'position.partially_closed':\n this.emit('position:closed', eventData as PositionEvent);\n break;\n \n case 'position.updated':\n this.emit('position:updated', eventData as PositionEvent);\n break;\n \n default:\n // Balance update (doesn't have 'type' field)\n if (message.topic?.startsWith('balance:')) {\n this.emit('balance:updated', eventData as BalanceEvent);\n } else {\n console.warn('Unknown event type:', eventType);\n }\n }\n }\n\n /**\n * Handles error messages from server\n */\n private handleError(message: WebSocketMessage): void {\n console.error('❌ WebSocket error:', message.data.message);\n if (message.data.error) {\n console.error(' Error details:', message.data.error);\n }\n this.emit('error', message.data);\n }\n\n /**\n * Emits an event to all registered listeners\n */\n private emit(event: WebSocketEventType, data: any): void {\n const listeners = this.listeners.get(event);\n if (listeners && listeners.size > 0) {\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`❌ Error in WebSocket listener for \"${event}\":`, error);\n }\n });\n }\n }\n\n /**\n * Handles reconnection logic with exponential backoff\n */\n private handleReconnect(): void {\n const autoReconnect = this.config.websocket?.autoReconnect ?? true;\n const maxAttempts = this.config.websocket?.maxReconnectAttempts ?? 5;\n\n if (!autoReconnect) {\n console.log('Auto-reconnect disabled');\n return;\n }\n\n if (this.reconnectAttempts >= maxAttempts) {\n console.log(`❌ Max reconnection attempts (${maxAttempts}) reached. Giving up.`);\n this.emit('error', new WebSocketError('Max reconnection attempts reached'));\n return;\n }\n\n // Exponential backoff: 1s, 2s, 4s, 8s, 16s, max 30s\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n console.log(\n `🔄 Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts + 1}/${maxAttempts})...`\n );\n\n this.isReconnecting = true;\n\n setTimeout(() => {\n this.reconnectAttempts++;\n this.connect().catch(error => {\n console.error('❌ Reconnection failed:', error);\n });\n }, delay);\n }\n\n /**\n * Starts heartbeat to keep connection alive\n */\n private startHeartbeat(): void {\n const interval = this.config.websocket?.heartbeatInterval || 30000;\n \n this.heartbeatTimer = setInterval(() => {\n if (this.isConnected) {\n this.sendPing();\n }\n }, interval);\n }\n\n /**\n * Stops heartbeat timer\n */\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = undefined;\n }\n }\n}\n","import { PipsendError } from '../types';\nimport type { AuthManager } from '../core/auth';\n\n/**\n * HTTP client for making requests to the Pipsend API\n */\nexport class HttpClient {\n constructor(\n private baseUrl: string,\n private authManager?: AuthManager\n ) {}\n\n /**\n * Makes an HTTP request\n */\n async request<T>(\n endpoint: string,\n options: RequestInit = {},\n retryOn401 = true\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n try {\n // Build headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {})\n };\n\n // Add Authorization header if authManager is available\n if (this.authManager) {\n const token = await this.authManager.ensureAuthenticated();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, {\n ...options,\n headers\n });\n\n // Handle 401 Unauthorized - try to refresh token and retry\n if (response.status === 401 && this.authManager && retryOn401) {\n console.log('⚠️ Received 401, attempting to refresh token...');\n await this.authManager.refreshToken();\n \n // Retry the request with new token (but don't retry again if it fails)\n return this.request<T>(endpoint, options, false);\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = `HTTP ${response.status}: ${errorText || response.statusText}`;\n let errorCode = 'HTTP_ERROR';\n let validationErrors;\n let errorResponse;\n \n // Try to parse error as JSON for better error messages\n try {\n const errorJson = JSON.parse(errorText);\n errorResponse = errorJson;\n \n // Extract message\n if (errorJson.message) {\n errorMessage = errorJson.message;\n }\n \n // Extract error code\n if (errorJson.status_code) {\n errorCode = errorJson.status_code;\n }\n \n // Extract validation errors (422 responses)\n if (errorJson.errors && Array.isArray(errorJson.errors)) {\n validationErrors = errorJson.errors;\n }\n } catch {\n // Keep the original error message if JSON parsing fails\n }\n\n throw new PipsendError(\n errorMessage,\n errorCode,\n response.status,\n validationErrors,\n errorResponse\n );\n }\n\n // Handle empty responses\n const text = await response.text();\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n } catch (error) {\n if (error instanceof PipsendError) {\n throw error;\n }\n throw new PipsendError(\n `Request failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n );\n }\n }\n\n /**\n * GET request\n */\n async get<T>(endpoint: string, params?: Record<string, any>): Promise<T> {\n const queryString = params ? this.buildQueryString(params) : '';\n const url = queryString ? `${endpoint}?${queryString}` : endpoint;\n return this.request<T>(url, { method: 'GET' });\n }\n\n /**\n * POST request\n */\n async post<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * PUT request\n */\n async put<T>(endpoint: string, body?: any): Promise<T> {\n return this.request<T>(endpoint, {\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T>(endpoint: string): Promise<T> {\n return this.request<T>(endpoint, { method: 'DELETE' });\n }\n\n /**\n * Builds query string from params object\n */\n private buildQueryString(params: Record<string, any>): string {\n const filtered = Object.entries(params)\n .filter(([_, value]) => value !== undefined && value !== null && value !== '')\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n \n return filtered.join('&');\n }\n}\n","import type {\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n AccountStatusResponse,\n AdjustBalanceRequest,\n AdjustBalanceResponse,\n ChangePasswordRequest,\n CreateAccountRequest,\n CreateAccountResponse,\n UpdateAccountRequest,\n UpdateAccountResponse\n} from '../types/api/accounts';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Accounts API\n */\nexport class AccountsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a new trading account\n */\n async create(request: CreateAccountRequest): Promise<CreateAccountResponse> {\n return this.http.post<CreateAccountResponse>('/api/v1/accounts', request);\n }\n\n /**\n * List all accounts with optional filters and pagination\n */\n async list(params?: AccountsListParams): Promise<PaginatedResponse<Account> | Account[]> {\n return this.http.get<PaginatedResponse<Account> | Account[]>('/api/v1/accounts', params);\n }\n\n /**\n * Get all account logins\n */\n async getLogins(): Promise<number[]> {\n return this.http.get<number[]>('/api/v1/accounts/logins');\n }\n\n /**\n * Get account status/metrics (balance, equity, credit, margin)\n */\n async getStatus(login: number): Promise<AccountStatusResponse> {\n return this.http.get<AccountStatusResponse>(`/api/v1/accounts/${login}/status`);\n }\n\n /**\n * Get account statistics with optional filters\n */\n async getStatistics(params?: AccountStatisticsParams): Promise<AccountStatistics> {\n return this.http.get<AccountStatistics>('/api/v1/accounts/statistics', params);\n }\n\n /**\n * Change master password for an account\n */\n async changeMasterPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/master`, request);\n }\n\n /**\n * Change investor password for an account\n */\n async changeInvestorPassword(login: number, request: ChangePasswordRequest): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/password/investor`, request);\n }\n\n /**\n * Archive an account\n */\n async archive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/archive`);\n }\n\n /**\n * Unarchive an account\n */\n async unarchive(login: number): Promise<void> {\n return this.http.put<void>(`/api/v1/accounts/${login}/unarchive`);\n }\n\n /**\n * Update account information (partial update)\n * All fields are optional, only send the ones you want to update\n */\n async update(login: number, request: UpdateAccountRequest): Promise<UpdateAccountResponse> {\n return this.http.put<UpdateAccountResponse>(`/api/v1/accounts/${login}`, request);\n }\n\n /**\n * Adjust balance or credit for an account\n * The adjustment is relative: amount is added or subtracted from current value\n */\n async balance(login: number, request: AdjustBalanceRequest): Promise<AdjustBalanceResponse> {\n return this.http.put<AdjustBalanceResponse>(`/api/v1/accounts/${login}/adjust`, request);\n }\n}\n","import type {\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics\n} from '../types/api/trading-groups';\nimport { HttpClient } from './http-client';\n\n/**\n * Trading Groups API\n */\nexport class TradingGroupsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List all trading groups with optional filters\n */\n async list(params?: TradingGroupsListParams): Promise<TradingGroup[]> {\n return this.http.get<TradingGroup[]>('/api/v1/trading-groups', params);\n }\n\n /**\n * Get trading group by name\n */\n async getByName(name: string): Promise<TradingGroup> {\n return this.http.get<TradingGroup>(`/api/v1/trading-groups/${encodeURIComponent(name)}`);\n }\n\n /**\n * Get all trading group names\n */\n async getNames(): Promise<string[]> {\n return this.http.get<string[]>('/api/v1/trading-groups/names');\n }\n\n /**\n * Get trading group statistics\n */\n async getStatistics(type?: string): Promise<TradingGroupStatistics> {\n return this.http.get<TradingGroupStatistics>('/api/v1/trading-groups/statistics', type ? { type } : undefined);\n }\n}\n","import type {\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams\n} from '../types/api/market-data';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Market Data API\n * \n * Note: All data has a minimum age of 1 hour (no real-time data)\n */\nexport class MarketDataAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Get historical OHLCV candles\n * \n * @param params - Candles parameters (symbol and timeframe are required)\n * @returns Paginated candles or array of candles\n * \n * @example\n * ```ts\n * // Get last 100 candles\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD',\n * timeframe: '1m',\n * limit: 100,\n * order: 'desc'\n * });\n * \n * // Get candles with time range\n * const candles = await client.marketData.getCandles({\n * symbol: 'BTCUSD,ETHUSD',\n * timeframe: '1h',\n * from: '2025-11-01T00:00:00Z',\n * to: '2025-11-02T00:00:00Z'\n * });\n * ```\n */\n async getCandles(params: CandlesParams): Promise<PaginatedResponse<Candle> | Candle[]> {\n return this.http.get<PaginatedResponse<Candle> | Candle[]>('/api/v1/candles', params);\n }\n\n /**\n * Get available symbols with metadata\n * \n * @param params - Optional filters for symbols\n * @returns Paginated symbols or array of symbols\n * \n * @example\n * ```ts\n * // Get all symbols\n * const symbols = await client.marketData.getSymbols();\n * \n * // Filter by group\n * const cryptoSymbols = await client.marketData.getSymbols({\n * group: 'CRYPTO_MAJOR',\n * has_data: true\n * });\n * ```\n */\n async getSymbols(params?: SymbolsParams): Promise<PaginatedResponse<Symbol> | Symbol[]> {\n return this.http.get<PaginatedResponse<Symbol> | Symbol[]>('/api/v1/symbols', params);\n }\n\n /**\n * Get symbol groups hierarchy\n * \n * Note: This endpoint never uses pagination\n * \n * @param params - Optional filters for groups\n * @returns Array of groups\n * \n * @example\n * ```ts\n * // Get all groups\n * const groups = await client.marketData.getGroups();\n * \n * // Get only root groups\n * const rootGroups = await client.marketData.getGroups({\n * root_only: true\n * });\n * ```\n */\n async getGroups(params?: GroupsParams): Promise<Group[]> {\n return this.http.get<Group[]>('/api/v1/groups', params);\n }\n}\n","import type {\n Position,\n PositionsListParams,\n PositionStatistics,\n PositionStatisticsGrouped,\n PositionStatsParams,\n PositionTotals,\n PositionTotalsParams,\n UpdatePositionRequest,\n UpdatePositionResponse,\n DeletePositionParams,\n CheckPositionsRequest,\n CheckPositionsResponse\n} from '../types/api/positions';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Positions API\n */\nexport class PositionsAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List positions with optional filters and pagination\n */\n async list(params?: PositionsListParams): Promise<PaginatedResponse<Position> | Position[]> {\n return this.http.get<PaginatedResponse<Position> | Position[]>('/api/v1/positions', params);\n }\n\n /**\n * Get position statistics with optional filters and grouping\n */\n async getStats(params?: PositionStatsParams): Promise<PositionStatistics | PositionStatisticsGrouped[]> {\n return this.http.get<PositionStatistics | PositionStatisticsGrouped[]>('/api/v1/positions/stats', params);\n }\n\n /**\n * Get position totals with dynamic grouping\n */\n async getTotals(params: PositionTotalsParams): Promise<PositionTotals[]> {\n return this.http.get<PositionTotals[]>('/api/v1/positions/totals', params);\n }\n\n /**\n * Update position (modify SL/TP)\n */\n async update(id: number, request: UpdatePositionRequest): Promise<UpdatePositionResponse> {\n return this.http.put<UpdatePositionResponse>(`/api/v1/positions/${id}`, request);\n }\n\n /**\n * Delete (close) position\n */\n async delete(id: number, params: DeletePositionParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/positions/${id}?login=${params.login}`);\n }\n\n /**\n * Check and recalculate positions\n */\n async check(request: CheckPositionsRequest): Promise<CheckPositionsResponse> {\n return this.http.post<CheckPositionsResponse>('/api/v1/positions/check', request);\n }\n}\n","import type {\n Order,\n OrdersListParams,\n OrderStatistics,\n OrderStatisticsGrouped,\n OrderStatsParams,\n OrderTotals,\n OrderTotalsParams,\n UpdateOrderRequest,\n UpdateOrderResponse,\n DeleteOrderParams,\n CheckOrdersRequest,\n CheckOrdersResponse\n} from '../types/api/orders';\nimport type { PaginatedResponse } from '../types/common';\nimport { HttpClient } from './http-client';\n\n/**\n * Orders API\n */\nexport class OrdersAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * List orders with optional filters and pagination\n */\n async list(params?: OrdersListParams): Promise<PaginatedResponse<Order> | Order[]> {\n return this.http.get<PaginatedResponse<Order> | Order[]>('/api/v1/orders', params);\n }\n\n /**\n * Get order statistics with optional filters and grouping\n */\n async getStats(params?: OrderStatsParams): Promise<OrderStatistics | OrderStatisticsGrouped[]> {\n return this.http.get<OrderStatistics | OrderStatisticsGrouped[]>('/api/v1/orders/stats', params);\n }\n\n /**\n * Get order totals with dynamic grouping\n */\n async getTotals(params: OrderTotalsParams): Promise<OrderTotals[]> {\n return this.http.get<OrderTotals[]>('/api/v1/orders/totals', params);\n }\n\n /**\n * Update order (modify SL/TP)\n */\n async update(id: number, request: UpdateOrderRequest): Promise<UpdateOrderResponse> {\n return this.http.put<UpdateOrderResponse>(`/api/v1/orders/${id}`, request);\n }\n\n /**\n * Delete (cancel) order\n */\n async delete(id: number, params: DeleteOrderParams): Promise<void> {\n return this.http.delete<void>(`/api/v1/orders/${id}?login=${params.login}`);\n }\n\n /**\n * Check and validate pending orders\n */\n async check(request: CheckOrdersRequest): Promise<CheckOrdersResponse> {\n return this.http.post<CheckOrdersResponse>('/api/v1/orders/check', request);\n }\n}\n","import type {\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse\n} from '../types/api/trades';\nimport { HttpClient } from './http-client';\n\n/**\n * Trades API\n */\nexport class TradesAPI {\n constructor(private http: HttpClient) {}\n\n /**\n * Open a new trade (market or pending order)\n */\n async open(request: OpenTradeRequest): Promise<OpenTradeResponse> {\n return this.http.post<OpenTradeResponse>('/api/v1/trades/open', request);\n }\n\n /**\n * Close a trade (full or partial)\n */\n async close(request: CloseTradeRequest): Promise<CloseTradeResponse> {\n return this.http.post<CloseTradeResponse>('/api/v1/trades/close', request);\n }\n\n /**\n * Modify trade Stop Loss and/or Take Profit\n */\n async modify(request: ModifyTradeRequest): Promise<ModifyTradeResponse> {\n return this.http.put<ModifyTradeResponse>('/api/v1/trades/modify', request);\n }\n\n /**\n * Check if there's sufficient margin for a trade\n */\n async checkMargin(request: CheckMarginRequest): Promise<CheckMarginResponse> {\n return this.http.post<CheckMarginResponse>('/api/v1/trades/check-margin', request);\n }\n\n /**\n * Calculate potential profit for a trade\n */\n async calculateProfit(request: CalculateProfitRequest): Promise<CalculateProfitResponse> {\n return this.http.post<CalculateProfitResponse>('/api/v1/trades/calc-profit', request);\n }\n}\n","import type { \n PipsendConfig,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketCallback,\n WebSocketChannel,\n PositionEvent,\n BalanceEvent\n} from '../types';\nimport type { HealthCheckResponse } from '../types/api/health';\nimport { ConfigurationError, WebSocketError } from '../types';\nimport { AuthManager } from './auth';\nimport { WebSocketManager } from './websocket';\nimport { \n HttpClient,\n AccountsAPI,\n TradingGroupsAPI,\n MarketDataAPI,\n PositionsAPI,\n OrdersAPI,\n TradesAPI\n} from '../api';\n\n/**\n * Main Pipsend SDK client\n */\nexport class PipsendClient {\n private authManager: AuthManager;\n private wsManager?: WebSocketManager;\n private config: PipsendConfig;\n private http: HttpClient;\n\n // API modules\n public readonly accounts: AccountsAPI;\n public readonly tradingGroups: TradingGroupsAPI;\n public readonly marketData: MarketDataAPI;\n public readonly positions: PositionsAPI;\n public readonly orders: OrdersAPI;\n public readonly trades: TradesAPI;\n\n constructor(config: PipsendConfig) {\n this.validateConfig(config);\n this.config = {\n ...config,\n autoRefresh: config.autoRefresh ?? true,\n refreshMarginMinutes: config.refreshMarginMinutes ?? 5,\n timezone: config.timezone ?? 'UTC'\n };\n this.authManager = new AuthManager(this.config);\n\n // Initialize HTTP client with auth manager\n this.http = new HttpClient(this.config.server, this.authManager);\n\n // Initialize API modules\n this.accounts = new AccountsAPI(this.http);\n this.tradingGroups = new TradingGroupsAPI(this.http);\n this.marketData = new MarketDataAPI(this.http);\n this.positions = new PositionsAPI(this.http);\n this.orders = new OrdersAPI(this.http);\n this.trades = new TradesAPI(this.http);\n\n // Initialize WebSocket if enabled\n if (config.websocket?.enabled) {\n this.wsManager = new WebSocketManager(this.config, this.authManager);\n \n // Auto-connect if configured\n if (config.websocket.autoConnect) {\n this.wsManager.connect().catch(error => {\n console.error('Failed to auto-connect WebSocket:', error);\n });\n }\n }\n }\n\n /**\n * Validates the initial configuration\n */\n private validateConfig(config: PipsendConfig): void {\n if (!config.server) {\n throw new ConfigurationError('The \"server\" parameter is required');\n }\n\n // Validate URL format\n try {\n new URL(config.server);\n } catch {\n throw new ConfigurationError('The \"server\" parameter must be a valid URL');\n }\n\n // Note: login and password are optional for now (will be required when auth is implemented)\n }\n\n /**\n * Authentication API\n * TODO: Implement when authentication is available\n */\n public auth = {\n /**\n * Forces a token refresh\n */\n refresh: async (): Promise<void> => {\n await this.authManager.refreshToken();\n },\n\n /**\n * Checks if the client is authenticated\n */\n isAuthenticated: (): boolean => {\n return this.authManager.isAuthenticated();\n },\n\n /**\n * Gets the current token (if it exists)\n */\n getToken: (): string | undefined => {\n return this.authManager.getToken();\n },\n\n /**\n * Logs out by clearing the token\n */\n logout: (): void => {\n this.authManager.clearToken();\n }\n };\n\n /**\n * WebSocket streaming API\n * Provides real-time updates for prices, orders, positions, etc.\n */\n public stream = {\n /**\n * Connects to WebSocket server\n */\n connect: async (): Promise<void> => {\n if (!this.wsManager) {\n throw new WebSocketError(\n 'WebSocket not enabled. Set websocket.enabled: true in config'\n );\n }\n await this.wsManager.connect();\n },\n\n /**\n * Disconnects from WebSocket server\n */\n disconnect: (): void => {\n this.wsManager?.disconnect();\n },\n\n /**\n * Checks if WebSocket is connected\n */\n isConnected: (): boolean => {\n return this.wsManager?.isWebSocketConnected() ?? false;\n },\n\n /**\n * Subscribes to WebSocket channels\n * @example\n * client.stream.subscribe(['positions:new', 'positions:closed']);\n */\n subscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.subscribe(channels);\n },\n\n /**\n * Unsubscribes from WebSocket channels\n */\n unsubscribe: (channels: WebSocketChannel[]): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.unsubscribe(channels);\n },\n\n /**\n * Gets list of subscribed channels\n */\n getSubscriptions: (): WebSocketChannel[] => {\n return this.wsManager?.getSubscribedChannels() ?? [];\n },\n\n /**\n * Listens to position opened events\n */\n onPositionOpened: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:opened', callback);\n },\n\n /**\n * Listens to position closed events (includes partial closes)\n */\n onPositionClosed: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:closed', callback);\n },\n\n /**\n * Listens to position updated events (throttled to max 1 per 2 seconds)\n */\n onPositionUpdated: (callback: WebSocketCallback<PositionEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback);\n },\n\n /**\n * Listens to balance updated events\n */\n onBalanceUpdated: (callback: WebSocketCallback<BalanceEvent>): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback);\n },\n\n // Legacy methods (deprecated but kept for compatibility)\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPriceUpdate: (callback: WebSocketCallback<PriceUpdate>): void => {\n console.warn('⚠️ onPriceUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new event for backward compatibility\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onPositionOpened/onPositionClosed instead\n */\n onOrderUpdate: (callback: WebSocketCallback<OrderUpdate>): void => {\n console.warn('⚠️ onOrderUpdate is deprecated. Use onPositionOpened/onPositionClosed instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n // Map to new events for backward compatibility\n this.wsManager.on('position:opened', callback as any);\n },\n\n /**\n * @deprecated Use onPositionUpdated instead\n */\n onPositionUpdate: (callback: WebSocketCallback<PositionUpdate>): void => {\n console.warn('⚠️ onPositionUpdate is deprecated. Use onPositionUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('position:updated', callback as any);\n },\n\n /**\n * @deprecated Use onBalanceUpdated instead\n */\n onBalanceUpdate: (callback: WebSocketCallback<BalanceUpdate>): void => {\n console.warn('⚠️ onBalanceUpdate is deprecated. Use onBalanceUpdated instead.');\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('balance:updated', callback as any);\n },\n\n /**\n * Listens to connection events\n */\n onConnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('connected', callback);\n },\n\n /**\n * Listens to disconnection events\n */\n onDisconnected: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('disconnected', callback);\n },\n\n /**\n * Listens to error events\n */\n onError: (callback: WebSocketCallback): void => {\n if (!this.wsManager) {\n throw new WebSocketError('WebSocket not enabled');\n }\n this.wsManager.on('error', callback);\n },\n\n /**\n * Removes event listener\n */\n off: (event: string, callback?: WebSocketCallback): void => {\n this.wsManager?.off(event as any, callback);\n }\n };\n\n /**\n * Health check\n */\n async ping(): Promise<HealthCheckResponse> {\n return this.http.get<HealthCheckResponse>('/ping');\n }\n\n /**\n * Client information\n */\n public getConfig(): Readonly<PipsendConfig> {\n return { ...this.config };\n }\n}\n","// Export types\nexport type {\n PipsendConfig,\n TokenInfo,\n OrderData,\n AuthResponse,\n WebSocketConfig,\n WebSocketMessage,\n PriceUpdate,\n OrderUpdate,\n PositionUpdate,\n BalanceUpdate,\n WebSocketEventType,\n WebSocketCallback,\n // API types\n PaginationParams,\n PaginatedResponse,\n Account,\n AccountsListParams,\n AccountStatistics,\n AccountStatisticsParams,\n ChangePasswordRequest,\n TradingGroup,\n TradingGroupsListParams,\n TradingGroupStatistics,\n Candle,\n CandlesParams,\n Symbol,\n SymbolsParams,\n Group,\n GroupsParams,\n Position,\n PositionsListParams,\n PositionStatistics,\n UpdatePositionRequest,\n Order,\n OrdersListParams,\n OrderStatistics,\n UpdateOrderRequest,\n OpenTradeRequest,\n OpenTradeResponse,\n CloseTradeRequest,\n CloseTradeResponse,\n ModifyTradeRequest,\n ModifyTradeResponse,\n CheckMarginRequest,\n CheckMarginResponse,\n CalculateProfitRequest,\n CalculateProfitResponse,\n HealthCheckResponse\n} from './types';\n\n// Export errors\nexport {\n PipsendError,\n AuthenticationError,\n ConfigurationError,\n WebSocketError\n} from './types';\n\n// Export client\nexport { PipsendClient } from './core/client';\n\n// Export creation function (main API)\nimport { PipsendClient } from './core/client';\nimport type { PipsendConfig } from './types';\n\n/**\n * Creates a new instance of the Pipsend client\n *\n * @example\n * ```typescript\n * import { createClient } from '@pipsend/sdk';\n *\n * const client = createClient({\n * server: 'https://api.pipsend.com',\n * login: 'your-username',\n * password: 'your-password',\n * timezone: 'America/New_York' // optional\n * });\n *\n * // The SDK handles authentication automatically\n * await client.orders.send({\n * symbol: 'EURUSD',\n * volume: 0.1\n * });\n * ```\n */\nexport function createClient(config: PipsendConfig): PipsendClient {\n return new PipsendClient(config);\n}\n\n// Export default for compatibility\nconst sdk = {\n createClient,\n PipsendClient\n};\n\nexport default sdk;\n"],"mappings":"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","names":[]}
|