valr-typescript-client 1.0.0
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 +363 -0
- package/dist/index.d.mts +3256 -0
- package/dist/index.d.ts +3256 -0
- package/dist/index.js +1973 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1939 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# VALR TypeScript Client
|
|
2
|
+
|
|
3
|
+
A comprehensive, fully-typed TypeScript/JavaScript client for the [VALR](https://www.valr.com) cryptocurrency exchange API.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Full TypeScript Support** - Complete type definitions for all endpoints and responses
|
|
8
|
+
- ✅ **Comprehensive API Coverage** - All 147 REST endpoints implemented
|
|
9
|
+
- ✅ **WebSocket Support** - Real-time market data and account updates (coming soon)
|
|
10
|
+
- ✅ **Modern Architecture** - Built with axios, supports both ESM and CommonJS
|
|
11
|
+
- ✅ **Automatic Authentication** - HMAC SHA512 request signing handled automatically
|
|
12
|
+
- ✅ **Error Handling** - Custom error classes for different error types
|
|
13
|
+
- ✅ **Rate Limit Aware** - Built-in awareness of VALR API rate limits
|
|
14
|
+
- ✅ **Subaccount Support** - Easy subaccount impersonation
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install valr-typescript-client
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
or
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
yarn add valr-typescript-client
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
or
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm add valr-typescript-client
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### Public API (No Authentication Required)
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { ValrClient } from 'valr-typescript-client';
|
|
40
|
+
|
|
41
|
+
const client = new ValrClient();
|
|
42
|
+
|
|
43
|
+
// Get server time
|
|
44
|
+
const time = await client.public.getServerTime();
|
|
45
|
+
console.log('Server time:', time);
|
|
46
|
+
|
|
47
|
+
// Get market summary for all pairs
|
|
48
|
+
const markets = await client.public.getMarketSummary();
|
|
49
|
+
console.log('Markets:', markets);
|
|
50
|
+
|
|
51
|
+
// Get order book for a specific pair
|
|
52
|
+
const orderBook = await client.public.getOrderBook('BTCZAR');
|
|
53
|
+
console.log('Order book:', orderBook);
|
|
54
|
+
|
|
55
|
+
// Get currencies
|
|
56
|
+
const currencies = await client.public.getCurrencies();
|
|
57
|
+
console.log('Supported currencies:', currencies);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Authenticated API
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { ValrClient } from 'valr-typescript-client';
|
|
64
|
+
|
|
65
|
+
const client = new ValrClient({
|
|
66
|
+
apiKey: 'your-api-key',
|
|
67
|
+
apiSecret: 'your-api-secret',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Get account balances
|
|
71
|
+
const balances = await client.account.getBalances();
|
|
72
|
+
console.log('Balances:', balances);
|
|
73
|
+
|
|
74
|
+
// Place a limit order
|
|
75
|
+
const order = await client.trading.placeLimitOrder({
|
|
76
|
+
pair: 'BTCZAR',
|
|
77
|
+
side: 'BUY',
|
|
78
|
+
quantity: '0.001',
|
|
79
|
+
price: '500000',
|
|
80
|
+
postOnly: 'POST_ONLY_REPRICE',
|
|
81
|
+
customerOrderId: 'my-order-1',
|
|
82
|
+
});
|
|
83
|
+
console.log('Order placed:', order);
|
|
84
|
+
|
|
85
|
+
// Get open orders
|
|
86
|
+
const openOrders = await client.trading.getAllOpenOrders();
|
|
87
|
+
console.log('Open orders:', openOrders);
|
|
88
|
+
|
|
89
|
+
// Get trade history
|
|
90
|
+
const trades = await client.account.getTradeHistory({
|
|
91
|
+
skip: 0,
|
|
92
|
+
limit: 100,
|
|
93
|
+
});
|
|
94
|
+
console.log('Trade history:', trades);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Advanced Trading
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// Place a market order
|
|
101
|
+
const marketOrder = await client.trading.placeMarketOrder({
|
|
102
|
+
pair: 'ETHZAR',
|
|
103
|
+
side: 'BUY',
|
|
104
|
+
quoteAmount: '1000', // Spend 1000 ZAR
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Place a stop-limit order
|
|
108
|
+
const stopOrder = await client.trading.placeStopLimitOrder({
|
|
109
|
+
pair: 'BTCZAR',
|
|
110
|
+
side: 'SELL',
|
|
111
|
+
quantity: '0.001',
|
|
112
|
+
price: '450000',
|
|
113
|
+
stopPrice: '460000',
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Place batch orders
|
|
117
|
+
const batchOrders = await client.trading.placeBatchOrders({
|
|
118
|
+
requests: [
|
|
119
|
+
{
|
|
120
|
+
pair: 'BTCZAR',
|
|
121
|
+
side: 'BUY',
|
|
122
|
+
quantity: '0.001',
|
|
123
|
+
price: '480000',
|
|
124
|
+
postOnly: 'POST_ONLY_REPRICE',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
pair: 'ETHZAR',
|
|
128
|
+
side: 'BUY',
|
|
129
|
+
quantity: '0.01',
|
|
130
|
+
price: '30000',
|
|
131
|
+
postOnly: 'POST_ONLY_REPRICE',
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Get order status
|
|
137
|
+
const orderStatus = await client.trading.getOrderStatus('BTCZAR', order.id);
|
|
138
|
+
console.log('Order status:', orderStatus);
|
|
139
|
+
|
|
140
|
+
// Cancel order
|
|
141
|
+
await client.trading.cancelOrder({
|
|
142
|
+
pair: 'BTCZAR',
|
|
143
|
+
orderId: order.id,
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Wallets
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Get crypto deposit address
|
|
151
|
+
const depositAddress = await client.wallets.getCryptoDepositAddress('BTC');
|
|
152
|
+
console.log('Deposit to:', depositAddress.address);
|
|
153
|
+
|
|
154
|
+
// Withdraw crypto
|
|
155
|
+
const withdrawal = await client.wallets.withdrawCrypto({
|
|
156
|
+
currency: 'BTC',
|
|
157
|
+
amount: '0.001',
|
|
158
|
+
address: 'bc1q...',
|
|
159
|
+
});
|
|
160
|
+
console.log('Withdrawal ID:', withdrawal.id);
|
|
161
|
+
|
|
162
|
+
// Get bank accounts
|
|
163
|
+
const bankAccounts = await client.wallets.getBankAccounts('ZAR');
|
|
164
|
+
console.log('Bank accounts:', bankAccounts);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Futures Trading
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// Get open futures positions
|
|
171
|
+
const positions = await client.futures.getOpenPositions();
|
|
172
|
+
console.log('Open positions:', positions);
|
|
173
|
+
|
|
174
|
+
// Get leverage info
|
|
175
|
+
const leverage = await client.futures.getLeverageInfo('BTCUSDTPERP');
|
|
176
|
+
console.log('Current leverage:', leverage);
|
|
177
|
+
|
|
178
|
+
// Update leverage
|
|
179
|
+
await client.futures.updateLeverage('BTCUSDTPERP', {
|
|
180
|
+
leverageMultiple: 5,
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Subaccount Impersonation
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const client = new ValrClient({
|
|
188
|
+
apiKey: 'your-primary-account-api-key',
|
|
189
|
+
apiSecret: 'your-primary-account-api-secret',
|
|
190
|
+
subaccountId: 'subaccount-id',
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// All requests will now be made on behalf of the subaccount
|
|
194
|
+
const balances = await client.account.getBalances();
|
|
195
|
+
|
|
196
|
+
// Change subaccount or clear
|
|
197
|
+
client.setSubaccountId('different-subaccount-id');
|
|
198
|
+
client.setSubaccountId(undefined); // Back to primary account
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## API Categories
|
|
202
|
+
|
|
203
|
+
The client organizes endpoints into logical categories:
|
|
204
|
+
|
|
205
|
+
- **`client.public`** - Public market data (no auth required)
|
|
206
|
+
- **`client.account`** - Account information, balances, history
|
|
207
|
+
- **`client.trading`** - Order placement and management
|
|
208
|
+
- **`client.wallets`** - Deposits and withdrawals
|
|
209
|
+
- **`client.futures`** - Futures positions and leverage
|
|
210
|
+
- **`client.margin`** - Margin trading
|
|
211
|
+
- **`client.loans`** - Lending and borrowing
|
|
212
|
+
- **`client.earn`** - Staking and earning products
|
|
213
|
+
- **`client.pay`** - Payment functionality
|
|
214
|
+
- **`client.bundles`** - Currency bundles
|
|
215
|
+
- **`client.health`** - API health status
|
|
216
|
+
|
|
217
|
+
## Authentication
|
|
218
|
+
|
|
219
|
+
VALR API uses HMAC SHA512 signatures for authentication. This client handles all signature generation automatically.
|
|
220
|
+
|
|
221
|
+
### Getting API Keys
|
|
222
|
+
|
|
223
|
+
1. Enable 2FA on your VALR account
|
|
224
|
+
2. Navigate to Account → API Keys
|
|
225
|
+
3. Create a new API key with appropriate permissions:
|
|
226
|
+
- **View**: Read-only access to account data
|
|
227
|
+
- **Trade**: Place and cancel orders
|
|
228
|
+
- **Transfer**: Transfer between accounts
|
|
229
|
+
- **Withdraw**: Withdraw funds
|
|
230
|
+
|
|
231
|
+
### API Key Security
|
|
232
|
+
|
|
233
|
+
- Never commit your API keys to version control
|
|
234
|
+
- Store keys in environment variables:
|
|
235
|
+
```typescript
|
|
236
|
+
const client = new ValrClient({
|
|
237
|
+
apiKey: process.env.VALR_API_KEY,
|
|
238
|
+
apiSecret: process.env.VALR_API_SECRET,
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
- Use minimal permissions for each key
|
|
242
|
+
- Regularly rotate your API keys
|
|
243
|
+
- Delete unused API keys
|
|
244
|
+
|
|
245
|
+
## Error Handling
|
|
246
|
+
|
|
247
|
+
The client throws typed errors for different failure scenarios:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import {
|
|
251
|
+
ValrError,
|
|
252
|
+
ValrAuthenticationError,
|
|
253
|
+
ValrRateLimitError,
|
|
254
|
+
ValrValidationError,
|
|
255
|
+
ValrApiError,
|
|
256
|
+
} from 'valr-typescript-client';
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
await client.trading.placeLimitOrder({
|
|
260
|
+
pair: 'BTCZAR',
|
|
261
|
+
side: 'BUY',
|
|
262
|
+
quantity: '0.001',
|
|
263
|
+
price: '500000',
|
|
264
|
+
});
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (error instanceof ValrAuthenticationError) {
|
|
267
|
+
console.error('Authentication failed - check your API keys');
|
|
268
|
+
} else if (error instanceof ValrRateLimitError) {
|
|
269
|
+
console.error('Rate limit exceeded - slow down requests');
|
|
270
|
+
} else if (error instanceof ValrValidationError) {
|
|
271
|
+
console.error('Validation error:', error.errors);
|
|
272
|
+
} else if (error instanceof ValrApiError) {
|
|
273
|
+
console.error('API error:', error.statusCode, error.message);
|
|
274
|
+
} else if (error instanceof ValrError) {
|
|
275
|
+
console.error('VALR error:', error.message);
|
|
276
|
+
} else {
|
|
277
|
+
console.error('Unknown error:', error);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Rate Limits
|
|
283
|
+
|
|
284
|
+
VALR enforces rate limits on API requests:
|
|
285
|
+
|
|
286
|
+
- **2000 requests per minute** per API key
|
|
287
|
+
- **1200 requests per minute** per IP address
|
|
288
|
+
- Some endpoints have stricter per-second limits (e.g., order placement: 400/s)
|
|
289
|
+
|
|
290
|
+
The client automatically includes rate limit information in error responses when limits are exceeded.
|
|
291
|
+
|
|
292
|
+
## TypeScript Support
|
|
293
|
+
|
|
294
|
+
The client is written in TypeScript and provides comprehensive type definitions:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import type {
|
|
298
|
+
CurrencyPair,
|
|
299
|
+
OrderSide,
|
|
300
|
+
OrderStatus,
|
|
301
|
+
Balance,
|
|
302
|
+
MarketSummary,
|
|
303
|
+
OrderResponse,
|
|
304
|
+
} from 'valr-typescript-client';
|
|
305
|
+
|
|
306
|
+
// All API responses are fully typed
|
|
307
|
+
const balances: Balance[] = await client.account.getBalances();
|
|
308
|
+
const markets: MarketSummary[] = await client.public.getMarketSummary();
|
|
309
|
+
|
|
310
|
+
// Request parameters are type-checked
|
|
311
|
+
await client.trading.placeLimitOrder({
|
|
312
|
+
pair: 'BTCZAR', // Type: CurrencyPair
|
|
313
|
+
side: 'BUY', // Type: OrderSide
|
|
314
|
+
quantity: '0.001',
|
|
315
|
+
price: '500000',
|
|
316
|
+
postOnly: 'POST_ONLY_REPRICE', // Type-checked enum
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Development
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Install dependencies
|
|
324
|
+
npm install
|
|
325
|
+
|
|
326
|
+
# Build the project
|
|
327
|
+
npm run build
|
|
328
|
+
|
|
329
|
+
# Run tests
|
|
330
|
+
npm test
|
|
331
|
+
|
|
332
|
+
# Run tests in watch mode
|
|
333
|
+
npm run test:watch
|
|
334
|
+
|
|
335
|
+
# Type check
|
|
336
|
+
npm run type-check
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Contributing
|
|
340
|
+
|
|
341
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
342
|
+
|
|
343
|
+
## License
|
|
344
|
+
|
|
345
|
+
MIT
|
|
346
|
+
|
|
347
|
+
## Links
|
|
348
|
+
|
|
349
|
+
- [VALR Website](https://www.valr.com)
|
|
350
|
+
- [VALR API Documentation](https://docs.valr.com)
|
|
351
|
+
- [GitHub Repository](https://github.com/yourusername/valr-typescript-client)
|
|
352
|
+
- [NPM Package](https://www.npmjs.com/package/valr-typescript-client)
|
|
353
|
+
|
|
354
|
+
## Disclaimer
|
|
355
|
+
|
|
356
|
+
This is an unofficial client library and is not affiliated with or endorsed by VALR. Use at your own risk.
|
|
357
|
+
|
|
358
|
+
## Support
|
|
359
|
+
|
|
360
|
+
For issues and questions:
|
|
361
|
+
|
|
362
|
+
- [GitHub Issues](https://github.com/yourusername/valr-typescript-client/issues)
|
|
363
|
+
- [VALR Support](https://support.valr.com)
|