use std::collections::HashMap;
use rgb::bitcoin::{Transaction as Tx, Txid};
use rgbcore::validation::{ResolveWitness, WitnessResolverError, WitnessStatus};
use rgbcore::vm::WitnessOrd;
use rgbcore::ChainNet;
use crate::containers::Consignment;
#[derive(From)]
#[non_exhaustive]
pub struct AnyResolver {
inner: Box<dyn ResolveWitness + Send>,
consignment_txes: HashMap<Txid, Tx>,
}
impl AnyResolver {
#[cfg(feature = "electrum_blocking")]
pub fn electrum_blocking(
url: &str,
config: Option<electrum_client::Config>,
) -> Result<Self, String> {
Ok(AnyResolver {
inner: Box::new(super::electrum_blocking::ElectrumClient {
inner: electrum_client::Client::from_config(url, config.unwrap_or_default())
.map_err(|e| e.to_string())?,
}),
consignment_txes: Default::default(),
})
}
#[cfg(feature = "esplora_blocking")]
pub fn esplora_blocking(builder: esplora_client::Builder) -> Result<Self, String> {
Ok(AnyResolver {
inner: Box::new(super::esplora_blocking::EsploraClient {
inner: esplora_client::BlockingClient::from_builder(builder),
}),
consignment_txes: Default::default(),
})
}
#[cfg(feature = "mempool_blocking")]
pub fn mempool_blocking(
_url: &str,
builder: Option<esplora_client::Builder>,
) -> Result<Self, String> {
Ok(AnyResolver {
inner: Box::new(super::mempool_blocking::MemPoolClient::new(builder.unwrap())),
consignment_txes: Default::default(),
})
}
pub fn add_consignment_txes<const TYPE: bool>(&mut self, consignment: &Consignment<TYPE>) {
self.consignment_txes.extend(
consignment
.bundles
.iter()
.filter_map(|bw| bw.pub_witness.tx().cloned())
.map(|tx| (tx.compute_txid(), tx)),
);
}
}
impl ResolveWitness for AnyResolver {
fn resolve_witness(&self, witness_id: Txid) -> Result<WitnessStatus, WitnessResolverError> {
if let Some(tx) = self.consignment_txes.get(&witness_id) {
Ok(WitnessStatus::Resolved(tx.clone(), WitnessOrd::Tentative))
} else {
self.inner.resolve_witness(witness_id)
}
}
fn check_chain_net(&self, chain_net: ChainNet) -> Result<(), WitnessResolverError> {
self.inner.check_chain_net(chain_net)
}
}