From 84d6ea7838941c44326f0f8478c812c0144bcfac Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Wed, 11 Oct 2023 12:30:28 -0400 Subject: [PATCH] Temp 19: Add Balance type --- bdk-ffi/src/bdk.udl | 16 + bdk-ffi/src/lib.rs | 500 +++++++++--------- bdk-ffi/src/wallet.rs | 11 +- .../kotlin/org/bitcoindevkit/WalletTest.kt | 19 +- 4 files changed, 298 insertions(+), 248 deletions(-) diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index f189076b..e6d20a90 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -137,6 +137,8 @@ interface Wallet { constructor(Descriptor descriptor, Descriptor? change_descriptor, Network network, WalletType wallet_type); AddressInfo get_address(AddressIndex address_index); + + Balance get_balance(); }; enum WalletType { @@ -163,3 +165,17 @@ interface AddressIndex { LastUnused(); Peek(u32 index); }; + +interface Balance { + u64 immature(); + + u64 trusted_pending(); + + u64 untrusted_pending(); + + u64 confirmed(); + + u64 trusted_spendable(); + + u64 total(); +}; diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index 1e804abb..eb980551 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -10,6 +10,7 @@ use bdk::bitcoin::Address as BdkAddress; use bdk::bitcoin::Network as BdkNetwork; use bdk::wallet::AddressIndex as BdkAddressIndex; use bdk::wallet::AddressInfo as BdkAddressInfo; +use bdk::wallet::Balance as BdkBalance; use bdk::Error as BdkError; use bdk::KeychainKind; use std::sync::Arc; @@ -146,248 +147,271 @@ impl From<&BdkAddressIndex> for AddressIndex { } } -// -// /// A wallet transaction -// #[derive(Debug, Clone, PartialEq, Eq, Default)] -// pub struct TransactionDetails { -// pub transaction: Option>, -// /// Transaction id. -// pub txid: String, -// /// Received value (sats) -// /// Sum of owned outputs of this transaction. -// pub received: u64, -// /// Sent value (sats) -// /// Sum of owned inputs of this transaction. -// pub sent: u64, -// /// Fee value (sats) if confirmed. -// /// The availability of the fee depends on the backend. It's never None with an Electrum -// /// Server backend, but it could be None with a Bitcoin RPC node without txindex that receive -// /// funds while offline. -// pub fee: Option, -// /// If the transaction is confirmed, contains height and timestamp of the block containing the -// /// transaction, unconfirmed transaction contains `None`. -// pub confirmation_time: Option, -// } -// -// impl From for TransactionDetails { -// fn from(tx_details: BdkTransactionDetails) -> Self { -// let optional_tx: Option> = -// tx_details.transaction.map(|tx| Arc::new(tx.into())); -// -// TransactionDetails { -// transaction: optional_tx, -// fee: tx_details.fee, -// txid: tx_details.txid.to_string(), -// received: tx_details.received, -// sent: tx_details.sent, -// confirmation_time: tx_details.confirmation_time, -// } -// } -// } -// -// /// A reference to a transaction output. -// #[derive(Clone, Debug, PartialEq, Eq, Hash)] -// pub struct OutPoint { -// /// The referenced transaction's txid. -// txid: String, -// /// The index of the referenced output in its transaction's vout. -// vout: u32, -// } -// -// impl From<&OutPoint> for BdkOutPoint { -// fn from(outpoint: &OutPoint) -> Self { -// BdkOutPoint { -// txid: Txid::from_str(&outpoint.txid).unwrap(), -// vout: outpoint.vout, -// } -// } -// } -// -// // MIGRATION 1.0: Not sure why total and spendable are not in Balance anymore. -// pub struct Balance { -// // All coinbase outputs not yet matured -// pub immature: u64, -// /// Unconfirmed UTXOs generated by a wallet tx -// pub trusted_pending: u64, -// /// Unconfirmed UTXOs received from an external wallet -// pub untrusted_pending: u64, -// /// Confirmed and immediately spendable balance -// pub confirmed: u64, -// } -// + +/// +/// /// A wallet transaction +/// #[derive(Debug, Clone, PartialEq, Eq, Default)] +/// pub struct TransactionDetails { +/// pub transaction: Option>, +/// /// Transaction id. +/// pub txid: String, +/// /// Received value (sats) +/// /// Sum of owned outputs of this transaction. +/// pub received: u64, +/// /// Sent value (sats) +/// /// Sum of owned inputs of this transaction. +/// pub sent: u64, +/// /// Fee value (sats) if confirmed. +/// /// The availability of the fee depends on the backend. It's never None with an Electrum +/// /// Server backend, but it could be None with a Bitcoin RPC node without txindex that receive +/// /// funds while offline. +/// pub fee: Option, +/// /// If the transaction is confirmed, contains height and timestamp of the block containing the +/// /// transaction, unconfirmed transaction contains `None`. +/// pub confirmation_time: Option, +/// } + +/// +/// impl From for TransactionDetails { +/// fn from(tx_details: BdkTransactionDetails) -> Self { +/// let optional_tx: Option> = +/// tx_details.transaction.map(|tx| Arc::new(tx.into())); +/// +/// TransactionDetails { +/// transaction: optional_tx, +/// fee: tx_details.fee, +/// txid: tx_details.txid.to_string(), +/// received: tx_details.received, +/// sent: tx_details.sent, +/// confirmation_time: tx_details.confirmation_time, +/// } +/// } +/// } +/// +/// /// A reference to a transaction output. +/// #[derive(Clone, Debug, PartialEq, Eq, Hash)] +/// pub struct OutPoint { +/// /// The referenced transaction's txid. +/// txid: String, +/// /// The index of the referenced output in its transaction's vout. +/// vout: u32, +/// } +/// +/// impl From<&OutPoint> for BdkOutPoint { +/// fn from(outpoint: &OutPoint) -> Self { +/// BdkOutPoint { +/// txid: Txid::from_str(&outpoint.txid).unwrap(), +/// vout: outpoint.vout, +/// } +/// } +/// } + +pub struct Balance { + pub inner: BdkBalance, +} + +impl Balance { + /// All coinbase outputs not yet matured. + fn immature(&self) -> u64 { + self.inner.immature + } + + /// Unconfirmed UTXOs generated by a wallet tx. + fn trusted_pending(&self) -> u64 { + self.inner.trusted_pending + } + + /// Unconfirmed UTXOs received from an external wallet. + fn untrusted_pending(&self) -> u64 { + self.inner.untrusted_pending + } + + /// Confirmed and immediately spendable balance. + fn confirmed(&self) -> u64 { + self.inner.confirmed + } + + // TODO: Is this how I should name this method? The Rust side calls it get_spendable but it's + // weird to have just the last two being named like getters when they all sort of are. + /// Get sum of trusted_pending and confirmed coins. + fn trusted_spendable(&self) -> u64 { + self.inner.trusted_spendable() + } + + /// Get the whole balance visible to the wallet. + fn total(&self) -> u64 { + self.inner.total() + } +} + // impl From for Balance { // fn from(bdk_balance: BdkBalance) -> Self { -// Balance { -// immature: bdk_balance.immature, -// trusted_pending: bdk_balance.trusted_pending, -// untrusted_pending: bdk_balance.untrusted_pending, -// confirmed: bdk_balance.confirmed, -// } +// Balance { inner: bdk_balance } // } // } -// -// /// A transaction output, which defines new coins to be created from old ones. -// #[derive(Debug, Clone)] -// pub struct TxOut { -// /// The value of the output, in satoshis. -// value: u64, -// /// The address of the output. -// script_pubkey: Arc