@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/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@pipsend/sdk)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
Official Pipsend SDK for Node.js and TypeScript. Complete
|
|
6
|
+
Official Pipsend SDK for Node.js and TypeScript. Complete trading platform integration with WebSocket support.
|
|
7
7
|
|
|
8
8
|
## 🚀 Features
|
|
9
9
|
|
|
@@ -31,13 +31,59 @@ yarn add @pipsend/sdk
|
|
|
31
31
|
pnpm add @pipsend/sdk
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## 🔐 Authentication
|
|
35
|
+
|
|
36
|
+
The SDK uses JWT-based authentication with automatic token refresh.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { createClient } from '@pipsend/sdk';
|
|
40
|
+
|
|
41
|
+
const client = createClient({
|
|
42
|
+
server: 'http://localhost:8080',
|
|
43
|
+
login: '1000', // Your admin/API login
|
|
44
|
+
password: 'YourPassword' // Your admin/API password
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// The SDK automatically:
|
|
48
|
+
// ✅ Authenticates on first API call
|
|
49
|
+
// ✅ Stores access and refresh tokens in memory
|
|
50
|
+
// ✅ Refreshes tokens automatically when they expire
|
|
51
|
+
// ✅ Re-authenticates if refresh fails
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Authentication happens automatically** - you don't need to call any login method. Just create the client and start making API calls.
|
|
55
|
+
|
|
56
|
+
### Manual Authentication Control (Advanced)
|
|
57
|
+
|
|
58
|
+
If you need manual control over authentication:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// Check authentication status
|
|
62
|
+
const isAuthenticated = client.isAuthenticated();
|
|
63
|
+
|
|
64
|
+
// Manually refresh token
|
|
65
|
+
await client.refreshToken();
|
|
66
|
+
|
|
67
|
+
// Logout (clears tokens)
|
|
68
|
+
await client.logout();
|
|
69
|
+
|
|
70
|
+
// Get current token info
|
|
71
|
+
const tokenInfo = client.getTokenInfo();
|
|
72
|
+
console.log('Token expires at:', tokenInfo?.expiresAt);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
34
77
|
## 🔧 Quick Start
|
|
35
78
|
|
|
36
79
|
```typescript
|
|
37
80
|
import { createClient } from '@pipsend/sdk';
|
|
38
81
|
|
|
82
|
+
// Create authenticated client
|
|
39
83
|
const client = createClient({
|
|
40
|
-
server: 'http://localhost:8080'
|
|
84
|
+
server: 'http://localhost:8080',
|
|
85
|
+
login: '1000',
|
|
86
|
+
password: 'DemoMaster'
|
|
41
87
|
});
|
|
42
88
|
|
|
43
89
|
const login = 50001;
|
|
@@ -79,9 +125,22 @@ await client.stream.connect();
|
|
|
79
125
|
|
|
80
126
|
### 1. Accounts API
|
|
81
127
|
|
|
82
|
-
Manage
|
|
128
|
+
Manage accounts with advanced filtering and statistics.
|
|
83
129
|
|
|
84
130
|
```typescript
|
|
131
|
+
// Create a new trading account
|
|
132
|
+
const newAccount = await client.accounts.create({
|
|
133
|
+
trading_group: 'Premium',
|
|
134
|
+
country: 'MX',
|
|
135
|
+
master_password: 'SecurePass123!',
|
|
136
|
+
investor_password: 'InvestorPass123!',
|
|
137
|
+
email: 'trader@example.com',
|
|
138
|
+
first_name: 'John',
|
|
139
|
+
last_name: 'Doe',
|
|
140
|
+
leverage: 100,
|
|
141
|
+
state: 'active'
|
|
142
|
+
});
|
|
143
|
+
|
|
85
144
|
// List accounts with filters
|
|
86
145
|
const accounts = await client.accounts.list({
|
|
87
146
|
state: 'active',
|
|
@@ -102,6 +161,13 @@ const stats = await client.accounts.getStatistics({
|
|
|
102
161
|
// Get all account logins
|
|
103
162
|
const logins = await client.accounts.getLogins();
|
|
104
163
|
|
|
164
|
+
// Get account status/metrics (balance, equity, credit, margin)
|
|
165
|
+
const status = await client.accounts.getStatus(50001);
|
|
166
|
+
console.log('Balance:', status.data.balance);
|
|
167
|
+
console.log('Equity:', status.data.equity);
|
|
168
|
+
console.log('Credit:', status.data.credit);
|
|
169
|
+
console.log('Margin:', status.data.margin);
|
|
170
|
+
|
|
105
171
|
// Change passwords
|
|
106
172
|
await client.accounts.changeMasterPassword(50001, {
|
|
107
173
|
new_password: 'NewPass123!'
|
|
@@ -114,6 +180,34 @@ await client.accounts.changeInvestorPassword(50001, {
|
|
|
114
180
|
// Archive/Unarchive
|
|
115
181
|
await client.accounts.archive(50001);
|
|
116
182
|
await client.accounts.unarchive(50001);
|
|
183
|
+
|
|
184
|
+
// Update account information (partial update)
|
|
185
|
+
await client.accounts.update(50001, {
|
|
186
|
+
email: 'newemail@example.com',
|
|
187
|
+
leverage: 200,
|
|
188
|
+
city: 'Los Angeles',
|
|
189
|
+
trading_group: 'Premium'
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Adjust balance or credit
|
|
193
|
+
await client.accounts.balance(50001, {
|
|
194
|
+
type: 'balance',
|
|
195
|
+
amount: 500.00,
|
|
196
|
+
comment: 'Client deposit'
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
await client.accounts.balance(50001, {
|
|
200
|
+
type: 'credit',
|
|
201
|
+
amount: 1000.00,
|
|
202
|
+
comment: 'Credit line increase'
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Subtract balance
|
|
206
|
+
await client.accounts.balance(50001, {
|
|
207
|
+
type: 'balance',
|
|
208
|
+
amount: -200.00,
|
|
209
|
+
comment: 'Withdrawal request'
|
|
210
|
+
});
|
|
117
211
|
```
|
|
118
212
|
|
|
119
213
|
### 2. Orders API
|
|
@@ -340,51 +434,120 @@ const stats = await client.tradingGroups.getStatistics();
|
|
|
340
434
|
|
|
341
435
|
### 7. WebSocket API
|
|
342
436
|
|
|
343
|
-
Real-time updates for
|
|
437
|
+
Real-time updates for positions and balance with manual channel subscription.
|
|
344
438
|
|
|
345
439
|
```typescript
|
|
440
|
+
// Enable WebSocket in config
|
|
441
|
+
const client = createClient({
|
|
442
|
+
server: 'http://localhost:8080',
|
|
443
|
+
login: '1000',
|
|
444
|
+
password: 'DemoMaster',
|
|
445
|
+
websocket: {
|
|
446
|
+
enabled: true,
|
|
447
|
+
autoConnect: false
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
346
451
|
// Connect to WebSocket
|
|
347
452
|
await client.stream.connect();
|
|
348
453
|
|
|
349
|
-
// Subscribe to
|
|
350
|
-
client.stream.
|
|
351
|
-
|
|
454
|
+
// Subscribe to channels
|
|
455
|
+
client.stream.subscribe([
|
|
456
|
+
'positions:new', // New positions opened
|
|
457
|
+
'positions:closed', // Positions closed (total and partial)
|
|
458
|
+
'positions:updated', // Position PnL updates (throttled to 1 per 2s)
|
|
459
|
+
'accounts:balance' // Balance updates
|
|
460
|
+
]);
|
|
461
|
+
|
|
462
|
+
// Listen to position opened events
|
|
463
|
+
client.stream.onPositionOpened((event) => {
|
|
464
|
+
const pos = event.position;
|
|
465
|
+
console.log('Position opened:', pos.symbol, pos.side === 1 ? 'LONG' : 'SHORT', pos.qty);
|
|
352
466
|
});
|
|
353
467
|
|
|
354
|
-
//
|
|
355
|
-
client.stream.
|
|
356
|
-
|
|
468
|
+
// Listen to position closed events
|
|
469
|
+
client.stream.onPositionClosed((event) => {
|
|
470
|
+
const pos = event.position;
|
|
471
|
+
console.log('Position closed:', pos.symbol, 'PnL:', pos.net_pnl);
|
|
357
472
|
});
|
|
358
473
|
|
|
359
|
-
//
|
|
360
|
-
client.stream.
|
|
361
|
-
|
|
474
|
+
// Listen to position updated events (throttled)
|
|
475
|
+
client.stream.onPositionUpdated((event) => {
|
|
476
|
+
const pos = event.position;
|
|
477
|
+
console.log('Position update:', pos.position_id, 'PnL:', pos.unrealized_pnl);
|
|
362
478
|
});
|
|
363
479
|
|
|
364
|
-
//
|
|
365
|
-
client.stream.
|
|
366
|
-
console.log('Balance:',
|
|
480
|
+
// Listen to balance updates
|
|
481
|
+
client.stream.onBalanceUpdated((event) => {
|
|
482
|
+
console.log('Balance:', event.balance, 'Equity:', event.equity);
|
|
367
483
|
});
|
|
368
484
|
|
|
485
|
+
// Unsubscribe from channels
|
|
486
|
+
client.stream.unsubscribe(['positions:updated']);
|
|
487
|
+
|
|
369
488
|
// Disconnect
|
|
370
|
-
|
|
489
|
+
client.stream.disconnect();
|
|
371
490
|
```
|
|
372
491
|
|
|
492
|
+
**Available Channels**:
|
|
493
|
+
- `positions:new` - New position opened
|
|
494
|
+
- `positions:closed` - Position closed (total or partial)
|
|
495
|
+
- `positions:updated` - PnL updates (throttled to max 1 per 2 seconds)
|
|
496
|
+
- `accounts:balance` - Balance changes
|
|
497
|
+
|
|
373
498
|
**Features**:
|
|
499
|
+
- Manual subscription to specific channels
|
|
374
500
|
- Auto-reconnect with exponential backoff
|
|
375
501
|
- Heartbeat/ping-pong mechanism
|
|
376
|
-
- Automatic subscription restoration
|
|
502
|
+
- Automatic subscription restoration on reconnect
|
|
503
|
+
- Throttled position updates to reduce load
|
|
504
|
+
|
|
505
|
+
See [WebSocket API Documentation](docs/WEBSOCKET_API.md) for complete guide.
|
|
377
506
|
|
|
378
507
|
## 🔧 Configuration
|
|
379
508
|
|
|
509
|
+
### Basic Configuration
|
|
510
|
+
|
|
380
511
|
```typescript
|
|
381
512
|
const client = createClient({
|
|
382
|
-
server: 'http://localhost:8080', // Required
|
|
383
|
-
login: '
|
|
384
|
-
password: '
|
|
513
|
+
server: 'http://localhost:8080', // Required: API server URL
|
|
514
|
+
login: '1000', // Required: Admin/API login
|
|
515
|
+
password: 'YourPassword' // Required: Admin/API password
|
|
385
516
|
});
|
|
386
517
|
```
|
|
387
518
|
|
|
519
|
+
### Advanced Configuration
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
const client = createClient({
|
|
523
|
+
server: 'http://localhost:8080',
|
|
524
|
+
login: '1000',
|
|
525
|
+
password: 'YourPassword',
|
|
526
|
+
|
|
527
|
+
// WebSocket configuration (optional)
|
|
528
|
+
websocket: {
|
|
529
|
+
enabled: true, // Enable WebSocket support
|
|
530
|
+
autoConnect: false, // Auto-connect on client creation
|
|
531
|
+
autoReconnect: true, // Auto-reconnect on disconnect
|
|
532
|
+
maxReconnectAttempts: 5, // Max reconnection attempts
|
|
533
|
+
heartbeatInterval: 30000 // Heartbeat interval in ms
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Configuration Options
|
|
539
|
+
|
|
540
|
+
| Option | Type | Required | Default | Description |
|
|
541
|
+
|--------|------|----------|---------|-------------|
|
|
542
|
+
| `server` | string | ✅ Yes | - | Pipsend API server URL |
|
|
543
|
+
| `login` | string | ✅ Yes | - | Admin/API login for authentication |
|
|
544
|
+
| `password` | string | ✅ Yes | - | Admin/API password |
|
|
545
|
+
| `websocket.enabled` | boolean | No | `false` | Enable WebSocket support |
|
|
546
|
+
| `websocket.autoConnect` | boolean | No | `false` | Auto-connect on creation |
|
|
547
|
+
| `websocket.autoReconnect` | boolean | No | `true` | Auto-reconnect on disconnect |
|
|
548
|
+
| `websocket.maxReconnectAttempts` | number | No | `5` | Max reconnection attempts |
|
|
549
|
+
| `websocket.heartbeatInterval` | number | No | `30000` | Heartbeat interval (ms) |
|
|
550
|
+
|
|
388
551
|
## 📦 API Response Structure
|
|
389
552
|
|
|
390
553
|
All API endpoints return a consistent response structure:
|
|
@@ -593,9 +756,13 @@ const candles = await client.marketData.getCandles({
|
|
|
593
756
|
|
|
594
757
|
## ⚠️ Error Handling
|
|
595
758
|
|
|
596
|
-
|
|
759
|
+
All errors thrown by the SDK are instances of `PipsendError` with detailed information.
|
|
760
|
+
|
|
761
|
+
### Basic Error Handling
|
|
597
762
|
|
|
598
763
|
```typescript
|
|
764
|
+
import { PipsendError } from '@pipsend/sdk';
|
|
765
|
+
|
|
599
766
|
try {
|
|
600
767
|
const trade = await client.trades.open({
|
|
601
768
|
login: 50001,
|
|
@@ -607,20 +774,80 @@ try {
|
|
|
607
774
|
|
|
608
775
|
console.log('Trade opened:', trade.position_id);
|
|
609
776
|
|
|
610
|
-
} catch (error
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
console.error('
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
777
|
+
} catch (error) {
|
|
778
|
+
if (error instanceof PipsendError) {
|
|
779
|
+
console.error('Error code:', error.code);
|
|
780
|
+
console.error('Status code:', error.statusCode);
|
|
781
|
+
console.error('Message:', error.message);
|
|
782
|
+
|
|
783
|
+
// Check if it's a validation error
|
|
784
|
+
if (error.isValidationError()) {
|
|
785
|
+
console.error('Validation errors:', error.errors);
|
|
786
|
+
// Get formatted message with all details
|
|
787
|
+
console.error(error.getDetailedMessage());
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
### Handling Validation Errors (422)
|
|
794
|
+
|
|
795
|
+
When the API returns validation errors, the SDK provides detailed field-level information:
|
|
796
|
+
|
|
797
|
+
```typescript
|
|
798
|
+
try {
|
|
799
|
+
const account = await client.accounts.create({
|
|
800
|
+
trading_group: 'InvalidGroup',
|
|
801
|
+
country: 'XYZ',
|
|
802
|
+
master_password: 'short',
|
|
803
|
+
investor_password: 'short',
|
|
804
|
+
email: 'invalid-email',
|
|
805
|
+
first_name: 'John',
|
|
806
|
+
last_name: 'Doe'
|
|
807
|
+
});
|
|
808
|
+
} catch (error) {
|
|
809
|
+
if (error instanceof PipsendError && error.isValidationError()) {
|
|
810
|
+
console.log('Validation failed:');
|
|
811
|
+
|
|
812
|
+
// Access individual validation errors
|
|
813
|
+
error.errors?.forEach(err => {
|
|
814
|
+
console.log(` - ${err.field}: ${err.message}`);
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
// Or get formatted message
|
|
818
|
+
console.log(error.getDetailedMessage());
|
|
819
|
+
|
|
820
|
+
// Output:
|
|
821
|
+
// The provided data is not valid.
|
|
822
|
+
// - trading_group: Trading group 'InvalidGroup' not found
|
|
823
|
+
// - country: Country 'XYZ' not found
|
|
824
|
+
// - master_password: The field master_password must be at least 8 characters.
|
|
825
|
+
// - email: The field email must be a valid email address.
|
|
620
826
|
}
|
|
621
827
|
}
|
|
622
828
|
```
|
|
623
829
|
|
|
830
|
+
### Error Properties
|
|
831
|
+
|
|
832
|
+
```typescript
|
|
833
|
+
interface PipsendError {
|
|
834
|
+
message: string; // Error message
|
|
835
|
+
code: string; // Error code (e.g., 'VALIDATION_ERROR', 'NOT_FOUND')
|
|
836
|
+
statusCode: number; // HTTP status code (e.g., 422, 404, 500)
|
|
837
|
+
errors?: ValidationError[]; // Validation errors (for 422 responses)
|
|
838
|
+
response?: any; // Full error response from server
|
|
839
|
+
|
|
840
|
+
// Helper methods
|
|
841
|
+
isValidationError(): boolean; // Check if it's a validation error
|
|
842
|
+
getDetailedMessage(): string; // Get formatted message with details
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
interface ValidationError {
|
|
846
|
+
field: string; // Field name that failed validation
|
|
847
|
+
message: string; // Validation error message
|
|
848
|
+
}
|
|
849
|
+
```
|
|
850
|
+
|
|
624
851
|
### Common Error Scenarios
|
|
625
852
|
|
|
626
853
|
```typescript
|