@pipsend/sdk 0.1.0 → 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/README.md +259 -32
- package/dist/index.d.mts +328 -29
- package/dist/index.d.ts +328 -29
- package/dist/index.js +313 -74
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +313 -74
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -16,15 +16,86 @@ interface WebSocketConfig {
|
|
|
16
16
|
heartbeatInterval?: number;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
* WebSocket
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
|
|
773
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1394
|
+
* Subscribes to WebSocket channels
|
|
1112
1395
|
* @example
|
|
1113
|
-
* client.stream.subscribe(['
|
|
1396
|
+
* client.stream.subscribe(['positions:new', 'positions:closed']);
|
|
1114
1397
|
*/
|
|
1115
|
-
subscribe: (channels:
|
|
1398
|
+
subscribe: (channels: WebSocketChannel[]) => void;
|
|
1116
1399
|
/**
|
|
1117
|
-
* Unsubscribes from
|
|
1400
|
+
* Unsubscribes from WebSocket channels
|
|
1118
1401
|
*/
|
|
1119
|
-
unsubscribe: (channels:
|
|
1402
|
+
unsubscribe: (channels: WebSocketChannel[]) => void;
|
|
1120
1403
|
/**
|
|
1121
1404
|
* Gets list of subscribed channels
|
|
1122
1405
|
*/
|
|
1123
|
-
getSubscriptions: () =>
|
|
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
|
-
*
|
|
1424
|
+
* @deprecated Use onPositionUpdated instead
|
|
1126
1425
|
*/
|
|
1127
1426
|
onPriceUpdate: (callback: WebSocketCallback<PriceUpdate>) => void;
|
|
1128
1427
|
/**
|
|
1129
|
-
*
|
|
1428
|
+
* @deprecated Use onPositionOpened/onPositionClosed instead
|
|
1130
1429
|
*/
|
|
1131
1430
|
onOrderUpdate: (callback: WebSocketCallback<OrderUpdate>) => void;
|
|
1132
1431
|
/**
|
|
1133
|
-
*
|
|
1432
|
+
* @deprecated Use onPositionUpdated instead
|
|
1134
1433
|
*/
|
|
1135
1434
|
onPositionUpdate: (callback: WebSocketCallback<PositionUpdate>) => void;
|
|
1136
1435
|
/**
|
|
1137
|
-
*
|
|
1436
|
+
* @deprecated Use onBalanceUpdated instead
|
|
1138
1437
|
*/
|
|
1139
1438
|
onBalanceUpdate: (callback: WebSocketCallback<BalanceUpdate>) => void;
|
|
1140
1439
|
/**
|