Implement Solana RPC proxy with automatic failover and caching - Add multi-provider support for 5 free Solana RPC endpoints (Alchemy, PublicNode, Helius, QuickNode, Solana Public) - Implement automatic failover with 30-minute backoff for failed providers - Add disk-based response caching with 100GB LRU eviction - Create SQLite error logging with UUID tracking - Support both HTTP JSON-RPC and WebSocket connections - Include provider-specific authentication handling - Add response normalization for consistent output - Write end-to-end tests for core functionality The proxy provides a unified endpoint that automatically routes requests to available providers, caches responses to reduce load, and logs all errors with retrievable UUIDs for debugging.
70 lines
1.8 KiB
Python
70 lines
1.8 KiB
Python
import os
|
|
import logging
|
|
from dotenv import load_dotenv
|
|
from aiohttp import web
|
|
from providers import create_providers
|
|
from cache import Cache
|
|
from errors import ErrorLogger
|
|
from router import Router
|
|
from http_proxy import setup_routes
|
|
from ws_proxy import setup_ws_routes
|
|
|
|
|
|
def load_config() -> dict:
|
|
load_dotenv()
|
|
|
|
return {
|
|
"proxy_port": int(os.getenv("PROXY_PORT", 8545)),
|
|
"cache_size_gb": int(os.getenv("CACHE_SIZE_GB", 100)),
|
|
"backoff_minutes": int(os.getenv("BACKOFF_MINUTES", 30)),
|
|
"log_level": os.getenv("LOG_LEVEL", "INFO"),
|
|
"error_db_path": os.getenv("ERROR_DB_PATH", "./errors.db"),
|
|
}
|
|
|
|
|
|
def setup_logging(log_level: str) -> None:
|
|
logging.basicConfig(
|
|
level=getattr(logging, log_level.upper()),
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
|
|
|
|
def create_app(config: dict) -> web.Application:
|
|
app = web.Application()
|
|
|
|
providers = create_providers()
|
|
cache = Cache(size_limit_gb=config["cache_size_gb"])
|
|
error_logger = ErrorLogger(db_path=config["error_db_path"])
|
|
router = Router(providers, cache, error_logger)
|
|
|
|
app['router'] = router
|
|
app['config'] = config
|
|
|
|
setup_routes(app)
|
|
setup_ws_routes(app)
|
|
|
|
return app
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
|
config = load_config()
|
|
setup_logging(config["log_level"])
|
|
|
|
logger = logging.getLogger(__name__)
|
|
logger.info(f"Starting Solana RPC Proxy on port {config['proxy_port']}")
|
|
logger.info(f"Cache size limit: {config['cache_size_gb']}GB")
|
|
logger.info(f"Provider backoff time: {config['backoff_minutes']} minutes")
|
|
|
|
app = create_app(config)
|
|
|
|
web.run_app(
|
|
app,
|
|
host='0.0.0.0',
|
|
port=config["proxy_port"]
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |