New stuff on the `FeeRate` type
This is adding 3 things to the FeeRate type.
- API docs
- Display trait
- New methods
The first and 3rd ones are simple and totally cool. The display trait need a bit of discussion maybe.
Note that the new methods are cool/useful because if you have the weight or vbytes for a transaction, you can give this to the FeeRate type and get an Amount that the transaction will pay in fee. I need to play with some of the advanced parts of the API a bit more, but I think you could basically predict the number of sats a transaction will pay before signing, which is pretty useful.
The display trait
This one is me sort of freehanding what I think is the better visual display of the feerate, and I understand it's a bit of a subjective thing. Happy to hear what other people think. The rust-bitcoin FeeRate type defines actually 2 "display" versions (this is a fairly obscure Rust feature but I do think it's pretty cool). The standard display is just the number (sat/kwu), which is... kind of weird if you're not used to it. For example 1 sat/vbyte is just 250 if you use the standard display (println!("Fee rate: {}", feerate)). If you use the alternative display, however (println!("Fee rate: {:#}", feerate)), you get "1.00 sat/vb". This is a better and nicer string, but the "X.00" is hardcoded, and internally you just get the FeeRate::to_sat_per_vb_ceil method. This means you have big plateaus of all the same sat/vb rate, even if at a more granual level you're sort of in between (1.09, 1.75, etc.). The decimals are always X.00. Instead, what I think makes the type interesting is its use of the kwu, which affords you more granularity. The downside of this is that on the normal print/display, you're not reminded of that and just get a weird and big number. So in this PR... I decided to merge the two Rust implementation and ideas, and add the rate type to the string while keeping the sat/kwu number. This is the result:
val feeRate = FeeRate.fromSatPerVb(3uL)
println("Fee rate: $feeRate")
// 750 sat/kwu
The new methods
This one has a tiny hiccup, more in style than anything, but I want to point it out. There appears to be a bug (as far as me and my friend Claude can tell it's at the uniffi level? that prevents us from returning an Option<Amount> on those two methods if I use the standard way to handle this. In theory, these should be very straightforward lines:
pub fn fee_vb(&self, vb: u64) -> Option<Amount> {
self.0.fee_vb(vb).map(Amount::from)
}
In practice, if you try to do this you'll get compilation errors at the uniffi level. I've tried a whole lot of stuff, and I even put Claude on it for a while, and it just kept running in circles and finding the same problems as me. Some names are clashing in the imports and uniffi thinks returning an Amount is the same as a BdkAmount, but of course it's not. In the end I can make it work by separating the one liner into a few lines with full type declaration.
Changelog notice
## Added
- Add `FeeRate.toString()` method [#859]
- Add `FeeRate::fee_vb` and `FeeRate::fee_wu` methods [#859]
[#859]: https://github.com/bitcoindevkit/bdk-ffi/pull/859
Checklists
All Submissions:
- [x] I've signed all my commits
- [x] I followed the contribution guidelines
- [x] I ran
cargo fmtandcargo clippybefore committing
New Features:
- [ ] I've added tests for the new feature
- [x] I've added docs for the new feature
Thanks for adding all the code comments for docs
Sorry for the delay. Ready for review now @reez.