valr-typescript-client
v1.0.24
Published
TypeScript client for the VALR cryptocurrency exchange API with full type safety, WebSocket support, and comprehensive endpoint coverage
Downloads
1,625
Maintainers
Readme
VALR TypeScript Client
A comprehensive, fully-typed TypeScript/JavaScript client for the VALR cryptocurrency exchange API.
Features
- ✅ Full TypeScript Support - Complete type definitions for all endpoints and responses
- ✅ Comprehensive API Coverage - All 147 REST endpoints implemented
- ✅ WebSocket Support - Real-time market data and account updates (coming soon)
- ✅ Modern Architecture - Built with axios, supports both ESM and CommonJS
- ✅ Automatic Authentication - HMAC SHA512 request signing handled automatically
- ✅ Error Handling - Custom error classes for different error types
- ✅ Rate Limit Aware - Built-in awareness of VALR API rate limits
- ✅ Subaccount Support - Easy subaccount impersonation
Installation
npm install valr-typescript-clientor
yarn add valr-typescript-clientor
pnpm add valr-typescript-clientQuick Start
Public API (No Authentication Required)
import { ValrClient } from 'valr-typescript-client';
const client = new ValrClient();
// Get server time
const time = await client.public.getServerTime();
console.log('Server time:', time);
// Get market summary for all pairs
const markets = await client.public.getMarketSummary();
console.log('Markets:', markets);
// Get order book for a specific pair
const orderBook = await client.public.getOrderBook('BTCZAR');
console.log('Order book:', orderBook);
// Get currencies
const currencies = await client.public.getCurrencies();
console.log('Supported currencies:', currencies);Authenticated API
import { ValrClient } from 'valr-typescript-client';
const client = new ValrClient({
apiKey: 'your-api-key',
apiSecret: 'your-api-secret',
});
// Get account balances
const balances = await client.account.getBalances();
console.log('Balances:', balances);
// Place a limit order
const order = await client.trading.placeLimitOrder({
pair: 'BTCZAR',
side: 'BUY',
quantity: '0.001',
price: '500000',
postOnly: 'POST_ONLY_REPRICE',
customerOrderId: 'my-order-1',
});
console.log('Order placed:', order);
// Get open orders
const openOrders = await client.trading.getAllOpenOrders();
console.log('Open orders:', openOrders);
// Get trade history
const trades = await client.account.getTradeHistory({
skip: 0,
limit: 100,
});
console.log('Trade history:', trades);Advanced Trading
// Place a market order
const marketOrder = await client.trading.placeMarketOrder({
pair: 'ETHZAR',
side: 'BUY',
quoteAmount: '1000', // Spend 1000 ZAR
});
// Place a stop-limit order
const stopOrder = await client.trading.placeStopLimitOrder({
pair: 'BTCZAR',
side: 'SELL',
quantity: '0.001',
price: '450000',
stopPrice: '460000',
});
// Place batch orders
const batchOrders = await client.trading.placeBatchOrders({
requests: [
{
pair: 'BTCZAR',
side: 'BUY',
quantity: '0.001',
price: '480000',
postOnly: 'POST_ONLY_REPRICE',
},
{
pair: 'ETHZAR',
side: 'BUY',
quantity: '0.01',
price: '30000',
postOnly: 'POST_ONLY_REPRICE',
},
],
});
// Get order status
const orderStatus = await client.trading.getOrderStatus('BTCZAR', order.id);
console.log('Order status:', orderStatus);
// Cancel order
await client.trading.cancelOrder({
pair: 'BTCZAR',
orderId: order.id,
});Wallets
// Get crypto deposit address
const depositAddress = await client.wallets.getCryptoDepositAddress('BTC');
console.log('Deposit to:', depositAddress.address);
// Withdraw crypto
const withdrawal = await client.wallets.withdrawCrypto({
currency: 'BTC',
amount: '0.001',
address: 'bc1q...',
});
console.log('Withdrawal ID:', withdrawal.id);
// Get bank accounts
const bankAccounts = await client.wallets.getBankAccounts('ZAR');
console.log('Bank accounts:', bankAccounts);Futures Trading
// Get open futures positions
const positions = await client.futures.getOpenPositions();
console.log('Open positions:', positions);
// Get leverage info
const leverage = await client.futures.getLeverageInfo('BTCUSDTPERP');
console.log('Current leverage:', leverage);
// Update leverage
await client.futures.updateLeverage('BTCUSDTPERP', {
leverageMultiple: 5,
});Subaccount Impersonation
const client = new ValrClient({
apiKey: 'your-primary-account-api-key',
apiSecret: 'your-primary-account-api-secret',
subaccountId: 'subaccount-id',
});
// All requests will now be made on behalf of the subaccount
const balances = await client.account.getBalances();
// Change subaccount or clear
client.setSubaccountId('different-subaccount-id');
client.setSubaccountId(undefined); // Back to primary accountAPI Categories
The client organizes endpoints into logical categories:
client.public- Public market data (no auth required)client.account- Account information, balances, historyclient.trading- Order placement and managementclient.wallets- Deposits and withdrawalsclient.futures- Futures positions and leverageclient.margin- Margin tradingclient.loans- Lending and borrowingclient.earn- Staking and earning productsclient.pay- Payment functionalityclient.bundles- Currency bundlesclient.health- API health status
Authentication
VALR API uses HMAC SHA512 signatures for authentication. This client handles all signature generation automatically.
Getting API Keys
- Enable 2FA on your VALR account
- Navigate to Account → API Keys
- Create a new API key with appropriate permissions:
- View: Read-only access to account data
- Trade: Place and cancel orders
- Transfer: Transfer between accounts
- Withdraw: Withdraw funds
API Key Security
- Never commit your API keys to version control
- Store keys in environment variables:
const client = new ValrClient({ apiKey: process.env.VALR_API_KEY, apiSecret: process.env.VALR_API_SECRET, }); - Use minimal permissions for each key
- Regularly rotate your API keys
- Delete unused API keys
Package Integrity & Verification
This package includes cryptographic checksums to verify package integrity and protect against supply chain attacks.
Verifying Package Checksums
After installing from npm or any registry, you can verify the package integrity:
# Using npm script (cross-platform)
npm run verify
# Or directly with Node.js
node node_modules/valr-typescript-client/scripts/verify-checksums.js
# Or on Unix systems with bash
bash node_modules/valr-typescript-client/scripts/verify-checksums.shThis will verify that:
- All
dist/files (the compiled JavaScript you actually execute) match the official build - The package hasn't been tampered with after publication
- You're running the exact code from the GitHub release
- Shows you the Git commit SHA of the source code it was built from
What you're verifying: The compiled JavaScript files in dist/ are what run when you use this package. The checksums prove these match the official build from GitHub Actions.
What Gets Verified
The checksum verification checks:
Distribution files (dist/) - What actually executes:
dist/index.js,dist/index.mjs- Compiled JavaScript (ESM/CJS)dist/index.d.ts,dist/index.d.mts- TypeScript definitionsdist/*.map- Source maps
Source files (src/) - For transparency:
- Original TypeScript source code
- Allows you to inspect what the dist was built from
- Enables reproducible builds (advanced users)
Metadata:
- Git commit SHA - Links to exact source code on GitHub
- Build timestamp - When the package was built
- Package version - Version number
Security model: Checksums prove your dist/ files match the official GitHub Actions build. You can inspect the source code at the Git commit shown in the checksums.
Building from Source
If you prefer to build from source yourself:
# Clone the repository
git clone https://github.com/yashutanna/valr-typescript-client.git
cd valr-typescript-client
# Checkout a specific release
git checkout v1.0.9
# Install dependencies (use ci for reproducible builds)
npm ci
# Build
npm run build
# Run tests
npm testReproducible Builds (Advanced)
For maximum trust, verify the official build was created from clean source code:
# Clone and checkout the release
git clone https://github.com/yashutanna/valr-typescript-client.git
cd valr-typescript-client
git checkout v1.0.9
# Build from source
npm ci
npm run build
# Compare your build with official checksums
bash scripts/build-and-verify.shThis attempts to reproduce the official build and compares your locally-built dist/ files with the checksums from the official release. Note that perfect reproducibility is challenging with JavaScript builds, but the script will show you any differences.
CI/CD Transparency
Every package published to npm includes:
CHECKSUMS.txt- SHA256 hashes of all files- Git commit SHA that was built
- Build timestamp
- Verification scripts
The checksums are available in multiple places:
- In the repository - Committed with each release (permanent Git history)
- GitHub Releases - Attached as an asset to every release
- npm package - Included at
node_modules/valr-typescript-client/CHECKSUMS.txt - GitHub Actions - Available as workflow artifacts
To verify a specific release, check the Git tag or GitHub release assets.
Error Handling
The client throws typed errors for different failure scenarios:
import {
ValrError,
ValrAuthenticationError,
ValrRateLimitError,
ValrValidationError,
ValrApiError,
} from 'valr-typescript-client';
try {
await client.trading.placeLimitOrder({
pair: 'BTCZAR',
side: 'BUY',
quantity: '0.001',
price: '500000',
});
} catch (error) {
if (error instanceof ValrAuthenticationError) {
console.error('Authentication failed - check your API keys');
} else if (error instanceof ValrRateLimitError) {
console.error('Rate limit exceeded - slow down requests');
} else if (error instanceof ValrValidationError) {
console.error('Validation error:', error.errors);
} else if (error instanceof ValrApiError) {
console.error('API error:', error.statusCode, error.message);
} else if (error instanceof ValrError) {
console.error('VALR error:', error.message);
} else {
console.error('Unknown error:', error);
}
}Rate Limits
VALR enforces rate limits on API requests:
- 2000 requests per minute per API key
- 1200 requests per minute per IP address
- Some endpoints have stricter per-second limits (e.g., order placement: 400/s)
The client automatically includes rate limit information in error responses when limits are exceeded.
TypeScript Support
The client is written in TypeScript and provides comprehensive type definitions:
import type {
CurrencyPair,
OrderSide,
OrderStatus,
Balance,
MarketSummary,
OrderResponse,
} from 'valr-typescript-client';
// All API responses are fully typed
const balances: Balance[] = await client.account.getBalances();
const markets: MarketSummary[] = await client.public.getMarketSummary();
// Request parameters are type-checked
await client.trading.placeLimitOrder({
pair: 'BTCZAR', // Type: CurrencyPair
side: 'BUY', // Type: OrderSide
quantity: '0.001',
price: '500000',
postOnly: 'POST_ONLY_REPRICE', // Type-checked enum
});Development
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Type check
npm run type-checkContributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Links
Disclaimer
This is an unofficial client library and is not affiliated with or endorsed by VALR. Use at your own risk.
Support
For issues and questions:
