bdk icon indicating copy to clipboard operation
bdk copied to clipboard

Add recommended_fees to BDK electrum client

Open matthiasdebernardini opened this issue 7 months ago • 12 comments

Describe the enhancement
Add a new function to BdkElectrumClient that returns a vector of FeeRates, so you can easily get the value you need to use with a transaction.

Use case
Using the estimate_fee route from the electrum API is unituitive because it uses units. There should be a method that returns a vector or FeeRates that you can then use to make a transaction with.

Additional context Something like the mempool recommended fees could be good example but if you try to do it this way, a user would pull in the reqwest library and end up having to depend on OpenSSL. While they should know better than to avoid this, it would be great if they could get an easy way to know which feerate to use.

I'm trying this for now, but something simpler would be better I think.

pub fn estimate_electrum_fee(network: Network) -> anyhow::Result<MempoolSpaceFeeEstimation> {
    let electrum_url = match network {
        // todo point to mempool
        Bitcoin =>
        // "ssl://mempool.space:50002",
            "ssl://electrum.blockstream.info:50002",
        _ => "ssl://mempool.space:60602",
    };

    let client = BdkElectrumClient::new(electrum_client::Client::new(electrum_url).unwrap());
    let frs: Vec<_> = (1..=6).map(|n| {
        match client.inner.estimate_fee(n) {
            Ok(fee) => {
                // Convert BTC/kB to satoshis/kb, truncating
                let sats_per_kb = Amount::from_btc((fee* 100_000_000.0).round() / 100_000_000.0).unwrap().to_sat();

                // Convert kB to weight units (1 kB = 4000 weight units)
                let weight_kb = Weight::from_vb(250).unwrap();

                // Calculate satoshis per 1000 weight units
                let sats_per_kwu = sats_per_kb / weight_kb.to_wu();

                FeeRate::from_sat_per_kwu(sats_per_kwu)
            }
            Err(e) => {FeeRate::ZERO}
        }

    }).collect();

    let fastest_fee = frs.first().cloned().unwrap();
    let half_hour_fee = frs[3];
    let hour_fee = frs.last().cloned().unwrap();
    let msfe = MempoolSpaceFeeEstimation{
        fastest_fee,
        half_hour_fee,
        hour_fee,
    };
    Ok(msfe)
}

matthiasdebernardini avatar Jul 18 '24 20:07 matthiasdebernardini