@runic-rpc/sdk
v0.1.3
Published
Production-grade Solana RPC load balancer with circuit breaking, retries, and health checks
Maintainers
Readme
@runic-rpc/sdk
Ancient reliability for modern Solana infrastructure
Production-grade Solana RPC load balancer with zero runtime dependencies.
Features
- Zero dependencies (only peer @solana/web3.js)
- Circuit breaker prevents cascading failures
- Intelligent routing (round-robin, latency-based, weighted, random)
- Automatic retries with exponential backoff
- Rate limiting per endpoint
- Request caching with TTL
- Request deduplication
- Health checks with configurable intervals
- WebSocket support with auto-reconnect
- Comprehensive events for observability
- Prometheus metrics export
Installation
npm install @runic-rpc/sdk @solana/web3.js
# or
pnpm add @runic-rpc/sdk @solana/web3.js
# or
yarn add @runic-rpc/sdk @solana/web3.jsQuick Start
import { RunicRPC, createHeliusEndpoint } from '@runic-rpc/sdk';
// Simple configuration with Helius
const rpc = new RunicRPC({
providers: {
helius: { apiKey: 'your-api-key' },
},
strategy: 'latency-based',
});
// Make RPC requests
const slot = await rpc.request('getSlot');
const balance = await rpc.request('getBalance', [publicKey]);
// Subscribe to WebSocket events
const subId = await rpc.subscribe(
'accountSubscribe',
[publicKey, { encoding: 'jsonParsed' }],
(data) => {
console.log('Account updated:', data);
}
);
// Cleanup
await rpc.close();Environment Variable Configuration
RunicRPC can automatically load configuration from environment variables and config files:
import { RunicRPC } from '@runic-rpc/sdk';
// Auto-loads from .env and runic.config.json
const rpc = RunicRPC.create();
// Or specify custom paths
const rpc = RunicRPC.create({}, {
envPath: '.env.local',
configPath: './config/runic.config.json',
});Supported Environment Variables
# Provider API Keys
HELIUS_API_KEY=your-helius-key
ALCHEMY_API_KEY=your-alchemy-key
QUICKNODE_RPC_URL=https://your-endpoint.quiknode.pro/token/
QUICKNODE_WS_URL=wss://your-endpoint.quiknode.pro/token/
# Configuration
RUNIC_STRATEGY=latency-based # round-robin, latency-based, weighted, random
RUNIC_LOG_LEVEL=info # debug, info, warn, error
RUNIC_RATE_LIMIT=100 # requests per second
# Framework-specific prefixes also supported:
NEXT_PUBLIC_HELIUS_API_KEY=your-key
VITE_HELIUS_API_KEY=your-keyConfig File (runic.config.json)
{
"providers": {
"helius": { "apiKey": "your-api-key" },
"alchemy": { "apiKey": "your-api-key" }
},
"strategy": "latency-based",
"cache": { "enabled": true, "ttl": 1000 },
"retry": { "maxAttempts": 3 }
}Configuration priority: Code config > Environment variables > Config file
Advanced Configuration
import { RunicRPC } from '@runic-rpc/sdk';
const rpc = new RunicRPC({
// Multiple providers
providers: {
helius: { apiKey: 'helius-key' },
alchemy: { apiKey: 'alchemy-key' },
},
// Routing strategy
strategy: 'latency-based', // or 'round-robin', 'weighted', 'random'
// Cache configuration
cache: {
enabled: true,
ttl: 1000, // 1 second
maxSize: 1000,
},
// Retry configuration
retry: {
maxAttempts: 3,
initialDelay: 100,
maxDelay: 5000,
backoffMultiplier: 2,
},
// Circuit breaker
circuitBreaker: {
failureThreshold: 5,
successThreshold: 2,
timeout: 30000, // 30 seconds
},
// Health checks
healthCheck: {
enabled: true,
interval: 30000, // 30 seconds
timeout: 5000,
unhealthyThreshold: 3,
healthyThreshold: 2,
},
// Rate limiting
rateLimit: 100, // requests per second per endpoint
// Logging
logLevel: 'info', // 'debug', 'info', 'warn', 'error'
});Events
// Listen for events
rpc.on('endpoint:healthy', (event) => {
console.log('Endpoint healthy:', event.endpoint);
});
rpc.on('endpoint:unhealthy', (event) => {
console.log('Endpoint unhealthy:', event.endpoint, event.reason);
});
rpc.on('circuit:open', (event) => {
console.log('Circuit opened:', event.endpoint);
});
rpc.on('request:retry', (event) => {
console.log('Retrying request:', event.method, 'attempt:', event.attempt);
});
rpc.on('cache:hit', (event) => {
console.log('Cache hit:', event.method);
});Metrics
// Get statistics
const stats = rpc.getStats();
console.log('Total requests:', stats.totalRequests);
console.log('Total errors:', stats.totalErrors);
console.log('Cache hit rate:', stats.cacheHitRate);
// Export Prometheus metrics
const metrics = rpc.exportPrometheusMetrics();Providers
Helius
import { createHeliusEndpoint } from '@runic-rpc/sdk';
const endpoint = createHeliusEndpoint('your-api-key');Alchemy
import { createAlchemyEndpoint } from '@runic-rpc/sdk';
const endpoint = createAlchemyEndpoint('your-api-key');QuickNode
import { createQuicknodeEndpoint } from '@runic-rpc/sdk';
const endpoint = createQuicknodeEndpoint(
'https://your-endpoint.quiknode.pro/token/',
'wss://your-endpoint.quiknode.pro/token/'
);Public Fallback
import { createPublicEndpoint } from '@runic-rpc/sdk';
const endpoint = createPublicEndpoint();
// ⚠️ Warning: Public endpoints have strict rate limitsLicense
MIT
