Skip to content

Commit

Permalink
wip(feat): update wallet::Balance to use bitcoin::Amount
Browse files Browse the repository at this point in the history
- update all fields `immature`, ` trusted_pending`, `unstrusted_pending`
  and `confirmed` to use the `bitcoin::Amount` instead of `u64`
- update all `impl Balance` methods to use `bitcoin::Amount`
  • Loading branch information
oleonardolima committed Apr 24, 2024
1 parent 8e73998 commit 0e6d7e5
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 21 deletions.
1 change: 1 addition & 0 deletions crates/bdk/src/wallet/tx_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ impl<'a, Cs: CoinSelectionAlgorithm> TxBuilder<'a, Cs, CreateTx> {
self
}

// TODO: (@leonardo) Should this expect/use `bitcoin::Amount` instead ? Would it be a huge breaking change ?
/// Add a recipient to the internal list
pub fn add_recipient(&mut self, script_pubkey: ScriptBuf, amount: u64) -> &mut Self {
self.params.recipients.push((script_pubkey, amount));
Expand Down
12 changes: 6 additions & 6 deletions crates/chain/src/keychain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,26 +90,26 @@ impl<K> AsRef<BTreeMap<K, u32>> for ChangeSet<K> {
)]
pub struct Balance {
/// All coinbase outputs not yet matured
pub immature: u64,
pub immature: bitcoin::Amount,
/// Unconfirmed UTXOs generated by a wallet tx
pub trusted_pending: u64,
pub trusted_pending: bitcoin::Amount,
/// Unconfirmed UTXOs received from an external wallet
pub untrusted_pending: u64,
pub untrusted_pending: bitcoin::Amount,
/// Confirmed and immediately spendable balance
pub confirmed: u64,
pub confirmed: bitcoin::Amount,
}

impl Balance {
/// Get sum of trusted_pending and confirmed coins.
///
/// This is the balance you can spend right now that shouldn't get cancelled via another party
/// double spending it.
pub fn trusted_spendable(&self) -> u64 {
pub fn trusted_spendable(&self) -> bitcoin::Amount {
self.confirmed + self.trusted_pending
}

/// Get the whole balance visible to the wallet.
pub fn total(&self) -> u64 {
pub fn total(&self) -> bitcoin::Amount {
self.confirmed + self.trusted_pending + self.untrusted_pending + self.immature
}
}
Expand Down
17 changes: 9 additions & 8 deletions crates/chain/src/tx_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1155,27 +1155,28 @@ impl<A: Anchor> TxGraph<A> {
outpoints: impl IntoIterator<Item = (OI, OutPoint)>,
mut trust_predicate: impl FnMut(&OI, &Script) -> bool,
) -> Result<Balance, C::Error> {
let mut immature = 0;
let mut trusted_pending = 0;
let mut untrusted_pending = 0;
let mut confirmed = 0;
let mut immature = bitcoin::Amount::ZERO;
let mut trusted_pending = bitcoin::Amount::ZERO;
let mut untrusted_pending = bitcoin::Amount::ZERO;
let mut confirmed = bitcoin::Amount::ZERO;

for res in self.try_filter_chain_unspents(chain, chain_tip, outpoints) {
let (spk_i, txout) = res?;

// TODO: (@leonardo) Should these operations use `bitcoin::Amount::checked_add()` instead ?
match &txout.chain_position {
ChainPosition::Confirmed(_) => {
if txout.is_confirmed_and_spendable(chain_tip.height) {
confirmed += txout.txout.value.to_sat();
confirmed += txout.txout.value;
} else if !txout.is_mature(chain_tip.height) {
immature += txout.txout.value.to_sat();
immature += txout.txout.value;
}
}
ChainPosition::Unconfirmed(_) => {
if trust_predicate(&spk_i, &txout.txout.script_pubkey) {
trusted_pending += txout.txout.value.to_sat();
trusted_pending += txout.txout.value;
} else {
untrusted_pending += txout.txout.value.to_sat();
untrusted_pending += txout.txout.value;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion example-crates/example_cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ where
let chain = &*chain.lock().unwrap();
fn print_balances<'a>(
title_str: &'a str,
items: impl IntoIterator<Item = (&'a str, u64)>,
items: impl IntoIterator<Item = (&'a str, Amount)>,
) {
println!("{}:", title_str);
for (name, amount) in items.into_iter() {
Expand Down
5 changes: 3 additions & 2 deletions example-crates/wallet_electrum/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const BATCH_SIZE: usize = 5;
use std::io::Write;
use std::str::FromStr;

use bdk::bitcoin::Address;
use bdk::bitcoin::{Address, Amount};
use bdk::wallet::Update;
use bdk::{bitcoin::Network, Wallet};
use bdk::{KeychainKind, SignOptions};
Expand Down Expand Up @@ -81,7 +81,8 @@ fn main() -> Result<(), anyhow::Error> {
let balance = wallet.get_balance();
println!("Wallet balance after syncing: {} sats", balance.total());

if balance.total() < SEND_AMOUNT {
// TODO: (@leonardo) Should we format here, or update on constant and TxBuilder::add_recipient() instead ?
if balance.total() < Amount::from_sat(SEND_AMOUNT) {
println!(
"Please send at least {} sats to the receiving address",
SEND_AMOUNT
Expand Down
5 changes: 3 additions & 2 deletions example-crates/wallet_esplora_async/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{io::Write, str::FromStr};

use bdk::{
bitcoin::{Address, Network},
bitcoin::{Address, Amount, Network},
wallet::Update,
KeychainKind, SignOptions, Wallet,
};
Expand Down Expand Up @@ -72,7 +72,8 @@ async fn main() -> Result<(), anyhow::Error> {
let balance = wallet.get_balance();
println!("Wallet balance after syncing: {} sats", balance.total());

if balance.total() < SEND_AMOUNT {
// TODO: (@leonardo) Should we format here, or update on constant and TxBuilder::add_recipient() instead ?
if balance.total() < Amount::from_sat(SEND_AMOUNT) {
println!(
"Please send at least {} sats to the receiving address",
SEND_AMOUNT
Expand Down
5 changes: 3 additions & 2 deletions example-crates/wallet_esplora_blocking/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const PARALLEL_REQUESTS: usize = 1;
use std::{io::Write, str::FromStr};

use bdk::{
bitcoin::{Address, Network},
bitcoin::{Address, Amount, Network},
wallet::Update,
KeychainKind, SignOptions, Wallet,
};
Expand Down Expand Up @@ -72,7 +72,8 @@ fn main() -> Result<(), anyhow::Error> {
let balance = wallet.get_balance();
println!("Wallet balance after syncing: {} sats", balance.total());

if balance.total() < SEND_AMOUNT {
// TODO: (@leonardo) Should we format here, or update on constant and TxBuilder::add_recipient() instead ?
if balance.total() < Amount::from_sat(SEND_AMOUNT) {
println!(
"Please send at least {} sats to the receiving address",
SEND_AMOUNT
Expand Down

0 comments on commit 0e6d7e5

Please sign in to comment.