diff --git a/.env b/.env index 902db39..b66e07a 100644 --- a/.env +++ b/.env @@ -31,18 +31,24 @@ API_SECRET_KEY=2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb # Solana RPC URL (Required for blockchain access) # -# CRITICAL: Primary RPC for all trading operations -# Current: Alchemy (300M compute units/month free tier) +# CRITICAL: Primary RPC for normal trading operations +# Current: Alchemy (300M compute units/month free tier, excellent stability) SOLANA_RPC_URL=https://solana-mainnet.g.alchemy.com/v2/5A0iA5UYpsmP9gkuezYeg # Fallback RPC URL (Optional but HIGHLY recommended) -# Automatically switches to fallback after 2 consecutive rate limits -# Use a different provider than primary for best redundancy -SOLANA_FALLBACK_RPC_URL=https://mainnet.helius-rpc.com/v1/?api-key=dcca4bf0-0b91-4f6a-8d12-1c5a4c1c6e5b +# +# SMART STRATEGY (DISABLED - Helius API key issue): +# 1. Bot STARTS with fallback (Helius) - handles startup burst better (10 req/sec sustained) +# 2. After init, SWITCHES to primary (Alchemy) - more stable for trading operations +# 3. On 429 errors, falls back to Helius temporarily, then returns to Alchemy +# +# TEMPORARILY DISABLED: Set to empty until Helius API key fixed +# SOLANA_FALLBACK_RPC_URL=https://mainnet.helius-rpc.com/?api-key=dcca4bf0-0b91-4f6a-8d12-1c5a4c1c6e5b +SOLANA_FALLBACK_RPC_URL= # RPC Provider Comparison (as of Nov 2025): -# ✅ Alchemy: 300M CU/month, excellent for primary (CURRENT PRIMARY) -# ⚠️ Helius: 10 req/sec sustained (free tier), good for fallback only +# ✅ Alchemy: 300M CU/month, excellent for trading operations (PRIMARY) +# ✅ Helius: 10 req/sec sustained, perfect for startup bursts (STARTUP + FALLBACK) # QuickNode: Paid plans, very reliable # Ankr/Public: Unreliable, not recommended diff --git a/lib/drift/client.ts b/lib/drift/client.ts index 9f42282..adc25c7 100644 --- a/lib/drift/client.ts +++ b/lib/drift/client.ts @@ -35,13 +35,25 @@ export class DriftService { private usingFallback: boolean = false constructor(private config: DriftConfig) { - this.connection = new Connection(config.rpcUrl, 'confirmed') - this.currentRpcUrl = config.rpcUrl + // SMART STARTUP: Use fallback (Helius) for initialization burst, then switch to primary (Alchemy) + // Helius handles the burst better, Alchemy is more stable for ongoing operations + const useHeliusForStartup = config.fallbackRpcUrl && !process.env.DISABLE_STARTUP_FALLBACK - // Initialize fallback connection if provided - if (config.fallbackRpcUrl) { - this.fallbackConnection = new Connection(config.fallbackRpcUrl, 'confirmed') - console.log('🔄 Fallback RPC configured:', this.maskRpcUrl(config.fallbackRpcUrl)) + if (useHeliusForStartup) { + console.log('🚀 Using fallback RPC for startup initialization (handles bursts better)') + this.connection = new Connection(config.fallbackRpcUrl!, 'confirmed') + this.currentRpcUrl = config.fallbackRpcUrl! + this.usingFallback = true + this.fallbackConnection = new Connection(config.rpcUrl, 'confirmed') // Primary becomes the "fallback" temporarily + } else { + this.connection = new Connection(config.rpcUrl, 'confirmed') + this.currentRpcUrl = config.rpcUrl + + // Initialize fallback connection if provided + if (config.fallbackRpcUrl) { + this.fallbackConnection = new Connection(config.fallbackRpcUrl, 'confirmed') + console.log('🔄 Fallback RPC configured:', this.maskRpcUrl(config.fallbackRpcUrl)) + } } // Create wallet from private key @@ -235,6 +247,35 @@ export class DriftService { this.isInitialized = true console.log('✅ Drift service initialized successfully') + // After successful initialization, switch to primary RPC if we started with fallback + if (this.usingFallback && this.fallbackConnection && this.driftClient) { + console.log('🔄 Startup complete - switching from Helius to Alchemy for normal operations') + + // Swap connections: primary (Alchemy) becomes active, fallback (Helius) becomes backup + const temp = this.connection + this.connection = this.fallbackConnection + this.fallbackConnection = temp + this.usingFallback = false + this.consecutiveRateLimits = 0 + + // Reinitialize SDK with new connection + const sdkConfig = initialize({ + env: this.config.env === 'devnet' ? 'devnet' : 'mainnet-beta' + }) + + // Update Drift client's connection reference + this.driftClient = new DriftClient({ + connection: this.connection, + wallet: this.wallet as any, + programID: new PublicKey(sdkConfig.DRIFT_PROGRAM_ID), + opts: { commitment: 'confirmed' } + }) + await this.driftClient.subscribe() + this.user = this.driftClient.getUser() + + console.log('✅ Now using Alchemy for stable trading operations') + } + } catch (error) { console.error('❌ Failed to initialize Drift service after retries:', error) throw error