envs.rs
1 use std::env; 2 3 use anyhow::Context; 4 use fedimint_core::util::SafeUrl; 5 use fedimint_derive::{Decodable, Encodable}; 6 use fedimint_logging::LOG_CORE; 7 use jsonrpsee_core::Serialize; 8 use serde::Deserialize; 9 use tracing::warn; 10 11 // Note: Keep in sync with `fedimint_build::envs`, which is not reused-to avoid 12 // introducing extra dependencies between core and build modules. 13 pub const FEDIMINT_BUILD_CODE_VERSION_ENV: &str = "FEDIMINT_BUILD_CODE_VERSION"; 14 15 /// In tests we want to routinely enable an extra unknown module to ensure 16 /// all client code handles correct modules that client doesn't know about. 17 pub const FM_USE_UNKNOWN_MODULE_ENV: &str = "FM_USE_UNKNOWN_MODULE"; 18 19 /// Check if env variable is set and not equal `0` or `false` which are common 20 /// ways to disable something. 21 pub fn is_env_var_set(var: &str) -> bool { 22 std::env::var_os(var).is_some_and(|v| v != "0" && v != "false") 23 } 24 25 /// Use to detect if running in a test environment, either `cargo test` or 26 /// `devimint`. 27 pub fn is_running_in_test_env() -> bool { 28 let unit_test = cfg!(test); 29 30 unit_test || is_env_var_set("NEXTEST") || is_env_var_set(FM_IN_DEVIMINT_ENV) 31 } 32 33 /// Get value of [`FEDIMINT_BUILD_CODE_VERSION_ENV`] at compile time 34 #[macro_export] 35 macro_rules! fedimint_build_code_version_env { 36 () => { 37 env!("FEDIMINT_BUILD_CODE_VERSION") 38 }; 39 } 40 41 /// Env var for bitcoin RPC kind (obsolete, use FM_DEFAULT_* instead) 42 pub const FM_BITCOIN_RPC_KIND_ENV: &str = "FM_BITCOIN_RPC_KIND"; 43 /// Env var for bitcoin URL (obsolete, use FM_DEFAULT_* instead) 44 pub const FM_BITCOIN_RPC_URL_ENV: &str = "FM_BITCOIN_RPC_URL"; 45 46 /// Env var for bitcoin RPC kind (default, used only as a default value for DKG 47 /// config settings) 48 pub const FM_DEFAULT_BITCOIN_RPC_KIND_ENV: &str = "FM_DEFAULT_BITCOIND_RPC_KIND"; 49 /// Env var for bitcoin URL (default, used only as a default value for DKG 50 /// config settings) 51 pub const FM_DEFAULT_BITCOIN_RPC_URL_ENV: &str = "FM_DEFAULT_BITCOIND_RPC_URL"; 52 53 /// Env var for bitcoin RPC kind (forced, takes priority over config settings) 54 pub const FM_FORCE_BITCOIN_RPC_KIND_ENV: &str = "FM_FORCE_BITCOIND_RPC_KIND"; 55 /// Env var for bitcoin URL (default, takes priority over config settings) 56 pub const FM_FORCE_BITCOIN_RPC_URL_ENV: &str = "FM_FORCE_BITCOIND_RPC_URL"; 57 58 /// Env var that can be set to point at the bitcoind's cookie file to use for 59 /// auth 60 pub const FM_BITCOIND_COOKIE_FILE_ENV: &str = "FM_BITCOIND_COOKIE_FILE"; 61 62 /// `devimint` will set when code is running inside `devimint` 63 pub const FM_IN_DEVIMINT_ENV: &str = "FM_IN_DEVIMINT"; 64 65 /// Configuration for the bitcoin RPC 66 #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize, Encodable, Decodable)] 67 pub struct BitcoinRpcConfig { 68 pub kind: String, 69 pub url: SafeUrl, 70 } 71 72 impl BitcoinRpcConfig { 73 pub fn get_defaults_from_env_vars() -> anyhow::Result<Self> { 74 Ok(Self { 75 kind: env::var(FM_DEFAULT_BITCOIN_RPC_KIND_ENV) 76 .or_else(|_| env::var(FM_BITCOIN_RPC_KIND_ENV).map(|v| { 77 warn!(target: LOG_CORE, "{FM_BITCOIN_RPC_KIND_ENV} is obsolete, use {FM_DEFAULT_BITCOIN_RPC_KIND_ENV} instead"); 78 v 79 }) 80 ) 81 .with_context(|| { 82 anyhow::anyhow!("failure looking up env var {FM_DEFAULT_BITCOIN_RPC_KIND_ENV}") 83 })?, 84 url: env::var(FM_DEFAULT_BITCOIN_RPC_URL_ENV) 85 .or_else(|_| env::var(FM_BITCOIN_RPC_URL_ENV).map(|v| { 86 warn!(target: LOG_CORE, "{FM_BITCOIN_RPC_URL_ENV} is obsolete, use {FM_DEFAULT_BITCOIN_RPC_URL_ENV} instead"); 87 v 88 }) 89 ) 90 .with_context(|| { 91 anyhow::anyhow!("failure looking up env var {FM_DEFAULT_BITCOIN_RPC_URL_ENV}") 92 })?.parse().with_context(|| { 93 anyhow::anyhow!("failure parsing env var {FM_DEFAULT_BITCOIN_RPC_URL_ENV}") 94 })? 95 , 96 }) 97 } 98 }