use std::fmt;
use std::path::{Path, PathBuf};
use anyhow::Context;
use bitcoin::{FeeRate, Network};
use bitcoin_ext::{BlockDelta, BlockHeight};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BarkNetwork {
Mainnet,
Signet,
Mutinynet,
Regtest,
}
impl BarkNetwork {
pub fn as_bitcoin(&self) -> Network {
match self {
Self::Mainnet => Network::Bitcoin,
Self::Signet => Network::Signet,
Self::Mutinynet => Network::Signet,
Self::Regtest => Network::Regtest,
}
}
}
impl fmt::Display for BarkNetwork {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Mainnet => f.write_str("mainnet"),
Self::Signet => f.write_str("signet"),
Self::Mutinynet => f.write_str("mutinynet"),
Self::Regtest => f.write_str("regtest"),
}
}
}
impl fmt::Debug for BarkNetwork {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub server_address: String,
pub server_access_token: Option<String>,
pub esplora_address: Option<String>,
pub bitcoind_address: Option<String>,
pub bitcoind_cookiefile: Option<PathBuf>,
pub bitcoind_user: Option<String>,
pub bitcoind_pass: Option<String>,
pub vtxo_refresh_expiry_threshold: BlockHeight,
pub vtxo_exit_margin: BlockDelta,
pub htlc_recv_claim_delta: BlockDelta,
#[cfg(feature = "socks5-proxy")]
pub socks5_proxy: Option<String>,
pub fallback_fee_rate: Option<FeeRate>,
pub round_tx_required_confirmations: BlockHeight,
pub offboard_required_confirmations: BlockHeight,
pub daemon_fast_sync_interval_secs: u64,
pub daemon_slow_sync_interval_secs: u64,
pub daemon_manual_sync: bool,
}
impl Config {
pub fn network_default(network: Network) -> Self {
let mut ret = Self {
server_address: "http://127.0.0.1:3535".to_owned(),
server_access_token: None,
esplora_address: None,
bitcoind_address: None,
bitcoind_cookiefile: None,
bitcoind_user: None,
bitcoind_pass: None,
#[cfg(feature = "socks5-proxy")]
socks5_proxy: None,
vtxo_refresh_expiry_threshold: 144,
vtxo_exit_margin: 12,
htlc_recv_claim_delta: 18,
fallback_fee_rate: Some(FeeRate::from_sat_per_vb_unchecked(2)),
round_tx_required_confirmations: 1,
offboard_required_confirmations: 2,
daemon_fast_sync_interval_secs: 1,
daemon_slow_sync_interval_secs: 60,
daemon_manual_sync: false,
};
if network != Network::Bitcoin {
ret.vtxo_refresh_expiry_threshold = 12;
ret.fallback_fee_rate = Some(FeeRate::from_sat_per_vb_unchecked(1));
ret.round_tx_required_confirmations = 1;
ret.offboard_required_confirmations = 0;
}
ret
}
pub fn load(network: Network, path: impl AsRef<Path>) -> anyhow::Result<Config> {
let default = config::Config::try_from(&Self::network_default(network))
.expect("default config failed to deconstruct");
Ok(config::Config::builder()
.add_source(default)
.add_source(config::File::from(path.as_ref()).required(false))
.add_source(config::Environment::with_prefix("BARK"))
.build().context("error building config")?
.try_deserialize::<Config>().context("error parsing config")?)
}
}