From 9d1b0d4c8c55b553e35e7ffbda8a732d6cc1cffe Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Thu, 11 Sep 2025 14:32:44 -0400 Subject: [PATCH 1/3] docs: add api docs for FeeRate type --- bdk-ffi/src/bitcoin.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bdk-ffi/src/bitcoin.rs b/bdk-ffi/src/bitcoin.rs index 35a21635..ceca0776 100644 --- a/bdk-ffi/src/bitcoin.rs +++ b/bdk-ffi/src/bitcoin.rs @@ -129,6 +129,7 @@ pub struct FeeRate(pub(crate) BdkFeeRate); #[uniffi::export] impl FeeRate { + // Constructs `FeeRate` from satoshis per virtual bytes. #[uniffi::constructor] pub fn from_sat_per_vb(sat_vb: u64) -> Result { let fee_rate: Option = BdkFeeRate::from_sat_per_vb(sat_vb); @@ -138,19 +139,23 @@ impl FeeRate { } } + // Constructs `FeeRate` from satoshis per 1000 weight units. #[uniffi::constructor] pub fn from_sat_per_kwu(sat_kwu: u64) -> Self { FeeRate(BdkFeeRate::from_sat_per_kwu(sat_kwu)) } + /// Converts to sat/vB rounding up. pub fn to_sat_per_vb_ceil(&self) -> u64 { self.0.to_sat_per_vb_ceil() } + /// Converts to sat/vB rounding down. pub fn to_sat_per_vb_floor(&self) -> u64 { self.0.to_sat_per_vb_floor() } + /// Returns raw fee rate. pub fn to_sat_per_kwu(&self) -> u64 { self.0.to_sat_per_kwu() } From 3f9326437e7eab602f0581814cb674001509aa3d Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Thu, 11 Sep 2025 15:05:40 -0400 Subject: [PATCH 2/3] feat: implement display trait for FeeRate type --- bdk-ffi/Cargo.lock | 2 +- bdk-ffi/src/bitcoin.rs | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/bdk-ffi/Cargo.lock b/bdk-ffi/Cargo.lock index 8d12c200..61641d88 100644 --- a/bdk-ffi/Cargo.lock +++ b/bdk-ffi/Cargo.lock @@ -119,7 +119,7 @@ dependencies = [ [[package]] name = "bdk-ffi" -version = "2.2.0-alpha.0" +version = "2.3.0-alpha.0" dependencies = [ "assert_matches", "bdk_electrum", diff --git a/bdk-ffi/src/bitcoin.rs b/bdk-ffi/src/bitcoin.rs index ceca0776..89c8c383 100644 --- a/bdk-ffi/src/bitcoin.rs +++ b/bdk-ffi/src/bitcoin.rs @@ -125,11 +125,12 @@ impl HashableOutPoint { /// This is an integer type representing fee rate in sat/kwu. It provides protection against mixing /// up the types as well as basic formatting features. #[derive(Clone, Debug, uniffi::Object)] +#[uniffi::export(Display)] pub struct FeeRate(pub(crate) BdkFeeRate); #[uniffi::export] impl FeeRate { - // Constructs `FeeRate` from satoshis per virtual bytes. + /// Constructs `FeeRate` from satoshis per virtual bytes. #[uniffi::constructor] pub fn from_sat_per_vb(sat_vb: u64) -> Result { let fee_rate: Option = BdkFeeRate::from_sat_per_vb(sat_vb); @@ -139,7 +140,7 @@ impl FeeRate { } } - // Constructs `FeeRate` from satoshis per 1000 weight units. + /// Constructs `FeeRate` from satoshis per 1000 weight units. #[uniffi::constructor] pub fn from_sat_per_kwu(sat_kwu: u64) -> Self { FeeRate(BdkFeeRate::from_sat_per_kwu(sat_kwu)) @@ -159,6 +160,36 @@ impl FeeRate { pub fn to_sat_per_kwu(&self) -> u64 { self.0.to_sat_per_kwu() } + + /// Calculates fee in satoshis by multiplying this fee rate by weight, in virtual bytes, returning `None` if overflow occurred. + /// + /// This is equivalent to converting vb to weight using Weight::from_vb and then calling Self::fee_wu(weight). + pub fn fee_vb(&self, vb: u64) -> Option> { + let rust_amount: BdkAmount = self.0.fee_vb(vb)?; + let amount: Amount = rust_amount.into(); + Some(Arc::new(amount)) + + // The whole code above should be replaceable by the following line: + // self.0.fee_vb(vb).map(Arc::new(Amount::from)) + // But in practice you get uniffi compilation errors on it. Not sure what is going on with it, + // but the code we use works just as well. + } + + /// Calculates fee by multiplying this fee rate by weight, in weight units, returning `None` if overflow occurred. + /// + /// This is equivalent to Self::checked_mul_by_weight(). + pub fn fee_wu(&self, wu: u64) -> Option> { + let weight: Weight = Weight::from_wu(wu); + let rust_amount: BdkAmount = self.0.fee_wu(weight)?; + let amount: Amount = rust_amount.into(); + Some(Arc::new(amount)) + } +} + +impl Display for FeeRate { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:#}", self.0) + } } impl_from_core_type!(BdkFeeRate, FeeRate); From 8c62796bdb3c448d8d2a52d7e6fc9e77e1c05a0a Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Thu, 11 Sep 2025 16:01:52 -0400 Subject: [PATCH 3/3] feat: expose FeeRate::fee_vb and FeeRate::fee_wu methods --- bdk-ffi/src/bitcoin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/bdk-ffi/src/bitcoin.rs b/bdk-ffi/src/bitcoin.rs index 89c8c383..40335362 100644 --- a/bdk-ffi/src/bitcoin.rs +++ b/bdk-ffi/src/bitcoin.rs @@ -30,6 +30,7 @@ use bdk_wallet::bitcoin::Transaction as BdkTransaction; use bdk_wallet::bitcoin::TxIn as BdkTxIn; use bdk_wallet::bitcoin::TxOut as BdkTxOut; use bdk_wallet::bitcoin::Txid as BitcoinTxid; +use bdk_wallet::bitcoin::Weight; use bdk_wallet::bitcoin::Wtxid as BitcoinWtxid; use bdk_wallet::miniscript::psbt::PsbtExt; use bdk_wallet::serde_json;