diff --git a/src/test_utils.rs b/src/test_utils.rs index ff288ac8..c0a51464 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -147,6 +147,11 @@ pub fn get_test_wpkh_and_change_desc() -> (&'static str, &'static str) { "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)") } +/// `wpkh` two-path descriptor +pub fn get_test_two_path_wpkh() -> &'static str { + "wpkh(tpubDDks68wKK1xKaVVVbNmXUAx68K1K817M6KwjvjEyCrjdU7xMvjKnfYAtZjfZcrfPfGFzqmibuVqMzKJGbBnK7mo7WSJri8Y9QgM7aNQ3fCp/<0;1>/*)" +} + /// `wsh` descriptor with policy `and(pk(A),older(6))` pub fn get_test_single_sig_csv() -> &'static str { "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),older(6)))" diff --git a/src/wallet/params.rs b/src/wallet/params.rs index 4868074b..388d67c5 100644 --- a/src/wallet/params.rs +++ b/src/wallet/params.rs @@ -270,6 +270,28 @@ impl LoadParams { self } + /// Checks that the provided two-path descriptor matches exactly what is loaded for both the + /// external and internal keychains. + /// + /// # Note + /// + /// You must also specify [`extract_keys`](Self::extract_keys) if you wish to add a signer + /// for an expected descriptor containing secrets. + pub fn two_path_descriptor(mut self, expected_descriptor: D) -> Self + where + D: IntoWalletDescriptor + Send + Clone + 'static, + { + let external: DescriptorToExtract = + make_two_path_descriptor_to_extract(expected_descriptor.clone(), 0); + let internal: DescriptorToExtract = + make_two_path_descriptor_to_extract(expected_descriptor, 1); + + self.check_descriptor = Some(Some(external)); + self.check_change_descriptor = Some(Some(internal)); + + self + } + /// Checks that the given network matches the one loaded from persistence. pub fn check_network(mut self, network: Network) -> Self { self.check_network = Some(network); diff --git a/tests/persisted_wallet.rs b/tests/persisted_wallet.rs index f0a9bbab..bc137594 100644 --- a/tests/persisted_wallet.rs +++ b/tests/persisted_wallet.rs @@ -427,6 +427,31 @@ fn single_descriptor_wallet_persist_and_recover() { ); } +#[test] +fn two_path_descriptor_wallet_persist_and_recover() { + use bdk_chain::rusqlite; + + let temp_dir = tempfile::tempdir().unwrap(); + let db_path = temp_dir.path().join("wallet.db"); + let mut db = rusqlite::Connection::open(db_path).unwrap(); + + let two_path_descriptor = get_test_two_path_wpkh(); + let mut wallet = Wallet::create_from_two_path_descriptor(two_path_descriptor) + .network(Network::Testnet4) + .create_wallet(&mut db) + .unwrap(); + let _ = wallet.reveal_addresses_to(KeychainKind::External, 2); + assert!(wallet.persist(&mut db).unwrap()); + + let loaded = Wallet::load() + .two_path_descriptor(two_path_descriptor) + .check_network(Network::Testnet4) + .load_wallet(&mut db) + .unwrap() + .expect("wallet must exist"); + assert_eq!(loaded.derivation_index(KeychainKind::External), Some(2)); +} + #[test] fn wallet_changeset_is_persisted() { persist_wallet_changeset("store.db", |path| {