use crate::{blockchain_client::BlockchainClient, consts, Error};
use lwk_common::electrum_ssl::LIQUID_SOCKET;
use lwk_common::electrum_ssl::LIQUID_TESTNET_SOCKET;
use lwk_common::Network;
use lwk_jade::TIMEOUT;
use lwk_wollet::amp2::Amp2;
use lwk_wollet::asyncr::EsploraClientBuilder;
use lwk_wollet::clients::TokenProvider;
use lwk_wollet::{amp2, ElectrumClient};
use std::fs;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::time::Duration;
#[derive(Clone, Debug)]
pub struct Config {
pub addr: SocketAddr,
pub datadir: PathBuf,
pub server_url: String,
pub server_type: String,
pub network: Network,
pub explorer_url: String,
pub registry_url: String,
pub timeout: Duration,
pub scanning_interval: Duration,
pub amp2_url: String,
pub amp2_keyorigin_xpub: String,
pub with_experimental_blinders: bool,
pub token_provider: TokenProvider,
}
impl Config {
pub fn default_testnet(datadir: PathBuf) -> Self {
Self {
addr: consts::DEFAULT_ADDR.into(),
datadir,
server_url: format!("ssl://{LIQUID_TESTNET_SOCKET}"),
server_type: "electrum".into(),
network: Network::TestnetLiquid,
explorer_url: "https://blockstream.info/liquidtestnet/".into(),
registry_url: "https://assets-testnet.blockstream.info/".into(),
timeout: TIMEOUT,
scanning_interval: consts::SCANNING_INTERVAL,
amp2_url: amp2::URL_TESTNET.into(),
amp2_keyorigin_xpub: amp2::KEYORIGIN_XPUB_TESTNET.into(),
with_experimental_blinders: false,
token_provider: TokenProvider::None,
}
}
pub fn default_mainnet(datadir: PathBuf) -> Self {
Self {
addr: consts::DEFAULT_ADDR.into(),
datadir,
server_url: format!("ssl://{LIQUID_SOCKET}"),
server_type: "electrum".into(),
network: Network::Liquid,
explorer_url: "https://blockstream.info/liquid/".into(),
registry_url: "https://assets.blockstream.info/".into(),
timeout: TIMEOUT,
scanning_interval: consts::SCANNING_INTERVAL,
amp2_url: "".into(),
amp2_keyorigin_xpub: "".into(),
with_experimental_blinders: false,
token_provider: TokenProvider::None,
}
}
pub fn default_regtest(datadir: PathBuf) -> Self {
Self {
addr: consts::DEFAULT_ADDR.into(),
datadir,
server_url: "".into(),
server_type: "electrum".into(),
network: Network::default_regtest(),
explorer_url: "".into(),
registry_url: "".into(),
timeout: TIMEOUT,
scanning_interval: Duration::from_secs(1),
amp2_url: "".into(),
amp2_keyorigin_xpub: "".into(),
with_experimental_blinders: false,
token_provider: TokenProvider::None,
}
}
pub fn jade_network(&self) -> Network {
self.network
}
pub fn default_home() -> Result<PathBuf, Error> {
let mut path = home::home_dir().ok_or(Error::Generic("Cannot get home dir".into()))?;
path.push(".lwk");
fs::create_dir_all(&path)?;
Ok(path)
}
pub fn datadir(&self) -> Result<PathBuf, Error> {
let mut path: PathBuf = self.datadir.clone();
path.push(self.network.as_str());
fs::create_dir_all(&path)?;
Ok(path)
}
pub fn sqlite_path(&self) -> Result<PathBuf, Error> {
let mut path = self.datadir()?;
path.push("lwk.sqlite");
Ok(path)
}
pub fn state_path(&self) -> Result<PathBuf, Error> {
let mut path = self.datadir()?;
path.push("state.json");
Ok(path)
}
pub fn is_mainnet(&self) -> bool {
matches!(self.network, Network::Liquid)
}
pub fn blockchain_client(&self) -> Result<BlockchainClient, Error> {
match self.server_type.as_ref() {
"electrum" => {
let electrum_url = self.server_url.parse().map_err(lwk_wollet::Error::Url)?;
let electrum_client = ElectrumClient::new(&electrum_url)?;
Ok(BlockchainClient::Electrum(electrum_client))
}
"esplora" => {
let builder = EsploraClientBuilder::new(&self.server_url, self.network)
.token_provider(self.token_provider.clone());
let esplora_client = builder.build_blocking()?;
Ok(BlockchainClient::Esplora(esplora_client))
}
"waterfalls" => {
let builder = EsploraClientBuilder::new(&self.server_url, self.network)
.waterfalls(true)
.token_provider(self.token_provider.clone());
let waterfalls_client = builder.build_blocking()?;
Ok(BlockchainClient::Esplora(waterfalls_client))
}
_ => Err(Error::Generic(format!(
"Unsupported server type: {}",
self.server_type
))),
}
}
pub fn amp2_client(&self) -> Result<Amp2, Error> {
if self.is_mainnet() {
return Err(Error::Generic(
"AMP2 methods are not available for mainnet".into(),
));
}
if self.amp2_url.is_empty() {
return Err(Error::Generic(
"on regtest you have to specify --amp2-url".into(),
));
}
if self.amp2_keyorigin_xpub.is_empty() {
return Err(Error::Generic(
"on regtest you have to specify --amp2-keyorigin-xpub".into(),
));
}
let amp2_keyorigin_xpub = self.amp2_keyorigin_xpub.clone();
let amp2_url = self.amp2_url.clone();
let amp_client = Amp2::new(amp2_keyorigin_xpub, amp2_url)?;
Ok(amp_client)
}
}