diff --git a/crates/wallet/README.md b/crates/wallet/README.md index be780b6c3..ed40ddc4a 100644 --- a/crates/wallet/README.md +++ b/crates/wallet/README.md @@ -78,9 +78,9 @@ let mut db = // Create a wallet with initial wallet data read from the file store. 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 changeset = db.aggregate_changesets().expect("changeset loaded").expect("changeset"); let mut wallet = - Wallet::new_or_load(descriptor, change_descriptor, changeset, Network::Testnet) + Wallet::load(descriptor, change_descriptor, changeset, Network::Testnet) .expect("create or load wallet"); // Get a new address to receive bitcoin. diff --git a/crates/wallet/src/wallet/mod.rs b/crates/wallet/src/wallet/mod.rs index 23d7eb114..925f83aca 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. +/// Method [`load_no_priv`] and [`load`] may return this error. /// -/// [`load_from_changeset`]: Wallet::load_from_changeset +/// [`load_no_priv`]: Wallet::load_no_priv +/// [`load`]: Wallet::load #[derive(Debug)] pub enum LoadError { /// There was a problem with the passed-in descriptor(s). @@ -215,34 +216,6 @@ 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. @@ -257,7 +230,7 @@ pub enum NewOrLoadError { /// 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 +239,22 @@ 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 } => { + 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:?}") + } + LoadError::LoadedGenesisDoesNotMatch { expected, got } => { write!(f, "loaded genesis hash is not {}, got {:?}", expected, got) } - NewOrLoadError::LoadedNetworkDoesNotMatch { expected, got } => { + LoadError::LoadedNetworkDoesNotMatch { expected, got } => { write!(f, "loaded network type is not {}, got {:?}", expected, got) } - NewOrLoadError::LoadedDescriptorDoesNotMatch { got, keychain } => { + LoadError::LoadedDescriptorDoesNotMatch { got, keychain } => { write!( f, "loaded descriptor is different from what was provided, got {:?} for keychain {:?}", @@ -288,7 +266,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)] @@ -336,8 +314,8 @@ impl Wallet { /// Initialize an empty [`Wallet`] with a custom genesis hash. /// - /// This is like [`Wallet::new`] with an additional `genesis_hash` parameter. This is useful - /// for syncing from alternative networks. + /// This is like [`Wallet::new`] with an additional `genesis_hash` parameter. This is useful for + /// syncing from alternative networks. pub fn new_with_genesis_hash( descriptor: E, change_descriptor: E, @@ -401,7 +379,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_no_priv(changeset)?; /// /// external_signer_container.signers().into_iter() /// .for_each(|s| wallet.add_signer(KeychainKind::External, SignerOrdering::default(), s.clone())); @@ -411,9 +389,9 @@ impl Wallet { /// # } /// ``` /// - /// Alternatively, you can call [`Wallet::new_or_load`], which will add the private keys of the + /// Alternatively, you can call [`Wallet::load`], which will add the private keys of the /// passed-in descriptors to the [`Wallet`]. - pub fn load_from_changeset(changeset: ChangeSet) -> Result { + pub fn load_no_priv(changeset: ChangeSet) -> Result { let secp = Secp256k1::new(); let network = changeset.network.ok_or(LoadError::MissingNetwork)?; let chain = @@ -454,7 +432,8 @@ impl Wallet { }) } - /// Either loads [`Wallet`] from the given [`ChangeSet`] or initializes it if one does not exist. + /// Loads [`Wallet`] from the given [`ChangeSet`] and add the private keys of the passed-in + /// descriptors to the [`Wallet`]. /// /// This method will fail if the loaded [`ChangeSet`] has different parameters to those provided. /// @@ -469,128 +448,105 @@ impl Wallet { /// 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)?; + /// if let Some(changeset) = changeset { + /// let mut wallet = Wallet::load(external_descriptor, internal_descriptor, changeset, Testnet)?; + /// } else { + /// let mut wallet = Wallet::new(external_descriptor, internal_descriptor, Testnet)?; + /// } /// # Ok::<(), anyhow::Error>(()) /// ``` - pub fn new_or_load( + pub fn load( descriptor: E, change_descriptor: E, - changeset: Option, + changeset: ChangeSet, network: Network, - ) -> Result { + ) -> 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, + let mut wallet = Self::load_no_priv(changeset).map_err(|e| match e { + LoadError::Descriptor(e) => LoadError::Descriptor(e), + LoadError::MissingNetwork => LoadError::LoadedNetworkDoesNotMatch { + expected: network, + got: None, + }, + LoadError::MissingGenesis => LoadError::LoadedGenesisDoesNotMatch { + expected: genesis_hash, + got: None, + }, + LoadError::MissingDescriptor(keychain) => { + LoadError::LoadedDescriptorDoesNotMatch { got: None, - }, - LoadError::MissingDescriptor(keychain) => { - NewOrLoadError::LoadedDescriptorDoesNotMatch { - got: None, - keychain, - } + 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(), - ) - }); } + // TODO: This is probably not the best way to handle this? + _ => panic!("load_no_priv should only be able to return Descriptor, MissingNetwork, MissingGenesis, MissingDescriptor"), + })?; + if wallet.network != network { + return Err(LoadError::LoadedNetworkDoesNotMatch { + expected: network, + got: Some(wallet.network), + }); + } + if wallet.chain.genesis_hash() != genesis_hash { + return Err(LoadError::LoadedGenesisDoesNotMatch { + expected: genesis_hash, + got: Some(wallet.chain.genesis_hash()), + }); + } - 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(), - ) - }); - } + let (expected_descriptor, expected_descriptor_keymap) = descriptor + .into_wallet_descriptor(&wallet.secp, 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, 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 +604,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_no_priv(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 ad1db345d..af5f8364b 100644 --- a/crates/wallet/tests/wallet.rs +++ b/crates/wallet/tests/wallet.rs @@ -100,7 +100,7 @@ const P2WPKH_FAKE_WITNESS_SIZE: usize = 106; const DB_MAGIC: &[u8] = &[0x21, 0x24, 0x48]; #[test] -fn load_recovers_wallet() -> anyhow::Result<()> { +fn test_wallet_load_no_priv() -> anyhow::Result<()> { fn run( filename: &str, create_new: New, @@ -139,7 +139,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_no_priv(changeset).expect("must recover wallet"); assert_eq!(wallet.network(), Network::Testnet); assert_eq!( wallet.spk_index().keychains().collect::>(), @@ -180,7 +180,7 @@ fn load_recovers_wallet() -> anyhow::Result<()> { } #[test] -fn new_or_load() -> anyhow::Result<()> { +fn test_wallet_load() -> anyhow::Result<()> { fn run( filename: &str, new_or_load: NewOrRecover, @@ -196,10 +196,10 @@ 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 + // initialize wallet let wallet_keychains: BTreeMap<_, _> = { - let wallet = &mut Wallet::new_or_load(desc, change_desc, None, Network::Testnet) - .expect("must init wallet"); + let wallet = + &mut Wallet::new(desc, change_desc, 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)?; @@ -210,13 +210,15 @@ fn new_or_load() -> anyhow::Result<()> { // 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) + let changeset = read(&mut db) + .expect("must recover wallet") + .expect("changeset"); + let err = Wallet::load(desc, change_desc, changeset, Network::Bitcoin) .expect_err("wrong network"); assert!( matches!( err, - bdk_wallet::wallet::NewOrLoadError::LoadedNetworkDoesNotMatch { + bdk_wallet::wallet::LoadError::LoadedNetworkDoesNotMatch { got: Some(Network::Testnet), expected: Network::Bitcoin } @@ -226,32 +228,6 @@ fn new_or_load() -> anyhow::Result<()> { ); } - // 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(); @@ -261,14 +237,13 @@ fn new_or_load() -> anyhow::Result<()> { .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 changeset = read(db).expect("must recover wallet").expect("changeset"); + let err = Wallet::load(exp_descriptor, exp_change_desc, changeset, Network::Testnet) + .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: {}", @@ -285,13 +260,13 @@ fn new_or_load() -> anyhow::Result<()> { .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 changeset = read(db).expect("must recover wallet").expect("changeset"); + let err = Wallet::load(desc, exp_descriptor, changeset, Network::Testnet) .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: {}", @@ -302,8 +277,8 @@ 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 changeset = read(db).expect("must recover wallet").expect("changeset"); + let wallet = Wallet::load(desc, change_desc, changeset, Network::Testnet) .expect("must recover wallet"); assert_eq!(wallet.network(), Network::Testnet); assert!(wallet @@ -330,6 +305,20 @@ fn new_or_load() -> anyhow::Result<()> { Ok(()) } +#[test] +fn test_wallet_new() -> anyhow::Result<()> { + let (desc, change_desc) = get_test_wpkh_with_change_desc(); + + // initialize wallet + let _: BTreeMap<_, _> = { + let wallet = + &mut Wallet::new(desc, change_desc, Network::Testnet).expect("must init wallet"); + wallet.keychains().map(|(k, v)| (*k, v.clone())).collect() + }; + + Ok(()) +} + #[test] fn test_error_external_and_internal_are_the_same() { // identical descriptors should fail to create wallet diff --git a/example-crates/wallet_electrum/src/main.rs b/example-crates/wallet_electrum/src/main.rs index 2adf090aa..b63e4604f 100644 --- a/example-crates/wallet_electrum/src/main.rs +++ b/example-crates/wallet_electrum/src/main.rs @@ -24,12 +24,18 @@ 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 = Wallet::load( + external_descriptor, + internal_descriptor, + changeset, + Network::Testnet, + )?; + } else { + wallet = 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 0fd82b985..85400abcd 100644 --- a/example-crates/wallet_esplora_async/src/main.rs +++ b/example-crates/wallet_esplora_async/src/main.rs @@ -19,14 +19,8 @@ async fn main() -> Result<(), anyhow::Error> { let mut db = Store::new(conn)?; let external_descriptor = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)"; 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 = Wallet::new(external_descriptor, internal_descriptor, Network::Signet)?; 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 32211b04b..dfa97ee5f 100644 --- a/example-crates/wallet_esplora_blocking/src/main.rs +++ b/example-crates/wallet_esplora_blocking/src/main.rs @@ -20,12 +20,17 @@ 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 = Wallet::load( + external_descriptor, + internal_descriptor, + changeset, + Network::Testnet, + )?; + } else { + wallet = 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 e09e6d762..e5a70b1dc 100644 --- a/example-crates/wallet_rpc/src/main.rs +++ b/example-crates/wallet_rpc/src/main.rs @@ -91,13 +91,19 @@ fn main() -> anyhow::Result<()> { args.db_path, )?; let changeset = db.aggregate_changesets()?; + let mut wallet; + + if let Some(changeset) = changeset { + wallet = Wallet::load( + &args.descriptor, + &args.change_descriptor, + changeset, + Network::Testnet, + )?; + } else { + wallet = Wallet::new(&args.descriptor, &args.change_descriptor, Network::Testnet)?; + } - let mut wallet = Wallet::new_or_load( - &args.descriptor, - &args.change_descriptor, - changeset, - args.network, - )?; println!( "Loaded wallet in {}s", start_load_wallet.elapsed().as_secs_f32()