Skip to content

Commit

Permalink
Change descriptor parameter in wallet constructor to use Descriptor i…
Browse files Browse the repository at this point in the history
…nstead of String
  • Loading branch information
thunderbiscuit committed Dec 15, 2022
1 parent cbebd43 commit b7d1635
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ class AndroidLibTest {
}
}

private val descriptor =
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
private val descriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Network.TESTNET)

private val databaseConfig = DatabaseConfig.Memory

Expand Down
2 changes: 1 addition & 1 deletion bdk-ffi/src/bdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ dictionary ScriptAmount {

interface Wallet {
[Throws=BdkError]
constructor(string descriptor, string? change_descriptor, Network network, DatabaseConfig database_config);
constructor(Descriptor descriptor, Descriptor? change_descriptor, Network network, DatabaseConfig database_config);

[Throws=BdkError]
AddressInfo get_address(AddressIndex address_index);
Expand Down
73 changes: 58 additions & 15 deletions bdk-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,6 @@ impl Blockchain {
}
}

struct Wallet {
wallet_mutex: Mutex<BdkWallet<AnyDatabase>>,
}

/// A reference to a transaction output.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct OutPoint {
Expand Down Expand Up @@ -411,15 +407,20 @@ impl PartiallySignedTransaction {
}
}

#[derive(Debug)]
struct Wallet {
wallet_mutex: Mutex<BdkWallet<AnyDatabase>>,
}

/// A Bitcoin wallet.
/// The Wallet acts as a way of coherently interfacing with output descriptors and related transactions. Its main components are:
/// 1. Output descriptors from which it can derive addresses.
/// 2. A Database where it tracks transactions and utxos related to the descriptors.
/// 3. Signers that can contribute signatures to addresses instantiated from the descriptors.
impl Wallet {
fn new(
descriptor: String,
change_descriptor: Option<String>,
descriptor: Arc<Descriptor>,
change_descriptor: Option<Arc<Descriptor>>,
network: Network,
database_config: DatabaseConfig,
) -> Result<Self, BdkError> {
Expand All @@ -429,6 +430,9 @@ impl Wallet {
DatabaseConfig::Sqlite { config } => AnyDatabaseConfig::Sqlite(config),
};
let database = AnyDatabase::from_config(&any_database_config)?;
let descriptor: String = descriptor.as_string_private();
let change_descriptor: Option<String> = change_descriptor.map(|d| d.as_string_private());

let wallet_mutex = Mutex::new(BdkWallet::new(
&descriptor,
change_descriptor.as_ref(),
Expand Down Expand Up @@ -1290,7 +1294,6 @@ uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
mod test {
use crate::*;
use bdk::bitcoin::Address;
use bdk::bitcoin::Network::Testnet;
use bdk::wallet::get_funded_wallet;
use std::str::FromStr;
use std::sync::Mutex;
Expand Down Expand Up @@ -1341,7 +1344,7 @@ mod test {
.cloned()
.unwrap()
.script_pubkey,
Testnet,
Network::Testnet,
)
.unwrap();
assert_eq!(
Expand All @@ -1364,7 +1367,7 @@ mod test {

fn get_descriptor_secret_key() -> DescriptorSecretKey {
let mnemonic = Mnemonic::from_string("chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect".to_string()).unwrap();
DescriptorSecretKey::new(Testnet, Arc::new(mnemonic), None)
DescriptorSecretKey::new(Network::Testnet, Arc::new(mnemonic), None)
}

fn derive_dsk(
Expand Down Expand Up @@ -1556,10 +1559,11 @@ mod test {
// Public 84: [d1d04177/84'/1'/0']tpubDDNxbq17egjFk2edjv8oLnzxk52zny9aAYNv9CMqTzA4mQDiQq818sEkNe9Gzmd4QU8558zftqbfoVBDQorG3E4Wq26tB2JeE4KUoahLkx6/*

let template_private_44 =
Descriptor::new_bip44(master.clone(), KeychainKind::External, Testnet);
Descriptor::new_bip44(master.clone(), KeychainKind::External, Network::Testnet);
let template_private_49 =
Descriptor::new_bip49(master.clone(), KeychainKind::External, Testnet);
let template_private_84 = Descriptor::new_bip84(master, KeychainKind::External, Testnet);
Descriptor::new_bip49(master.clone(), KeychainKind::External, Network::Testnet);
let template_private_84 =
Descriptor::new_bip84(master, KeychainKind::External, Network::Testnet);

// the extended public keys are the same when creating them manually as they are with the templates
println!("Template 49: {}", template_private_49.as_string());
Expand All @@ -1571,19 +1575,19 @@ mod test {
handmade_public_44,
"d1d04177".to_string(),
KeychainKind::External,
Testnet,
Network::Testnet,
);
let template_public_49 = Descriptor::new_bip49_public(
handmade_public_49,
"d1d04177".to_string(),
KeychainKind::External,
Testnet,
Network::Testnet,
);
let template_public_84 = Descriptor::new_bip84_public(
handmade_public_84,
"d1d04177".to_string(),
KeychainKind::External,
Testnet,
Network::Testnet,
);

println!("Template public 49: {}", template_public_49.as_string());
Expand Down Expand Up @@ -1619,4 +1623,43 @@ mod test {
// template_public_84.as_string()
// );
}

#[test]
fn test_descriptor_from_string() {
let descriptor1 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet);
let descriptor2 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Bitcoin);

// Creating a Descriptor using an extended key that doesn't match the network provided will throw and InvalidNetwork Error
assert!(descriptor1.is_ok());
assert_eq!(
descriptor2.unwrap_err().to_string(),
"Descriptor(Key(InvalidNetwork))"
)
}

#[test]
fn test_wallet_from_descriptor() {
let descriptor1 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet).unwrap();

let wallet1 = Wallet::new(
Arc::new(Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet).unwrap()),
None,
Network::Testnet,
DatabaseConfig::Memory
);

let wallet2 = Wallet::new(
Arc::new(descriptor1),
None,
Network::Bitcoin,
DatabaseConfig::Memory,
);

// Creating a wallet using a Descriptor with an extended key that doesn't match the network provided in the wallet constructor will throw and InvalidNetwork Error
assert!(wallet1.is_ok());
assert_eq!(
wallet2.unwrap_err().to_string(),
"Descriptor(Key(InvalidNetwork))"
);
}
}
3 changes: 1 addition & 2 deletions bdk-jvm/lib/src/test/kotlin/org/bitcoindevkit/JvmLibTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class JvmLibTest {
}
}

private val descriptor =
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
private val descriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Network.TESTNET)

private val databaseConfig = DatabaseConfig.Memory

Expand Down

0 comments on commit b7d1635

Please sign in to comment.