"""Resolver di ambiente (testnet/mainnet) per MCP exchange. Precedenza: env var > campo secret > default True (testnet). """ from __future__ import annotations import os from dataclasses import dataclass from typing import Literal Environment = Literal["testnet", "mainnet"] Source = Literal["env", "credentials", "default"] TRUTHY = {"1", "true", "yes", "on"} @dataclass(frozen=True) class EnvironmentInfo: exchange: str environment: Environment source: Source env_value: str | None base_url: str def resolve_environment( creds: dict, *, env_var: str, flag_key: str, exchange: str, default_base_url_live: str | None = None, default_base_url_testnet: str | None = None, ) -> EnvironmentInfo: """Risolvi l'ambiente per un MCP exchange. creds: dict letto dal secret JSON. Può contenere base_url_live/base_url_testnet per override; in assenza vengono usati i default kwargs. env_var: nome della env var di override (es. DERIBIT_TESTNET). flag_key: chiave booleana nel secret JSON (es. "testnet" o "paper" per alpaca). exchange: nome exchange per logging/info. default_base_url_live / default_base_url_testnet: URL canonici dell'exchange, applicati se non presenti in creds. """ env_value = os.environ.get(env_var) if env_value is not None: is_test = env_value.strip().lower() in TRUTHY environment: Environment = "testnet" if is_test else "mainnet" source: Source = "env" elif flag_key in creds: environment = "testnet" if bool(creds[flag_key]) else "mainnet" source = "credentials" else: environment = "testnet" source = "default" if default_base_url_live is not None: creds.setdefault("base_url_live", default_base_url_live) if default_base_url_testnet is not None: creds.setdefault("base_url_testnet", default_base_url_testnet) base_url = creds["base_url_testnet"] if environment == "testnet" else creds["base_url_live"] return EnvironmentInfo( exchange=exchange, environment=environment, source=source, env_value=env_value, base_url=base_url, )