@pipsend/sdk 0.1.0 → 0.1.1

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.d.mts CHANGED
@@ -16,15 +16,86 @@ interface WebSocketConfig {
16
16
  heartbeatInterval?: number;
17
17
  }
18
18
  /**
19
- * WebSocket message structure
19
+ * Available WebSocket channels for subscription
20
+ */
21
+ type WebSocketChannel = 'positions:new' | 'positions:closed' | 'positions:updated' | 'accounts:balance';
22
+ /**
23
+ * WebSocket operation types from server
24
+ */
25
+ type WebSocketOperation = 'connected' | 'subscription_success' | 'unsubscription_success' | 'push' | 'error';
26
+ /**
27
+ * Position event types
28
+ */
29
+ type PositionEventType = 'position.opened' | 'position.closed' | 'position.partially_closed' | 'position.updated';
30
+ /**
31
+ * WebSocket message structure from server
20
32
  */
21
33
  interface WebSocketMessage {
22
- type: string;
23
- payload?: any;
24
- timestamp?: number;
34
+ op: WebSocketOperation;
35
+ topic?: string;
36
+ data: any;
37
+ }
38
+ /**
39
+ * Position data structure
40
+ */
41
+ interface PositionData {
42
+ position_id: string;
43
+ symbol: string;
44
+ symbol_name?: string;
45
+ status: 'open' | 'closed';
46
+ side: 1 | -1;
47
+ qty: number;
48
+ entry_avg: number;
49
+ exit_avg?: number;
50
+ current_price?: number;
51
+ unrealized_pnl?: number;
52
+ unrealized_pnl_pct?: number;
53
+ net_pnl?: number;
54
+ net_pnl_pct?: number;
55
+ sl?: number;
56
+ tp?: number;
57
+ contract_size?: number;
58
+ point_value?: number;
59
+ account_ccy?: string;
60
+ fees_accrued?: number;
61
+ financing_accrued?: number;
62
+ close_reason?: string;
63
+ close_comment?: string;
64
+ opened_at: number;
65
+ updated_at: number;
66
+ version: number;
67
+ }
68
+ /**
69
+ * Position event structure
70
+ */
71
+ interface PositionEvent {
72
+ type: PositionEventType;
73
+ ts: number;
74
+ account_id: string;
75
+ position: PositionData;
76
+ diff?: {
77
+ previous_qty: string;
78
+ new_qty: string;
79
+ };
25
80
  }
26
81
  /**
27
- * Real-time price update
82
+ * Balance update event
83
+ */
84
+ interface BalanceEvent {
85
+ account_id: string;
86
+ balance: number;
87
+ equity: number;
88
+ margin: number;
89
+ free_margin: number;
90
+ margin_level: number;
91
+ timestamp: number;
92
+ }
93
+ /**
94
+ * WebSocket event types (internal)
95
+ */
96
+ type WebSocketEventType = 'position:opened' | 'position:closed' | 'position:updated' | 'balance:updated' | 'connected' | 'disconnected' | 'error' | 'subscription_success' | 'unsubscription_success' | '*';
97
+ /**
98
+ * @deprecated Use PositionEvent instead
28
99
  */
