/ fedimint-core / src / envs.rs
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  }