use std::collections::HashSet;
use bitcoin::{Script, Transaction, Txid};
use electrum_client::{Client, ElectrumApi};
use super::{ResolveTx, ResolveTxFee, ResolveUtxo, TxResolverError, UtxoResolverError};
use crate::blockchain::Utxo;
impl ResolveTx for Client {
fn resolve_tx(&self, txid: Txid) -> Result<Transaction, TxResolverError> {
self.transaction_get(&txid).map_err(|err| TxResolverError {
txid,
err: Some(Box::new(err)),
})
}
}
impl ResolveTxFee for Client {
fn resolve_tx_fee(&self, txid: Txid) -> Result<Option<(Transaction, u64)>, TxResolverError> {
let tx = self.resolve_tx(txid)?;
let input_amount: u64 = tx
.input
.iter()
.map(|i| {
Ok((
self.resolve_tx(i.previous_output.txid)?,
i.previous_output.vout,
))
})
.collect::<Result<Vec<_>, TxResolverError>>()?
.into_iter()
.map(|(tx, vout)| tx.output[vout as usize].value)
.sum();
let output_amount = tx.output.iter().fold(0, |sum, o| sum + o.value);
let fee = input_amount
.checked_sub(output_amount)
.ok_or_else(|| TxResolverError::with(txid))?;
Ok(Some((tx, fee)))
}
}
impl ResolveUtxo for Client {
fn resolve_utxo<'script>(
&self,
scripts: impl IntoIterator<Item = &'script Script> + Clone,
) -> Result<Vec<HashSet<Utxo>>, UtxoResolverError> {
Ok(self
.batch_script_list_unspent(scripts)?
.into_iter()
.map(|res| res.into_iter().map(Utxo::from).collect())
.collect())
}
}