"""Builder centralizzato di client per ClientRegistry.""" from __future__ import annotations from typing import Literal from cerbero_mcp.settings import Settings Environment = Literal["testnet", "mainnet"] async def build_client( settings: Settings, exchange: str, env: Environment ): if exchange == "deribit": from cerbero_mcp.exchanges.deribit.client import DeribitClient url = settings.deribit.url_testnet if env == "testnet" else settings.deribit.url_live cid, csec = settings.deribit.credentials(env) return DeribitClient( client_id=cid, client_secret=csec, testnet=(env == "testnet"), base_url_override=url, ) if exchange == "hyperliquid": from cerbero_mcp.exchanges.hyperliquid.client import HyperliquidClient url = settings.hyperliquid.url_testnet if env == "testnet" else settings.hyperliquid.url_live return HyperliquidClient( wallet_address=settings.hyperliquid.wallet_address, private_key=settings.hyperliquid.private_key.get_secret_value(), testnet=(env == "testnet"), api_wallet_address=settings.hyperliquid.api_wallet_address, base_url=url, ) if exchange == "macro": # Read-only data provider — env ignored. Il registry # istanzia comunque 2 entry (testnet/mainnet); costo trascurabile # (wrapper stateless senza HTTP session). from cerbero_mcp.exchanges.macro.client import MacroClient return MacroClient( fred_api_key=settings.macro.fred_api_key.get_secret_value(), finnhub_api_key=settings.macro.finnhub_api_key.get_secret_value(), ) if exchange == "sentiment": # Read-only data provider — env ignored (CryptoPanic, LunarCrush e # endpoint pubblici di funding/OI multi-exchange sono unici). from cerbero_mcp.exchanges.sentiment.client import SentimentClient return SentimentClient( cryptopanic_key=settings.sentiment.cryptopanic_key.get_secret_value(), lunarcrush_key=settings.sentiment.lunarcrush_key.get_secret_value(), ) if exchange == "ibkr": from cerbero_mcp.exchanges.ibkr.client import IBKRClient from cerbero_mcp.exchanges.ibkr.oauth import OAuth1aSigner creds = settings.ibkr.credentials(env) url = settings.ibkr.url_testnet if env == "testnet" else settings.ibkr.url_live signer = OAuth1aSigner( consumer_key=creds["consumer_key"], access_token=creds["access_token"], access_token_secret=creds["access_token_secret"], signature_key_path=creds["signature_key_path"], encryption_key_path=creds["encryption_key_path"], dh_prime=creds["dh_prime"], ) return IBKRClient( signer=signer, account_id=creds["account_id"], paper=(env == "testnet"), base_url=url, ) raise ValueError(f"unsupported exchange: {exchange}")