29
100
  interface PriceUpdate {
30
101
  symbol: string;
@@ -34,7 +105,7 @@ interface PriceUpdate {
34
105
  timestamp: number;
35
106
  }
36
107
  /**
37
- * Real-time order update
108
+ * @deprecated Use PositionEvent instead
38
109
  */
39
110
  interface OrderUpdate {
40
111
  orderId: string;
@@ -49,7 +120,7 @@ interface OrderUpdate {
49
120
  timestamp: number;
50
121
  }
51
122
  /**
52
- * Real-time position update
123
+ * @deprecated Use PositionEvent instead
53
124
  */
54
125
  interface PositionUpdate {
55
126
  positionId: string;
@@ -63,7 +134,7 @@ interface PositionUpdate {
63
134
  timestamp: number;
64
135
  }
65
136
  /**
66
- * Account balance update
137
+ * @deprecated Use BalanceEvent instead
67
138
  */
68
139
  interface BalanceUpdate {
69
140
  balance: number;
@@ -73,10 +144,6 @@ interface BalanceUpdate {
73
144
  marginLevel: number;
74
145
  timestamp: number;
75
146
  }
76
- /**
77
- * WebSocket event types
78
- */
79
- type WebSocketEventType = 'price' | 'order' | 'position' | 'balance' | 'connected' | 'disconnected' | 'error' | 'authenticated' | '*';
80
147
  /**
81
148
  * WebSocket event callback
82
149
  */
@@ -174,6 +241,134 @@ interface AccountStatisticsParams {
174
241
  interface ChangePasswordRequest {
175
242
  new_password: string;
176
243
  }
244
+ /**
245
+ * Create account request
246
+ */
247
+ interface CreateAccountRequest {
248
+ /** Trading group name or path (e.g., "Premium" or "Standard/VIP") */
249
+ trading_group: string;
250
+ /** Country code or name (e.g., "MX", "Mexico", "US") */
251
+ country: string;
252
+ /** Master password (minimum 8 characters) */
253
+ master_password: string;
254
+ /** Investor password (minimum 8 characters) */
255
+ investor_password: string;
256
+ /** Valid email address */
257
+ email: string;
258
+ /** First name */
259
+ first_name: string;
260
+ /** Last name */
261
+ last_name: string;
262
+ /** Specific login (auto-generated if not provided) */
263
+ login?: number;
264
+ /** Middle name */
265
+ middle_name?: string;
266
+ /** Company name */
267
+ company?: string;
268
+ /** Phone number */
269
+ phone?: string;
270
+ /** City */
271
+ city?: string;
272
+ /** Address */
273
+ address?: string;
274
+ /** Zip code */
275
+ zip_code?: string;
276
+ /** Phone password */
277
+ phone_password?: string;
278
+ /** Leverage (uses group default if not specified) */
279
+ leverage?: number;
280
+ /** Account state: "active" or "inactive" (default: "active") */
281
+ state?: 'active' | 'inactive';
282
+ }
283
+ /**
284
+ * Create account response
285
+ */
286
+ interface CreateAccountResponse {
287
+ status: 'success';
288
+ status_code: 'CREATED';
289
+ data: Account;
290
+ }
291
+ /**
292
+ * Update account request (all fields are optional)
293
+ */
294
+ interface UpdateAccountRequest {
295
+ /** Trading group name or path (e.g., "Premium" or "Standard/VIP") */
296
+ trading_group?: string;
297
+ /** Country code or name (e.g., "MX", "Mexico", "US") */
298
+ country?: string;
299
+ /** Valid email address */
300
+ email?: string;
301
+ /** First name */
302
+ first_name?: string;
303
+ /** Last name */
304
+ last_name?: string;
305
+ /** Middle name */
306
+ middle_name?: string;
307
+ /** Company name */
308
+ company?: string;
309
+ /** Phone number */
310
+ phone?: string;
311
+ /** City */
312
+ city?: string;
313
+ /** Address */
314
+ address?: string;
315
+ /** Zip code */
316
+ zip_code?: string;
317
+ /** Leverage */
318
+ leverage?: number;
319
+ /** Account state: "active" or "inactive" */
320
+ state?: 'active' | 'inactive';
321
+ }
322
+ /**
323
+ * Update account response
324
+ */
325
+ interface UpdateAccountResponse {
326
+ status: 'success';
327
+ status_code: 'SUCCESS';
328
+ data: Account;
329
+ }
330
+ /**
331
+ * Adjust balance or credit request
332
+ */
333
+ interface AdjustBalanceRequest {
334
+ /** Type of adjustment: "balance" or "credit" */
335
+ type: 'balance' | 'credit';
336
+ /** Amount to adjust (positive = add, negative = subtract) */
337
+ amount: number;
338
+ /** Descriptive comment (max 255 characters) */
339
+ comment?: string;
340
+ }
341
+ /**
342
+ * Adjust balance or credit response
343
+ */
344
+ interface AdjustBalanceResponse {
345
+ status: 'success';
346
+ status_code: 'SUCCESS';
347
+ data: Account;
348
+ }
349
+ /**
350
+ * Account status/metrics
351
+ */
352
+ interface AccountStatus {
353
+ /** Account login */
354
+ login: number;
355
+ /** Effective balance (balance + credit) */
356
+ balance: number;
357
+ /** Equity (balance + unrealized P&L) */
358
+ equity: number;
359
+ /** Available credit */
360
+ credit: number;
361
+ /** Used margin (margin required by open positions) */
362
+ margin: number;
363
+ }
364
+ /**
365
+ * Account status response
366
+ */
367
+ interface AccountStatusResponse {
368
+ status: 'success';
369
+ status_code: 'SUCCESS';
370
+ data: AccountStatus;
371
+ }
177
372
 
178
373
  /**
179
374
  * Trading Group types
@@ -750,6 +945,7 @@ interface PipsendConfig {
750
945
  */
751
946
  interface TokenInfo {
752
947
  token: string;
948
+ refreshToken?: string;
753
949
  expiresAt: Date;
754
950
  issuedAt: Date;
755
951
  }
@@ -765,12 +961,28 @@ interface OrderData {
765
961
  takeProfit?: number;
766
962
  }
767
963
  /**
768
- * Server authentication response
769
- * TODO: Adjust according to real API response
964
+ * Server authentication response from /api/v1/auth/login
770
965
  */
771
966
  interface AuthResponse {
772
- token: string;
773
- expiresIn: number;
967
+ access_token: string;
968
+ refresh_token: string;
969
+ expires_in: number;
970
+ token_type: string;
971
+ user: {
972
+ login: number;
973
+ email: string;
974
+ first_name: string;
975
+ last_name: string;
976
+ balance: number;
977
+ };
978
+ logged_with: string;
979
+ }
980
+ /**
981
+ * Validation error detail
982
+ */
983
+ interface ValidationError {
984
+ field: string;
985
+ message: string;
774
986
  }
775
987
  /**
776
988
  * Custom SDK errors
@@ -778,7 +990,17 @@ interface AuthResponse {
778
990
  declare class PipsendError extends Error {
779
991
  code?: string | undefined;
780
992
  statusCode?: number | undefined;
781
- constructor(message: string, code?: string | undefined, statusCode?: number | undefined);
993
+ errors?: ValidationError[];
994
+ response?: any;
995
+ constructor(message: string, code?: string | undefined, statusCode?: number | undefined, errors?: ValidationError[], response?: any);
996
+ /**
997
+ * Get formatted error message with validation details
998
+ */
999
+ getDetailedMessage(): string;
1000
+ /**
1001
+ * Check if this is a validation error
1002
+ */
1003
+ isValidationError(): boolean;
782
1004
  }
783
1005
  declare class AuthenticationError extends PipsendError {
784
1006
  constructor(message: string);
@@ -790,16 +1012,59 @@ declare class WebSocketError extends PipsendError {
790
1012
  constructor(message: string);
791
1013
  }
792
1014
 
1015
+ /**
1016
+ * Authentication manager with auto-refresh tokens
1017
+ */
1018
+ declare class AuthManager {
1019
+ private config;
1020
+ private tokenInfo?;
1021
+ private refreshMarginMs;
1022
+ constructor(config: PipsendConfig);
1023
+ /**
1024
+ * Checks if a valid token is available
1025
+ */
1026
+ isAuthenticated(): boolean;
1027
+ /**
1028
+ * Gets the current token (if it exists and is valid)
1029
+ */
1030
+ getToken(): string | undefined;
1031
+ /**
1032
+ * Ensures a valid token exists, authenticating if necessary
1033
+ */
1034
+ ensureAuthenticated(): Promise<string>;
1035
+ /**
1036
+ * Performs authentication with the server
1037
+ */
1038
+ private authenticate;
1039
+ /**
1040
+ * Refreshes the access token using the refresh token
1041
+ */
1042
+ refreshToken(): Promise<void>;
1043
+ /**
1044
+ * Clears the current token
1045
+ */
1046
+ clearToken(): void;
1047
+ /**
1048
+ * Checks if the token is expired or about to expire
1049
+ */
1050
+ private isTokenExpired;
1051
+ /**
1052
+ * Stores the received token information
1053
+ */
1054
+ private setTokenInfo;
1055
+ }
1056
+
793
1057
  /**
794
1058
  * HTTP client for making requests to the Pipsend API
795
1059
  */
796
1060
  declare class HttpClient {
797
1061
  private baseUrl;
798
- constructor(baseUrl: string);
1062
+ private authManager?;
1063
+ constructor(baseUrl: string, authManager?: AuthManager | undefined);
799
1064
  /**
800
1065
  * Makes an HTTP request
801
1066
  */
802
- request<T>(endpoint: string, options?: RequestInit): Promise<T>;
1067
+ request<T>(endpoint: string, options?: RequestInit, retryOn401?: boolean): Promise<T>;
803
1068
  /**
804
1069
  * GET request
805
1070
  */
@@ -828,6 +1093,10 @@ declare class HttpClient {
828
1093
  declare class AccountsAPI {
829
1094
  private http;
830
1095
  constructor(http: HttpClient);
1096
+ /**
1097
+ * Create a new trading account
1098
+ */
1099
+ create(request: CreateAccountRequest): Promise<CreateAccountResponse>;
831
1100
  /**
832
1101
  * List all accounts with optional filters and pagination
833
1102
  */
@@ -836,6 +1105,10 @@ declare class AccountsAPI {
836
1105
  * Get all account logins
837
1106
  */
838
1107
  getLogins(): Promise<number[]>;
1108
+ /**
1109
+ * Get account status/metrics (balance, equity, credit, margin)
1110
+ */
1111
+ getStatus(login: number): Promise<AccountStatusResponse>;
839
1112
  /**
840
1113
  * Get account statistics with optional filters
841
1114
  */
@@ -856,6 +1129,16 @@ declare class AccountsAPI {
856
1129
  * Unarchive an account
857
1130
  */
858
1131
  unarchive(login: number): Promise<void>;
1132
+ /**
1133
+ * Update account information (partial update)
1134
+ * All fields are optional, only send the ones you want to update
1135
+ */
1136
+ update(login: number, request: UpdateAccountRequest): Promise<UpdateAccountResponse>;
1137
+ /**
1138
+ * Adjust balance or credit for an account
1139
+ * The adjustment is relative: amount is added or subtracted from current value
1140
+ */
1141
+ balance(login: number, request: AdjustBalanceRequest): Promise<AdjustBalanceResponse>;
859
1142
  }
860
1143
 
861
1144
  /**
@@ -1108,33 +1391,49 @@ declare class PipsendClient {
1108
1391
  */
1109
1392
  isConnected: () => boolean;
1110
1393
  /**
1111
- * Subscribes to symbols or channels
1394
+ * Subscribes to WebSocket channels
1112
1395
  * @example
1113
- * client.stream.subscribe(['EURUSD', 'GBPUSD']);
1396
+ * client.stream.subscribe(['positions:new', 'positions:closed']);
1114
1397
  */
1115
- subscribe: (channels: string[]) => void;
1398
+ subscribe: (channels: WebSocketChannel[]) => void;
1116
1399
  /**
1117
- * Unsubscribes from symbols or channels
1400
+ * Unsubscribes from WebSocket channels
1118
1401
  */
1119
- unsubscribe: (channels: string[]) => void;
1402
+ unsubscribe: (channels: WebSocketChannel[]) => void;
1120
1403
  /**
1121
1404
  * Gets list of subscribed channels
1122
1405
  */
1123
- getSubscriptions: () => string[];
1406
+ getSubscriptions: () => WebSocketChannel[];
1407
+ /**
1408
+ * Listens to position opened events
1409
+ */
1410
+ onPositionOpened: (callback: WebSocketCallback<PositionEvent>) => void;
1411
+ /**
1412
+ * Listens to position closed events (includes partial closes)
1413
+ */
1414
+ onPositionClosed: (callback: WebSocketCallback<PositionEvent>) => void;
1415
+ /**
1416
+ * Listens to position updated events (throttled to max 1 per 2 seconds)
1417
+ */
1418
+ onPositionUpdated: (callback: WebSocketCallback<PositionEvent>) => void;
1419
+ /**
1420
+ * Listens to balance updated events
1421
+ */
1422
+ onBalanceUpdated: (callback: WebSocketCallback<BalanceEvent>) => void;
1124
1423
  /**
1125
- * Listens to real-time price updates
1424
+ * @deprecated Use onPositionUpdated instead
1126
1425
  */
1127
1426
  onPriceUpdate: (callback: WebSocketCallback<PriceUpdate>) => void;
1128
1427
  /**
1129
- * Listens to real-time order updates
1428
+ * @deprecated Use onPositionOpened/onPositionClosed instead
1130
1429
  */
1131
1430
  onOrderUpdate: (callback: WebSocketCallback<OrderUpdate>) => void;
1132
1431
  /**
1133
- * Listens to real-time position updates
1432
+ * @deprecated Use onPositionUpdated instead
1134
1433
  */
1135
1434
  onPositionUpdate: (callback: WebSocketCallback<PositionUpdate>) => void;
1136
1435
  /**
1137
- * Listens to real-time balance updates
1436
+ * @deprecated Use onBalanceUpdated instead
1138
1437
  */
1139
1438
  onBalanceUpdate: (callback: WebSocketCallback<BalanceUpdate>) => void;
1140
1439
  /**