diff --git a/crates/wallet/README.md b/crates/wallet/README.md index be780b6c31..a734a8da26 100644 --- a/crates/wallet/README.md +++ b/crates/wallet/README.md @@ -79,9 +79,11 @@ let mut db = let descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/0/*)"; let change_descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/1/*)"; let changeset = db.aggregate_changesets().expect("changeset loaded"); -let mut wallet = - Wallet::new_or_load(descriptor, change_descriptor, changeset, Network::Testnet) - .expect("create or load wallet"); +let mut wallet = if let Some(changeset) = changeset { + Wallet::load(changeset).expect("loaded wallet") +} else { + Wallet::new(descriptor, change_descriptor, Network::Testnet).expect("created new wallet") +}; // Get a new address to receive bitcoin. let receive_address = wallet.reveal_next_address(KeychainKind::External); diff --git a/crates/wallet/src/wallet/mod.rs b/crates/wallet/src/wallet/mod.rs index 9db21ac71d..62c6e6d283 100644 --- a/crates/wallet/src/wallet/mod.rs +++ b/crates/wallet/src/wallet/mod.rs @@ -202,9 +202,10 @@ impl std::error::Error for NewError {} /// The error type when loading a [`Wallet`] from a [`ChangeSet`]. /// -/// Method [`load_from_changeset`] may return this error. +/// Methods [`load`] and [`load_with_descriptors`] may return this error. /// -/// [`load_from_changeset`]: Wallet::load_from_changeset +/// [`load`]: Wallet::load +/// [`load_with_descriptors`]: Wallet::load_with_descriptors #[derive(Debug)] pub enum LoadError { /// There was a problem with the passed-in descriptor(s). @@ -215,49 +216,7 @@ pub enum LoadError { MissingGenesis, /// Data loaded from persistence is missing descriptor. MissingDescriptor(KeychainKind), -} - -impl fmt::Display for LoadError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - LoadError::Descriptor(e) => e.fmt(f), - LoadError::MissingNetwork => write!(f, "loaded data is missing network type"), - LoadError::MissingGenesis => write!(f, "loaded data is missing genesis hash"), - LoadError::MissingDescriptor(k) => { - write!(f, "loaded data is missing descriptor for keychain {k:?}") - } - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for LoadError {} - -/// Error type for when we try load a [`Wallet`] from persistence and creating it if non-existent. -/// -/// Methods [`new_or_load`] and [`new_or_load_with_genesis_hash`] may return this error. -/// -/// [`new_or_load`]: Wallet::new_or_load -/// [`new_or_load_with_genesis_hash`]: Wallet::new_or_load_with_genesis_hash -#[derive(Debug)] -pub enum NewOrLoadError { - /// There is a problem with the passed-in descriptor. - Descriptor(crate::descriptor::DescriptorError), - /// The loaded genesis hash does not match what was provided. - LoadedGenesisDoesNotMatch { - /// The expected genesis block hash. - expected: BlockHash, - /// The block hash loaded from persistence. - got: Option, - }, - /// The loaded network type does not match what was provided. - LoadedNetworkDoesNotMatch { - /// The expected network type. - expected: Network, - /// The network type loaded from persistence. - got: Option, - }, - /// The loaded desccriptor does not match what was provided. + /// The loaded descriptor does not match what was provided. LoadedDescriptorDoesNotMatch { /// The descriptor loaded from persistence. got: Option, @@ -266,17 +225,16 @@ pub enum NewOrLoadError { }, } -impl fmt::Display for NewOrLoadError { +impl fmt::Display for LoadError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - NewOrLoadError::Descriptor(e) => e.fmt(f), - NewOrLoadError::LoadedGenesisDoesNotMatch { expected, got } => { - write!(f, "loaded genesis hash is not {}, got {:?}", expected, got) - } - NewOrLoadError::LoadedNetworkDoesNotMatch { expected, got } => { - write!(f, "loaded network type is not {}, got {:?}", expected, got) + LoadError::Descriptor(e) => e.fmt(f), + LoadError::MissingNetwork => write!(f, "loaded data is missing network type"), + LoadError::MissingGenesis => write!(f, "loaded data is missing genesis hash"), + LoadError::MissingDescriptor(k) => { + write!(f, "loaded data is missing descriptor for keychain {k:?}") } - NewOrLoadError::LoadedDescriptorDoesNotMatch { got, keychain } => { + LoadError::LoadedDescriptorDoesNotMatch { got, keychain } => { write!( f, "loaded descriptor is different from what was provided, got {:?} for keychain {:?}", @@ -288,7 +246,7 @@ impl fmt::Display for NewOrLoadError { } #[cfg(feature = "std")] -impl std::error::Error for NewOrLoadError {} +impl std::error::Error for LoadError {} /// An error that may occur when applying a block to [`Wallet`]. #[derive(Debug)] @@ -325,6 +283,15 @@ impl std::error::Error for ApplyBlockError {} impl Wallet { /// Initialize an empty [`Wallet`]. + /// + /// The `descriptor` is used for external (public) addresses and the `change_descriptor` is + /// used for internal (change output) addresses. + /// + /// If only public keys are included in the descriptors then it will be a "watch-only" wallet. + /// Or use [`Wallet::add_signer`] to manually add signers. + /// + /// If private keys are included in the descriptors then signers for those keys will be added + /// automatically to the new [`Wallet]. pub fn new( descriptor: E, change_descriptor: E, @@ -401,7 +368,7 @@ impl Wallet { /// let external_signer_container = SignersContainer::build(external_keymap, &external_descriptor, &secp); /// let internal_signer_container = SignersContainer::build(internal_keymap, &internal_descriptor, &secp); /// let changeset = db.read()?.expect("there must be an existing changeset"); - /// let mut wallet = Wallet::load_from_changeset(changeset)?; + /// let mut wallet = Wallet::load(changeset)?; /// /// external_signer_container.signers().into_iter() /// .for_each(|s| wallet.add_signer(KeychainKind::External, SignerOrdering::default(), s.clone())); @@ -411,32 +378,14 @@ impl Wallet { /// # } /// ``` /// - /// Alternatively, you can call [`Wallet::new_or_load`], which will add the private keys of the - /// passed-in descriptors to the [`Wallet`]. - pub fn load_from_changeset(changeset: ChangeSet) -> Result { + /// Alternatively, you can call [`Wallet::load_with_descriptors`], which will add the private + /// keys (if any) of the passed-in descriptors to the [`Wallet`]. + pub fn load(changeset: ChangeSet) -> Result { let secp = Secp256k1::new(); let network = changeset.network.ok_or(LoadError::MissingNetwork)?; let chain = LocalChain::from_changeset(changeset.chain).map_err(|_| LoadError::MissingGenesis)?; - let mut index = KeychainTxOutIndex::::default(); - let descriptor = changeset - .indexed_tx_graph - .indexer - .keychains_added - .get(&KeychainKind::External) - .ok_or(LoadError::MissingDescriptor(KeychainKind::External))? - .clone(); - let change_descriptor = changeset - .indexed_tx_graph - .indexer - .keychains_added - .get(&KeychainKind::Internal) - .ok_or(LoadError::MissingDescriptor(KeychainKind::Internal))? - .clone(); - - let (signers, change_signers) = - create_signers(&mut index, &secp, descriptor, change_descriptor, network) - .expect("Can't fail: we passed in valid descriptors, recovered from the changeset"); + let index = KeychainTxOutIndex::::default(); let mut indexed_graph = IndexedTxGraph::new(index); indexed_graph.apply_changeset(changeset.indexed_tx_graph); @@ -444,8 +393,8 @@ impl Wallet { let stage = ChangeSet::default(); Ok(Wallet { - signers, - change_signers, + signers: Arc::new(SignersContainer::new()), + change_signers: Arc::new(SignersContainer::new()), chain, indexed_graph, stage, @@ -454,9 +403,13 @@ impl Wallet { }) } - /// Either loads [`Wallet`] from the given [`ChangeSet`] or initializes it if one does not exist. + /// Loads [`Wallet`] from the previously persisted [`ChangeSet`] and descriptors. + /// + /// This method will fail if the given descriptors don't match those included in the + /// [`ChangeSet`]. /// - /// This method will fail if the loaded [`ChangeSet`] has different parameters to those provided. + /// If the provided descriptors contain private keys the signers for those keys will be added + /// to the `Wallet`. /// /// ```rust,no_run /// # use bdk_wallet::Wallet; @@ -464,133 +417,74 @@ impl Wallet { /// # use bitcoin::Network::Testnet; /// let conn = Connection::open_in_memory().expect("must open connection"); /// let mut db = Store::new(conn).expect("must create db"); - /// let changeset = db.read()?; + /// let changeset = db.read()?.expect("changeset must exist"); /// /// let external_descriptor = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)"; /// let internal_descriptor = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)"; /// - /// let mut wallet = Wallet::new_or_load(external_descriptor, internal_descriptor, changeset, Testnet)?; + /// let mut wallet = Wallet::load_with_descriptors(external_descriptor, internal_descriptor, changeset)?; /// # Ok::<(), anyhow::Error>(()) /// ``` - pub fn new_or_load( + pub fn load_with_descriptors( descriptor: E, change_descriptor: E, - changeset: Option, - network: Network, - ) -> Result { - let genesis_hash = genesis_block(network).block_hash(); - Self::new_or_load_with_genesis_hash( - descriptor, - change_descriptor, - changeset, - network, - genesis_hash, - ) - } - - /// Either loads [`Wallet`] from a [`ChangeSet`] or initializes it if one does not exist, using the - /// provided descriptor, change descriptor, network, and custom genesis hash. - /// - /// This method will fail if the loaded [`ChangeSet`] has different parameters to those provided. - /// This is like [`Wallet::new_or_load`] with an additional `genesis_hash` parameter. This is - /// useful for syncing from alternative networks. - pub fn new_or_load_with_genesis_hash( - descriptor: E, - change_descriptor: E, - changeset: Option, - network: Network, - genesis_hash: BlockHash, - ) -> Result { - if let Some(changeset) = changeset { - let mut wallet = Self::load_from_changeset(changeset).map_err(|e| match e { - LoadError::Descriptor(e) => NewOrLoadError::Descriptor(e), - LoadError::MissingNetwork => NewOrLoadError::LoadedNetworkDoesNotMatch { - expected: network, - got: None, - }, - LoadError::MissingGenesis => NewOrLoadError::LoadedGenesisDoesNotMatch { - expected: genesis_hash, - got: None, - }, - LoadError::MissingDescriptor(keychain) => { - NewOrLoadError::LoadedDescriptorDoesNotMatch { - got: None, - keychain, - } - } - })?; - if wallet.network != network { - return Err(NewOrLoadError::LoadedNetworkDoesNotMatch { - expected: network, - got: Some(wallet.network), - }); - } - if wallet.chain.genesis_hash() != genesis_hash { - return Err(NewOrLoadError::LoadedGenesisDoesNotMatch { - expected: genesis_hash, - got: Some(wallet.chain.genesis_hash()), - }); - } - - let (expected_descriptor, expected_descriptor_keymap) = descriptor - .into_wallet_descriptor(&wallet.secp, network) - .map_err(NewOrLoadError::Descriptor)?; - let wallet_descriptor = wallet.public_descriptor(KeychainKind::External); - if wallet_descriptor != &expected_descriptor { - return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch { - got: Some(wallet_descriptor.clone()), - keychain: KeychainKind::External, - }); - } - // if expected descriptor has private keys add them as new signers - if !expected_descriptor_keymap.is_empty() { - let signer_container = SignersContainer::build( - expected_descriptor_keymap, - &expected_descriptor, - &wallet.secp, - ); - signer_container.signers().into_iter().for_each(|signer| { - wallet.add_signer( - KeychainKind::External, - SignerOrdering::default(), - signer.clone(), - ) - }); - } - - let (expected_change_descriptor, expected_change_descriptor_keymap) = change_descriptor - .into_wallet_descriptor(&wallet.secp, network) - .map_err(NewOrLoadError::Descriptor)?; - let wallet_change_descriptor = wallet.public_descriptor(KeychainKind::Internal); - if wallet_change_descriptor != &expected_change_descriptor { - return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch { - got: Some(wallet_change_descriptor.clone()), - keychain: KeychainKind::Internal, - }); - } - // if expected change descriptor has private keys add them as new signers - if !expected_change_descriptor_keymap.is_empty() { - let signer_container = SignersContainer::build( - expected_change_descriptor_keymap, - &expected_change_descriptor, - &wallet.secp, - ); - signer_container.signers().into_iter().for_each(|signer| { - wallet.add_signer( - KeychainKind::Internal, - SignerOrdering::default(), - signer.clone(), - ) - }); - } + changeset: ChangeSet, + ) -> Result { + let mut wallet = Self::load(changeset)?; + + let (expected_descriptor, expected_descriptor_keymap) = descriptor + .into_wallet_descriptor(&wallet.secp, wallet.network) + .map_err(LoadError::Descriptor)?; + let wallet_descriptor = wallet.public_descriptor(KeychainKind::External); + if wallet_descriptor != &expected_descriptor { + return Err(LoadError::LoadedDescriptorDoesNotMatch { + got: Some(wallet_descriptor.clone()), + keychain: KeychainKind::External, + }); + } + // if expected descriptor has private keys add them as new signers + if !expected_descriptor_keymap.is_empty() { + let signer_container = SignersContainer::build( + expected_descriptor_keymap, + &expected_descriptor, + &wallet.secp, + ); + signer_container.signers().into_iter().for_each(|signer| { + wallet.add_signer( + KeychainKind::External, + SignerOrdering::default(), + signer.clone(), + ) + }); + } - Ok(wallet) - } else { - Self::new_with_genesis_hash(descriptor, change_descriptor, network, genesis_hash) - .map_err(|e| match e { - NewError::Descriptor(e) => NewOrLoadError::Descriptor(e), - }) + let (expected_change_descriptor, expected_change_descriptor_keymap) = change_descriptor + .into_wallet_descriptor(&wallet.secp, wallet.network) + .map_err(LoadError::Descriptor)?; + let wallet_change_descriptor = wallet.public_descriptor(KeychainKind::Internal); + if wallet_change_descriptor != &expected_change_descriptor { + return Err(LoadError::LoadedDescriptorDoesNotMatch { + got: Some(wallet_change_descriptor.clone()), + keychain: KeychainKind::Internal, + }); } + // if expected change descriptor has private keys add them as new signers + if !expected_change_descriptor_keymap.is_empty() { + let signer_container = SignersContainer::build( + expected_change_descriptor_keymap, + &expected_change_descriptor, + &wallet.secp, + ); + signer_container.signers().into_iter().for_each(|signer| { + wallet.add_signer( + KeychainKind::Internal, + SignerOrdering::default(), + signer.clone(), + ) + }); + } + + Ok(wallet) } /// Get the Bitcoin network the wallet is using. @@ -648,7 +542,7 @@ impl Wallet { /// let conn = Connection::open_in_memory().expect("must open connection"); /// let mut db = Store::new(conn).expect("must create store"); /// # let changeset = ChangeSet::default(); - /// # let mut wallet = Wallet::load_from_changeset(changeset).expect("load wallet"); + /// # let mut wallet = Wallet::load(changeset).expect("load wallet"); /// let next_address = wallet.reveal_next_address(KeychainKind::External); /// if let Some(changeset) = wallet.take_staged() { /// db.write(&changeset)?; diff --git a/crates/wallet/tests/wallet.rs b/crates/wallet/tests/wallet.rs index 15e73958fb..69f603efd2 100644 --- a/crates/wallet/tests/wallet.rs +++ b/crates/wallet/tests/wallet.rs @@ -141,7 +141,7 @@ fn load_recovers_wallet() -> anyhow::Result<()> { let db = &mut recover(&file_path).expect("must recover db"); let changeset = read(db).expect("must recover wallet").expect("changeset"); - let wallet = Wallet::load_from_changeset(changeset).expect("must recover wallet"); + let wallet = Wallet::load(changeset).expect("must recover wallet"); assert_eq!(wallet.network(), Network::Testnet); assert_eq!( wallet.spk_index().keychains().collect::>(), @@ -182,15 +182,15 @@ fn load_recovers_wallet() -> anyhow::Result<()> { } #[test] -fn new_or_load() -> anyhow::Result<()> { - fn run( +fn new_and_load() -> anyhow::Result<()> { + fn run( filename: &str, - new_or_load: NewOrRecover, + load: Recover, read: Read, write: Write, ) -> anyhow::Result<()> where - NewOrRecover: Fn(&Path) -> anyhow::Result, + Recover: Fn(&Path) -> anyhow::Result, Read: Fn(&mut Db) -> anyhow::Result>, Write: Fn(&mut Db, &ChangeSet) -> anyhow::Result<()>, { @@ -198,62 +198,16 @@ fn new_or_load() -> anyhow::Result<()> { let file_path = temp_dir.path().join(filename); let (desc, change_desc) = get_test_wpkh_with_change_desc(); - // init wallet when non-existent + // init wallet let wallet_keychains: BTreeMap<_, _> = { - let wallet = &mut Wallet::new_or_load(desc, change_desc, None, Network::Testnet) - .expect("must init wallet"); - let mut db = new_or_load(&file_path).expect("must create db"); - if let Some(changeset) = wallet.take_staged() { - write(&mut db, &changeset)?; - } + let wallet = + &mut Wallet::new(desc, change_desc, Network::Testnet).expect("must init wallet"); + let changeset = wallet.take_staged().expect("must have changeset"); + let db = &mut load(&file_path).expect("must open db"); + write(db, &changeset)?; wallet.keychains().map(|(k, v)| (*k, v.clone())).collect() }; - // wrong network - { - let mut db = new_or_load(&file_path).expect("must create db"); - let changeset = read(&mut db)?; - let err = Wallet::new_or_load(desc, change_desc, changeset, Network::Bitcoin) - .expect_err("wrong network"); - assert!( - matches!( - err, - bdk_wallet::wallet::NewOrLoadError::LoadedNetworkDoesNotMatch { - got: Some(Network::Testnet), - expected: Network::Bitcoin - } - ), - "err: {}", - err, - ); - } - - // wrong genesis hash - { - let exp_blockhash = BlockHash::all_zeros(); - let got_blockhash = bitcoin::constants::genesis_block(Network::Testnet).block_hash(); - - let db = &mut new_or_load(&file_path).expect("must open db"); - let changeset = read(db)?; - let err = Wallet::new_or_load_with_genesis_hash( - desc, - change_desc, - changeset, - Network::Testnet, - exp_blockhash, - ) - .expect_err("wrong genesis hash"); - assert!( - matches!( - err, - bdk_wallet::wallet::NewOrLoadError::LoadedGenesisDoesNotMatch { got, expected } - if got == Some(got_blockhash) && expected == exp_blockhash - ), - "err: {}", - err, - ); - } - // wrong external descriptor { let (exp_descriptor, exp_change_desc) = get_test_tr_single_sig_xprv_with_change_desc(); @@ -262,15 +216,14 @@ fn new_or_load() -> anyhow::Result<()> { .unwrap() .0; - let db = &mut new_or_load(&file_path).expect("must open db"); - let changeset = read(db)?; - let err = - Wallet::new_or_load(exp_descriptor, exp_change_desc, changeset, Network::Testnet) - .expect_err("wrong external descriptor"); + let db = &mut load(&file_path).expect("must open db"); + let changeset = read(db)?.expect("changeset must exist"); + let err = Wallet::load_with_descriptors(exp_descriptor, exp_change_desc, changeset) + .expect_err("wrong external descriptor"); assert!( matches!( err, - bdk_wallet::wallet::NewOrLoadError::LoadedDescriptorDoesNotMatch { ref got, keychain } + bdk_wallet::wallet::LoadError::LoadedDescriptorDoesNotMatch { ref got, keychain } if got == &Some(got_descriptor) && keychain == KeychainKind::External ), "err: {}", @@ -286,14 +239,14 @@ fn new_or_load() -> anyhow::Result<()> { .unwrap() .0; - let db = &mut new_or_load(&file_path).expect("must open db"); - let changeset = read(db)?; - let err = Wallet::new_or_load(desc, exp_descriptor, changeset, Network::Testnet) + let db = &mut load(&file_path).expect("must open db"); + let changeset = read(db)?.expect("changeset must exist"); + let err = Wallet::load_with_descriptors(desc, exp_descriptor, changeset) .expect_err("wrong internal descriptor"); assert!( matches!( err, - bdk_wallet::wallet::NewOrLoadError::LoadedDescriptorDoesNotMatch { ref got, keychain } + bdk_wallet::wallet::LoadError::LoadedDescriptorDoesNotMatch { ref got, keychain } if got == &Some(got_descriptor) && keychain == KeychainKind::Internal ), "err: {}", @@ -303,9 +256,9 @@ fn new_or_load() -> anyhow::Result<()> { // all parameters match { - let db = &mut new_or_load(&file_path).expect("must open db"); - let changeset = read(db)?; - let wallet = Wallet::new_or_load(desc, change_desc, changeset, Network::Testnet) + let db = &mut load(&file_path).expect("must open db"); + let changeset = read(db)?.expect("changeset must exist"); + let wallet = Wallet::load_with_descriptors(desc, change_desc, changeset) .expect("must recover wallet"); assert_eq!(wallet.network(), Network::Testnet); assert!(wallet @@ -313,6 +266,23 @@ fn new_or_load() -> anyhow::Result<()> { .map(|(k, v)| (*k, v.clone())) .eq(wallet_keychains)); } + + // signers added + { + let db = &mut load(&file_path).expect("must open db"); + let changeset = read(db)?.expect("changeset must exist"); + let wallet = Wallet::load_with_descriptors(desc, change_desc, changeset) + .expect("must recover wallet"); + assert_eq!( + wallet.get_signers(KeychainKind::External).signers().len(), + 1 + ); + assert_eq!( + wallet.get_signers(KeychainKind::Internal).signers().len(), + 1 + ); + } + Ok(()) } diff --git a/example-crates/wallet_electrum/src/main.rs b/example-crates/wallet_electrum/src/main.rs index bda0e91cd8..1a48fd74f8 100644 --- a/example-crates/wallet_electrum/src/main.rs +++ b/example-crates/wallet_electrum/src/main.rs @@ -24,12 +24,11 @@ fn main() -> Result<(), anyhow::Error> { let changeset = db .aggregate_changesets() .map_err(|e| anyhow!("load changes error: {}", e))?; - let mut wallet = Wallet::new_or_load( - external_descriptor, - internal_descriptor, - changeset, - Network::Testnet, - )?; + let mut wallet = if let Some(changeset) = changeset { + Wallet::load_with_descriptors(external_descriptor, internal_descriptor, changeset)? + } else { + Wallet::new(external_descriptor, internal_descriptor, Network::Testnet)? + }; let address = wallet.next_unused_address(KeychainKind::External); if let Some(changeset) = wallet.take_staged() { diff --git a/example-crates/wallet_esplora_async/src/main.rs b/example-crates/wallet_esplora_async/src/main.rs index 0fd82b9859..0bfe8b4018 100644 --- a/example-crates/wallet_esplora_async/src/main.rs +++ b/example-crates/wallet_esplora_async/src/main.rs @@ -21,12 +21,11 @@ async fn main() -> Result<(), anyhow::Error> { let internal_descriptor = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)"; let changeset = db.read()?; - let mut wallet = Wallet::new_or_load( - external_descriptor, - internal_descriptor, - changeset, - Network::Signet, - )?; + let mut wallet = if let Some(changeset) = changeset { + Wallet::load_with_descriptors(external_descriptor, internal_descriptor, changeset)? + } else { + Wallet::new(external_descriptor, internal_descriptor, Network::Testnet)? + }; let address = wallet.next_unused_address(KeychainKind::External); if let Some(changeset) = wallet.take_staged() { diff --git a/example-crates/wallet_esplora_blocking/src/main.rs b/example-crates/wallet_esplora_blocking/src/main.rs index 32211b04bf..2f8bdb6402 100644 --- a/example-crates/wallet_esplora_blocking/src/main.rs +++ b/example-crates/wallet_esplora_blocking/src/main.rs @@ -20,12 +20,11 @@ fn main() -> Result<(), anyhow::Error> { let internal_descriptor = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)"; let changeset = db.aggregate_changesets()?; - let mut wallet = Wallet::new_or_load( - external_descriptor, - internal_descriptor, - changeset, - Network::Testnet, - )?; + let mut wallet = if let Some(changeset) = changeset { + Wallet::load_with_descriptors(external_descriptor, internal_descriptor, changeset)? + } else { + Wallet::new(external_descriptor, internal_descriptor, Network::Testnet)? + }; let address = wallet.next_unused_address(KeychainKind::External); if let Some(changeset) = wallet.take_staged() { diff --git a/example-crates/wallet_rpc/src/main.rs b/example-crates/wallet_rpc/src/main.rs index e09e6d7623..05664036fe 100644 --- a/example-crates/wallet_rpc/src/main.rs +++ b/example-crates/wallet_rpc/src/main.rs @@ -92,12 +92,12 @@ fn main() -> anyhow::Result<()> { )?; let changeset = db.aggregate_changesets()?; - let mut wallet = Wallet::new_or_load( - &args.descriptor, - &args.change_descriptor, - changeset, - args.network, - )?; + let mut wallet = if let Some(changeset) = changeset { + Wallet::load_with_descriptors(&args.descriptor, &args.change_descriptor, changeset)? + } else { + Wallet::new(&args.descriptor, &args.change_descriptor, Network::Testnet)? + }; + println!( "Loaded wallet in {}s", start_load_wallet.elapsed().as_secs_f32()