use bdk_wallet::bitcoin::Transaction;
use tokio_util::sync::CancellationToken;
use crate::error::Error;
#[cfg(feature = "bitcoin-rpc")]
pub mod bitcoin_rpc;
#[cfg(feature = "esplora")]
pub mod esplora;
#[derive(Debug, Clone)]
pub struct BitcoinRpcConfig {
pub host: String,
pub port: u16,
pub user: String,
pub password: String,
}
#[derive(Debug, Clone)]
pub struct EsploraConfig {
pub url: String,
pub parallel_requests: usize,
}
#[derive(Debug, Clone)]
pub enum ChainSource {
#[cfg(feature = "esplora")]
Esplora(EsploraConfig),
#[cfg(feature = "bitcoin-rpc")]
BitcoinRpc(BitcoinRpcConfig),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum BroadcastOutcome {
Accepted,
AlreadyKnown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum BroadcastErrorKind {
Rejected,
Transient,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct BroadcastFailure {
pub kind: BroadcastErrorKind,
pub message: String,
}
impl BroadcastFailure {
pub(crate) fn new(kind: BroadcastErrorKind, message: String) -> Self {
Self { kind, message }
}
}
impl ChainSource {
pub async fn sync_wallet(
&self,
cdk_bdk: &crate::CdkBdk,
cancel_token: CancellationToken,
) -> Result<(), Error> {
match self {
#[cfg(feature = "esplora")]
ChainSource::Esplora(config) => {
esplora::sync_esplora(cdk_bdk, config, cancel_token).await
}
#[cfg(feature = "bitcoin-rpc")]
ChainSource::BitcoinRpc(config) => {
bitcoin_rpc::sync_bitcoin_rpc(cdk_bdk, config, cancel_token).await
}
#[allow(unreachable_patterns)]
_ => unreachable!("ChainSource must have at least one feature enabled"),
}
}
pub(crate) async fn broadcast(
&self,
tx: Transaction,
) -> Result<BroadcastOutcome, BroadcastFailure> {
match self {
#[cfg(feature = "esplora")]
ChainSource::Esplora(config) => esplora::broadcast_esplora(config, tx).await,
#[cfg(feature = "bitcoin-rpc")]
ChainSource::BitcoinRpc(config) => bitcoin_rpc::broadcast_bitcoin_rpc(config, tx).await,
#[allow(unreachable_patterns)]
_ => unreachable!("ChainSource must have at least one feature enabled"),
}
}
pub async fn fetch_fee_rate(&self, target_blocks: u16) -> Result<f64, Error> {
match self {
#[cfg(feature = "esplora")]
ChainSource::Esplora(config) => {
esplora::fetch_fee_rate_esplora(config, target_blocks).await
}
#[cfg(feature = "bitcoin-rpc")]
ChainSource::BitcoinRpc(config) => {
bitcoin_rpc::fetch_fee_rate_bitcoin_rpc(config, target_blocks).await
}
#[allow(unreachable_patterns)]
_ => unreachable!("ChainSource must have at least one feature enabled"),
}
}
}