Skip to content

Commit

Permalink
Temp 19: Add Balance type
Browse files Browse the repository at this point in the history
  • Loading branch information
thunderbiscuit committed Oct 11, 2023
1 parent be982c7 commit 6589695
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 43 deletions.
22 changes: 22 additions & 0 deletions bdk-ffi/src/bdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ interface Wallet {
constructor(Descriptor descriptor, Descriptor? change_descriptor, Network network, WalletType wallet_type);

AddressInfo get_address(AddressIndex address_index);

Network network();

Balance get_balance();
};

enum WalletType {
Expand All @@ -148,6 +152,10 @@ interface Address {
[Throws=BdkError]
constructor(string address, Network network);

Network network();

string to_qr_uri();

string as_string();
};

Expand All @@ -163,3 +171,17 @@ interface AddressIndex {
LastUnused();
Peek(u32 index);
};

interface Balance {
u64 immature();

u64 trusted_pending();

u64 untrusted_pending();

u64 confirmed();

u64 trusted_spendable();

u64 total();
};
80 changes: 51 additions & 29 deletions bdk-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -146,7 +147,6 @@ impl From<&BdkAddressIndex> for AddressIndex {
}
}

//
// /// A wallet transaction
// #[derive(Debug, Clone, PartialEq, Eq, Default)]
// pub struct TransactionDetails {
Expand All @@ -168,6 +168,7 @@ impl From<&BdkAddressIndex> for AddressIndex {
// /// transaction, unconfirmed transaction contains `None`.
// pub confirmation_time: Option<BlockTime>,
// }

//
// impl From<BdkTransactionDetails> for TransactionDetails {
// fn from(tx_details: BdkTransactionDetails) -> Self {
Expand Down Expand Up @@ -202,30 +203,51 @@ impl From<&BdkAddressIndex> for AddressIndex {
// }
// }
// }
//
// // 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,
// }
//

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<BdkBalance> 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 {
Expand Down Expand Up @@ -381,13 +403,13 @@ impl From<&BdkAddressIndex> for AddressIndex {
// self.inner.output.iter().map(|x| x.into()).collect()
// }
// }
//

// impl From<BdkTransaction> for Transaction {
// fn from(tx: BdkTransaction) -> Self {
// Transaction { inner: tx }
// }
// }
//

/// A Bitcoin address.
#[derive(Debug, PartialEq, Eq)]
pub struct Address {
Expand Down Expand Up @@ -427,19 +449,19 @@ impl Address {
// }
// }

// fn network(&self) -> Network {
// self.inner.network
// }
fn network(&self) -> Network {
self.inner.network.into()
}

// fn script_pubkey(&self) -> Arc<Script> {
// Arc::new(Script {
// inner: self.inner.script_pubkey(),
// })
// }

// fn to_qr_uri(&self) -> String {
// self.inner.to_qr_uri()
// }
fn to_qr_uri(&self) -> String {
self.inner.to_qr_uri()
}

fn as_string(&self) -> String {
self.inner.to_string()
Expand Down
18 changes: 11 additions & 7 deletions bdk-ffi/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
// };

use crate::descriptor::Descriptor;
use crate::Balance;
use crate::{AddressIndex, AddressInfo, Network};
// use bdk::wallet::AddressIndex as BdkAddressIndex;
use bdk::Error as BdkError;
use bdk::Wallet as BdkWallet;
use std::sync::{Arc, Mutex, MutexGuard};
Expand Down Expand Up @@ -87,19 +87,23 @@ impl Wallet {
// )
}

// pub fn network(&self) -> Network {
// self.get_wallet().network().into()
// }
pub fn network(&self) -> Network {
self.get_wallet().network().into()
}

// fn get_internal_address(&mut self, address_index: AddressIndex) -> AddressInfo {
// self.get_wallet()
// .get_internal_address(address_index.into())
// .into()
// }

// fn get_balance(&self) -> Balance {
// Balance::from(self.inner.get_balance())
// }
// TODO 16: Why is the Arc required here?
pub fn get_balance(&self) -> Arc<Balance> {
// Arc::new(self.get_wallet().get_balance().into())
let bdk_balance = self.get_wallet().get_balance();
let balance = Balance { inner: bdk_balance };
Arc::new(balance)
}

// fn is_mine(&self, script: Arc<Script>) -> bool {
// self.get_wallet().is_mine(&script.inner)
Expand Down
19 changes: 12 additions & 7 deletions bdk-jvm/lib/src/test/kotlin/org/bitcoindevkit/WalletTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ class WalletTest {

@Test
fun testUsedWallet() {
val descriptor1 = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
// val mnemonic = Mnemonic(WordCount.WORDS12)
// val descriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, null)
// val descriptor = Descriptor.newBip86(descriptorSecretKey, KeychainKind.EXTERNAL, Network.TESTNET)
val wallet = Wallet(descriptor1, null, Network.TESTNET, WalletType.MEMORY)
val (index, address, keychain) = wallet.getAddress(AddressIndex.LastUnused)
println("Address ${address.asString()} at index $index")
val descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
val wallet = Wallet(descriptor, null, Network.TESTNET, WalletType.MEMORY)
val (index, address, keychain) = wallet.getAddress(AddressIndex.LastUnused)
println("Address ${address.asString()} at index $index")
}

@Test
fun testBalance() {
val descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
val wallet = Wallet(descriptor, null, Network.TESTNET, WalletType.MEMORY)

assert(wallet.getBalance().total() == 0uL)
}
}

0 comments on commit 6589695

Please sign in to comment.