newton-core 0.4.16

newton protocol core sdk
use std::{path::Path, str::FromStr};

use dotenvy;

/// Initialize environment variables from .env file.
///
/// Resolution order:
/// 1. Chain-specific .env in cwd (e.g., `.env.mainnet.prod`, `.env.sepolia.stagef`)
/// 2. Generic `.env` in cwd
/// 3. `~/.newton/.env`
/// 4. No .env file (returns Ok — env files are optional)
pub fn init() -> Result<(), dotenvy::Error> {
    let cwd = std::env::current_dir()
        .map(|p| p.to_string_lossy().to_string())
        .unwrap_or_else(|_| ".".to_string());

    let chain_id = std::env::var("CHAIN_ID")
        .unwrap_or_else(|_| "31337".to_string())
        .parse::<u64>()
        .unwrap_or(31337);
    let deployment_env = std::env::var("DEPLOYMENT_ENV").unwrap_or_else(|_| "stagef".to_string());

    let chain_env_file = match chain_id {
        1 => Some(format!(".env.mainnet.{deployment_env}")),
        11155111 => Some(format!(".env.sepolia.{deployment_env}")),
        _ => None,
    };

    // Try chain-specific env file in cwd
    if let Some(ref env_file) = chain_env_file {
        let path = format!("{cwd}/{env_file}");
        if Path::new(&path).exists() {
            tracing::info!("Loading environment variables from {path}");
            return dotenvy::from_path(Path::new(&path));
        }
    }

    // Try generic .env in cwd
    let cwd_env = format!("{cwd}/.env");
    if Path::new(&cwd_env).exists() {
        tracing::info!("Loading environment variables from {cwd_env}");
        return dotenvy::from_path(Path::new(&cwd_env));
    }

    // Try ~/.newton/.env
    if let Ok(home) = std::env::var("HOME") {
        let home_env = format!("{home}/.newton/.env");
        if Path::new(&home_env).exists() {
            tracing::info!("Loading environment variables from {home_env}");
            return dotenvy::from_path(Path::new(&home_env));
        }
    }

    Ok(())
}

/// Get environment variable
/// # Arguments
/// * `parameter` - The parameter to get
/// # Returns
/// The value of the environment variable, or the default value if the environment variable is not set
pub fn get<T: FromStr + Default>(parameter: &str) -> T {
    std::env::var(parameter)
        .map(|s| s.parse().unwrap_or(T::default()))
        .unwrap_or_default()
}