A sophisticated NestJS-based trading platform with Unified API Architecture supporting multiple perpetual futures exchanges including Aster DEX, Hyperliquid, Binance Futures, and OKX Perpetuals.
- β Unified API: Single set of endpoints serving all exchanges
- β Factory Pattern: Dynamic service resolution at runtime via Exchange Factory
- β Interface-Driven: Clean separation between interfaces and implementations
- β Type-Safe: Full TypeScript with strict mode enabled
- β Modular Design: Each exchange is a self-contained module
- β Plug & Play: Add new exchanges by implementing standard interfaces
- β Aster DEX: Decentralized perpetual futures (with WebSocket support)
- β Hyperliquid: On-chain perpetual futures (with WebSocket support)
- β Binance Futures: Centralized perpetual futures
- β OKX Perpetuals: Centralized perpetual futures
- β Trading Operations: Market/limit orders, position management, leverage control
- β Risk Management: Stop-loss, take-profit, margin management
- β Balance & Portfolio: Real-time balance tracking, P&L calculation, portfolio value
- β Market Data: Real-time prices, orderbook depth, historical candles, funding rates
- β Symbol Normalization: Automatic symbol format conversion across exchanges
- β
REST API: Comprehensive Swagger documentation at
/api - β WebSocket Support: Real-time market data and account updates
- β Authentication: API Key guard for secure access
- β Error Handling: Standardized error responses
- β Clean Architecture: Modular, testable, maintainable codebase
# Install dependencies
pnpm installCreate a .env file in the root directory with your exchange API credentials:
# Application Settings
NODE_ENV=development
PORT=3000
LOG_LEVEL=debug
# API Access Control (REQUIRED!)
# This key protects all endpoints
API_KEY_ACCESS=your_secure_api_key_here
# Aster DEX Configuration
ASTER_API_KEY=your_aster_api_key
ASTER_API_SECRET=your_aster_api_secret
ASTER_USER_ADDRESS=your_wallet_address
ASTER_SIGNER_ADDRESS=your_signer_address
ASTER_PRIVATE_KEY=your_private_key
ASTER_REST_URL=https://fapi.asterdex.com
ASTER_WS_URL=wss://fstream.asterdex.com
# Hyperliquid Configuration
HYPERLIQUID_REST_URL=https://api.hyperliquid.xyz
HYPERLIQUID_WS_URL=wss://api.hyperliquid.xyz/ws
HYPERLIQUID_WALLET_ADDRESS=your_wallet_address
HYPERLIQUID_PRIVATE_KEY=your_private_key
HYPERLIQUID_TESTNET=false
# Binance Futures Configuration (Optional)
BINANCE_API_KEY=your_binance_api_key
BINANCE_API_SECRET=your_binance_api_secret
BINANCE_REST_URL=https://fapi.binance.com
BINANCE_TESTNET=false
# OKX Perpetuals Configuration (Optional)
OKX_API_KEY=your_okx_api_key
OKX_API_SECRET=your_okx_api_secret
OKX_PASSPHRASE=your_okx_passphrase
OKX_REST_URL=https://www.okx.com
OKX_TESTNET=falseSecurity Note: The API_KEY_ACCESS is required in the X-API-Key header for all requests to protected endpoints.
# Development mode with hot reload
pnpm start:dev
# Production mode
pnpm build
pnpm start:prodThe application will be available at:
- API: http://localhost:3000
- Swagger Documentation: http://localhost:3000/api
All trading endpoints require API key authentication using the X-API-Key header.
Required Header:
X-API-Key: your_api_key_access_here- Open http://localhost:3000/api
- Click the "Authorize" button (lock icon) at the top
- Enter your
API_KEY_ACCESSfrom.envfile - Click "Authorize" and "Close"
- Now you can test all endpoints directly in the browser
curl -H "X-API-Key: your_api_key_access_here" \
http://localhost:3000/balance?exchange=asterAll endpoints follow a unified pattern: /{resource}?exchange={exchange_name}
GET /balance?exchange={exchange}- Get account balance and positionsGET /balance/portfolio?exchange={exchange}- Get portfolio summaryGET /balance/positions?exchange={exchange}- Get all open positionsGET /balance/position?exchange={exchange}&symbol={symbol}- Get specific position
Example:
# Get Aster balance
curl -H "X-API-Key: your_key" \
"http://localhost:3000/balance?exchange=aster"
# Get Hyperliquid positions
curl -H "X-API-Key: your_key" \
"http://localhost:3000/balance/positions?exchange=hyperliquid"GET /market/symbols?exchange={exchange}- Get all tradable symbolsGET /market/ticker?exchange={exchange}&symbol={symbol}- Get 24hr tickerGET /market/orderbook?exchange={exchange}&symbol={symbol}- Get order bookGET /market/trades?exchange={exchange}&symbol={symbol}- Get recent tradesGET /market/candles?exchange={exchange}&symbol={symbol}&interval={interval}- Get klines/candlesGET /market/funding?exchange={exchange}&symbol={symbol}- Get funding rate history
Example:
# Get BTC ticker from Binance
curl -H "X-API-Key: your_key" \
"http://localhost:3000/market/ticker?exchange=binance&symbol=BTC-USDT"
# Get ETH orderbook from Hyperliquid
curl -H "X-API-Key: your_key" \
"http://localhost:3000/market/orderbook?exchange=hyperliquid&symbol=ETH-USD"POST /trading/order/market- Place market orderPOST /trading/order/limit- Place limit orderPOST /trading/order/cancel- Cancel orderPOST /trading/order/cancel-all- Cancel all ordersGET /trading/orders?exchange={exchange}- Get open ordersPOST /trading/leverage- Set leveragePOST /trading/position/close- Close position
Market Order Example:
curl -X POST -H "X-API-Key: your_key" \
-H "Content-Type: application/json" \
"http://localhost:3000/trading/order/market" \
-d '{
"exchange": "aster",
"symbol": "BTC-USDT",
"side": "BUY",
"quantity": 0.001
}'Limit Order Example:
curl -X POST -H "X-API-Key: your_key" \
-H "Content-Type: application/json" \
"http://localhost:3000/trading/order/limit" \
-d '{
"exchange": "hyperliquid",
"symbol": "ETH-USD",
"side": "SELL",
"quantity": 0.1,
"price": 3500
}'Close Position Example:
curl -X POST -H "X-API-Key: your_key" \
-H "Content-Type: application/json" \
"http://localhost:3000/trading/position/close" \
-d '{
"exchange": "binance",
"symbol": "BTC-USDT"
}'src/
βββ api/ # Unified API Layer
β βββ controllers/ # REST API Controllers
β β βββ balance.controller.ts # Balance & portfolio endpoints
β β βββ market.controller.ts # Market data endpoints
β β βββ trading.controller.ts # Trading endpoints
β βββ api.module.ts # API module configuration
β
βββ common/ # Shared Utilities
β βββ decorators/ # Custom decorators
β β βββ api-key.decorator.ts # API key extraction
β β βββ public.decorator.ts # Public endpoint marker
β βββ dto/ # Data Transfer Objects
β β βββ exchange.dto.ts # Exchange selection DTOs
β β βββ trading.dto.ts # Trading operation DTOs
β βββ factory/ # Factory Pattern
β β βββ exchange.factory.ts # Dynamic service resolution
β βββ guards/ # Authentication Guards
β β βββ api-key.guard.ts # API key validation
β βββ interfaces/ # Standard Interfaces
β β βββ balance.interface.ts # Balance operations
β β βββ market.interface.ts # Market data operations
β β βββ trading.interface.ts # Trading operations
β βββ middleware/ # HTTP Middleware
β β βββ symbol-normalizer.middleware.ts # Symbol format conversion
β βββ services/ # Common Services
β β βββ symbol-normalizer.service.ts # Symbol normalization logic
β βββ types/ # Type Definitions
β βββ exchange.types.ts # Exchange enums and types
β
βββ exchanges/ # Exchange Integrations
β βββ aster/ # Aster DEX
β β βββ perpetual/
β β β βββ services/
β β β β βββ perpetual-balance.service.ts
β β β β βββ perpetual-market.service.ts
β β β β βββ perpetual-trading.service.ts
β β β βββ perpetual.module.ts
β β βββ shared/
β β β βββ aster-api.service.ts # REST API client
β β β βββ aster-websocket.service.ts # WebSocket client
β β βββ types/ # Type definitions
β β βββ aster.module.ts
β β
β βββ hyperliquid/ # Hyperliquid
β β βββ perp/
β β β βββ services/
β β β β βββ balance.service.ts
β β β β βββ market-data.service.ts
β β β β βββ order-management.service.ts
β β β β βββ order-placement.service.ts
β β β βββ perp.module.ts
β β βββ shared/
β β β βββ hyperliquid-api.service.ts # REST API client
β β β βββ signing.service.ts # Signature generation
β β βββ types/
β β βββ hyperliquid.module.ts
β β
β βββ binance/ # Binance Futures
β β βββ perpetual/
β β β βββ services/
β β β β βββ perpetual-balance.service.ts
β β β β βββ perpetual-market.service.ts
β β β β βββ perpetual-trading.service.ts
β β β βββ perpetual.module.ts
β β βββ shared/
β β β βββ binance-api.service.ts
β β βββ types/
β β βββ binance.module.ts
β β
β βββ okx/ # OKX Perpetuals
β β βββ perpetual/
β β β βββ services/
β β β β βββ perpetual-balance.service.ts
β β β β βββ perpetual-market.service.ts
β β β β βββ perpetual-trading.service.ts
β β β βββ perpetual.module.ts
β β βββ shared/
β β β βββ okx-api.service.ts
β β βββ types/
β β βββ okx.module.ts
β β
β βββ exchanges.module.ts # Exchanges module aggregator
β
βββ config/ # Configuration Files
β βββ app.config.ts # App settings
β βββ aster.config.ts # Aster configuration
β βββ binance.config.ts # Binance configuration
β βββ hyperliquid.config.ts # Hyperliquid configuration
β βββ okx.config.ts # OKX configuration
β βββ trading.config.ts # Trading settings
β
βββ app.module.ts # Root module
βββ main.ts # Application entry point
Instead of separate endpoints per exchange, we use a unified pattern:
Traditional Approach (Bad):
- /aster/balance
- /hyperliquid/balance
- /binance/balance
- /okx/balance
β 4 exchanges Γ 50 operations = 200 endpoints!
Unified Approach (Good):
- /balance?exchange=aster
- /balance?exchange=hyperliquid
- /balance?exchange=binance
- /balance?exchange=okx
β 50 endpoints serving all exchanges
The ExchangeFactory dynamically resolves the correct service based on the exchange parameter:
// Client request
GET /balance?exchange=aster
// Factory resolves
ExchangeFactory β AsterPerpetualBalanceService β Execute
// Client request
GET /balance?exchange=hyperliquid
// Factory resolves
ExchangeFactory β HyperliquidBalanceService β ExecuteAll exchange implementations follow standard interfaces:
IBalanceService: Balance and portfolio operationsIMarketDataService: Market data operationsITradingService: Trading operations
This ensures:
- Consistency: All exchanges work the same way
- Testability: Easy to mock and test
- Maintainability: Changes in one place affect all exchanges
- Extensibility: New exchanges just implement interfaces
Each exchange uses different symbol formats:
- Aster:
BTCUSDT - Hyperliquid:
BTC - Binance:
BTCUSDT - OKX:
BTC-USDT-SWAP
The SymbolNormalizerMiddleware automatically converts symbols:
Client β "BTC-USDT" β Middleware β "BTCUSDT" (Aster)
Client β "BTC-USDT" β Middleware β "BTC" (Hyperliquid)
Client β "BTC-USDT" β Middleware β "BTC-USDT-SWAP" (OKX)
| Variable | Description | Required | Default |
|---|---|---|---|
API_KEY_ACCESS |
API key for endpoint authentication | Yes | - |
PORT |
Application port | No | 3000 |
NODE_ENV |
Environment mode | No | development |
LOG_LEVEL |
Logging level | No | debug |
Aster DEX:
| Variable | Description | Required |
|---|---|---|
ASTER_API_KEY |
Aster API key | Yes |
ASTER_API_SECRET |
Aster API secret | Yes |
ASTER_USER_ADDRESS |
Wallet address | Yes |
ASTER_SIGNER_ADDRESS |
Signer address | Yes |
ASTER_PRIVATE_KEY |
Private key | Yes |
ASTER_REST_URL |
REST API URL | No |
ASTER_WS_URL |
WebSocket URL | No |
Hyperliquid:
| Variable | Description | Required |
|---|---|---|
HYPERLIQUID_WALLET_ADDRESS |
Wallet address | Yes |
HYPERLIQUID_PRIVATE_KEY |
Private key | Yes |
HYPERLIQUID_REST_URL |
REST API URL | No |
HYPERLIQUID_WS_URL |
WebSocket URL | No |
HYPERLIQUID_TESTNET |
Use testnet | No |
Binance Futures:
| Variable | Description | Required |
|---|---|---|
BINANCE_API_KEY |
Binance API key | Yes |
BINANCE_API_SECRET |
Binance API secret | Yes |
BINANCE_REST_URL |
REST API URL | No |
BINANCE_TESTNET |
Use testnet | No |
OKX Perpetuals:
| Variable | Description | Required |
|---|---|---|
OKX_API_KEY |
OKX API key | Yes |
OKX_API_SECRET |
OKX API secret | Yes |
OKX_PASSPHRASE |
OKX passphrase | Yes |
OKX_REST_URL |
REST API URL | No |
OKX_TESTNET |
Use testnet | No |
# Development
pnpm start:dev # Start with hot reload
pnpm build # Build for production
pnpm start:prod # Start production build
# Testing
pnpm test # Run unit tests
pnpm test:watch # Run tests in watch mode
pnpm test:cov # Generate coverage report
pnpm test:e2e # Run end-to-end tests
# Code Quality
pnpm lint # Run ESLint
pnpm format # Format code with PrettierTo add support for a new exchange:
-
Create exchange module structure:
mkdir -p src/exchanges/newexchange/perpetual/services mkdir -p src/exchanges/newexchange/shared mkdir -p src/exchanges/newexchange/types
-
Implement standard interfaces:
Create services implementing:
IBalanceService(balance operations)IMarketDataService(market data)ITradingService(trading operations)
-
Create API service:
Implement REST API client in
shared/newexchange-api.service.ts -
Define types:
Add exchange-specific types in
types/index.ts -
Create configuration:
Add config in
src/config/newexchange.config.ts -
Register in factory:
Add exchange to
ExchangeFactoryresolution logic -
Update exchange enum:
Add to
ExchangeNameenum incommon/types/exchange.types.ts -
Test thoroughly:
Create unit tests for all services
- Environment Variables: Sensitive data stored securely in
.env - API Key Authentication: All endpoints protected with API key guard
- HMAC Signatures: Secure API authentication for supported exchanges
- Input Validation: Comprehensive validation using class-validator
- Rate Limiting: Built-in protection against API rate limits
- Error Sanitization: Sensitive information removed from logs
The application uses structured logging with contextual information:
- Error: System errors and critical failures
- Warn: Non-critical issues and warnings
- Info: General application information
- Debug: Detailed debugging information (set
LOG_LEVEL=debug)
Logs include request IDs, exchange names, and operation metadata for easy troubleshooting.
Connection Failed:
- Verify API credentials in
.envfile - Check network connectivity
- Ensure exchange API is accessible
Invalid Signature:
- Verify API secret is correct
- Check system time synchronization
- Ensure timestamp is within acceptable range
Rate Limited:
- Reduce request frequency
- Implement exponential backoff
- Check exchange rate limit documentation
Symbol Not Found:
- Verify symbol format for the specific exchange
- Check if symbol is supported by the exchange
- Use
/market/symbolsendpoint to list available symbols
Enable detailed logging:
LOG_LEVEL=debug pnpm start:devAll API responses follow a standardized format:
Success Response:
{
"success": true,
"data": {
// Response data here
},
"timestamp": "2024-01-01T00:00:00.000Z"
}Error Response:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Error description",
"details": {}
},
"timestamp": "2024-01-01T00:00:00.000Z"
}# Build image
docker build -t perps-vibe-ai .
# Run container
docker run -d \
--name perps-vibe-ai \
-p 3000:3000 \
--env-file .env \
perps-vibe-ai# Deploy to Google Cloud Run
./scripts/deploy-cloudrun.shFor detailed documentation, see the .docs folder:
- Architecture guides
- API authentication details
- Exchange-specific documentation
- Trading strategies
- WebSocket integration guides
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Implement your changes
- Add tests for new features
- Submit a pull request
MIT License - see LICENSE file for details.
Important: This is a trading platform that can place real orders and spend real money. Always:
- Test thoroughly in testnet/sandbox environments
- Start with small amounts
- Implement proper risk management
- Monitor positions actively
- Use at your own risk
The developers are not responsible for any financial losses incurred while using this platform.