From: 志宇 Date: Wed, 17 Jul 2024 14:37:10 +0000 (+0000) Subject: refactor!: move `WalletChangeSet` to `bdk_wallet` and fix import paths X-Git-Tag: v1.0.0-beta.1~2^2~8 X-Git-Url: http://internal-gitweb-vhost/script/%22https:/database/scripts/struct.EncoderStringWriter.html?a=commitdiff_plain;h=eb73f0659e0046f39f5bf6a07d4145a19f865794;p=bdk refactor!: move `WalletChangeSet` to `bdk_wallet` and fix import paths --- diff --git a/crates/chain/src/changeset.rs b/crates/chain/src/changeset.rs deleted file mode 100644 index 77a7ca23..00000000 --- a/crates/chain/src/changeset.rs +++ /dev/null @@ -1,207 +0,0 @@ -use crate::{ConfirmationBlockTime, Merge}; - -type IndexedTxGraphChangeSet = - crate::indexed_tx_graph::ChangeSet; - -/// A changeset containing [`crate`] structures typically persisted together. -#[derive(Default, Debug, Clone, PartialEq)] -#[cfg_attr( - feature = "serde", - derive(crate::serde::Deserialize, crate::serde::Serialize), - serde(crate = "crate::serde") -)] -pub struct WalletChangeSet { - /// Descriptor for recipient addresses. - pub descriptor: Option>, - /// Descriptor for change addresses. - pub change_descriptor: Option>, - /// Stores the network type of the transaction data. - pub network: Option, - /// Changes to the [`LocalChain`](crate::local_chain::LocalChain). - pub local_chain: crate::local_chain::ChangeSet, - /// Changes to [`TxGraph`](crate::tx_graph::TxGraph). - pub tx_graph: crate::tx_graph::ChangeSet, - /// Changes to [`KeychainTxOutIndex`](crate::keychain_txout::KeychainTxOutIndex). - pub indexer: crate::keychain_txout::ChangeSet, -} - -impl Merge for WalletChangeSet { - /// Merge another [`WalletChangeSet`] into itself. - /// - /// The `keychains_added` field respects the invariants of... TODO: FINISH THIS! - fn merge(&mut self, other: Self) { - if other.descriptor.is_some() { - debug_assert!( - self.descriptor.is_none() || self.descriptor == other.descriptor, - "descriptor must never change" - ); - self.descriptor = other.descriptor; - } - if other.change_descriptor.is_some() { - debug_assert!( - self.change_descriptor.is_none() - || self.change_descriptor == other.change_descriptor, - "change descriptor must never change" - ); - } - if other.network.is_some() { - debug_assert!( - self.network.is_none() || self.network == other.network, - "network must never change" - ); - self.network = other.network; - } - - crate::Merge::merge(&mut self.local_chain, other.local_chain); - crate::Merge::merge(&mut self.tx_graph, other.tx_graph); - crate::Merge::merge(&mut self.indexer, other.indexer); - } - - fn is_empty(&self) -> bool { - self.descriptor.is_none() - && self.change_descriptor.is_none() - && self.network.is_none() - && self.local_chain.is_empty() - && self.tx_graph.is_empty() - && self.indexer.is_empty() - } -} - -#[cfg(feature = "sqlite")] -impl WalletChangeSet { - /// Schema name for wallet. - pub const WALLET_SCHEMA_NAME: &'static str = "bdk_wallet"; - /// Name of table to store wallet descriptors and network. - pub const WALLET_TABLE_NAME: &'static str = "bdk_wallet"; - - /// Initialize sqlite tables for wallet schema & table. - fn init_wallet_sqlite_tables(db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> { - let schema_v0: &[&str] = &[&format!( - "CREATE TABLE {} ( \ - id INTEGER PRIMARY KEY NOT NULL CHECK (id = 0), \ - descriptor TEXT, \ - change_descriptor TEXT, \ - network TEXT \ - ) STRICT;", - Self::WALLET_TABLE_NAME, - )]; - crate::sqlite::migrate_schema(db_tx, Self::WALLET_SCHEMA_NAME, &[schema_v0]) - } - - /// Recover a [`WalletChangeSet`] from sqlite database. - pub fn from_sqlite(db_tx: &rusqlite::Transaction) -> rusqlite::Result { - Self::init_wallet_sqlite_tables(db_tx)?; - use crate::sqlite::Sql; - use miniscript::{Descriptor, DescriptorPublicKey}; - use rusqlite::OptionalExtension; - - let mut changeset = Self::default(); - - let mut wallet_statement = db_tx.prepare(&format!( - "SELECT descriptor, change_descriptor, network FROM {}", - Self::WALLET_TABLE_NAME, - ))?; - let row = wallet_statement - .query_row([], |row| { - Ok(( - row.get::<_, Sql>>("descriptor")?, - row.get::<_, Sql>>("change_descriptor")?, - row.get::<_, Sql>("network")?, - )) - }) - .optional()?; - if let Some((Sql(desc), Sql(change_desc), Sql(network))) = row { - changeset.descriptor = Some(desc); - changeset.change_descriptor = Some(change_desc); - changeset.network = Some(network); - } - - changeset.local_chain = crate::local_chain::ChangeSet::from_sqlite(db_tx)?; - changeset.tx_graph = crate::tx_graph::ChangeSet::<_>::from_sqlite(db_tx)?; - changeset.indexer = crate::indexer::keychain_txout::ChangeSet::from_sqlite(db_tx)?; - - Ok(changeset) - } - - /// Persist [`WalletChangeSet`] to sqlite database. - pub fn persist_to_sqlite(&self, db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> { - Self::init_wallet_sqlite_tables(db_tx)?; - use crate::sqlite::Sql; - use rusqlite::named_params; - - let mut descriptor_statement = db_tx.prepare_cached(&format!( - "INSERT INTO {}(id, descriptor) VALUES(:id, :descriptor) ON CONFLICT(id) DO UPDATE SET descriptor=:descriptor", - Self::WALLET_TABLE_NAME, - ))?; - if let Some(descriptor) = &self.descriptor { - descriptor_statement.execute(named_params! { - ":id": 0, - ":descriptor": Sql(descriptor.clone()), - })?; - } - - let mut change_descriptor_statement = db_tx.prepare_cached(&format!( - "INSERT INTO {}(id, change_descriptor) VALUES(:id, :change_descriptor) ON CONFLICT(id) DO UPDATE SET change_descriptor=:change_descriptor", - Self::WALLET_TABLE_NAME, - ))?; - if let Some(change_descriptor) = &self.change_descriptor { - change_descriptor_statement.execute(named_params! { - ":id": 0, - ":change_descriptor": Sql(change_descriptor.clone()), - })?; - } - - let mut network_statement = db_tx.prepare_cached(&format!( - "INSERT INTO {}(id, network) VALUES(:id, :network) ON CONFLICT(id) DO UPDATE SET network=:network", - Self::WALLET_TABLE_NAME, - ))?; - if let Some(network) = self.network { - network_statement.execute(named_params! { - ":id": 0, - ":network": Sql(network), - })?; - } - - self.local_chain.persist_to_sqlite(db_tx)?; - self.tx_graph.persist_to_sqlite(db_tx)?; - self.indexer.persist_to_sqlite(db_tx)?; - Ok(()) - } -} - -impl From for WalletChangeSet { - fn from(chain: crate::local_chain::ChangeSet) -> Self { - Self { - local_chain: chain, - ..Default::default() - } - } -} - -impl From for WalletChangeSet { - fn from(indexed_tx_graph: IndexedTxGraphChangeSet) -> Self { - Self { - tx_graph: indexed_tx_graph.tx_graph, - indexer: indexed_tx_graph.indexer, - ..Default::default() - } - } -} - -impl From> for WalletChangeSet { - fn from(tx_graph: crate::tx_graph::ChangeSet) -> Self { - Self { - tx_graph, - ..Default::default() - } - } -} - -impl From for WalletChangeSet { - fn from(indexer: crate::keychain_txout::ChangeSet) -> Self { - Self { - indexer, - ..Default::default() - } - } -} diff --git a/crates/chain/src/lib.rs b/crates/chain/src/lib.rs index b95a1594..0070c89b 100644 --- a/crates/chain/src/lib.rs +++ b/crates/chain/src/lib.rs @@ -52,13 +52,9 @@ pub use descriptor_ext::{DescriptorExt, DescriptorId}; #[cfg(feature = "miniscript")] mod spk_iter; #[cfg(feature = "miniscript")] -pub use spk_iter::*; -#[cfg(feature = "miniscript")] -mod changeset; -#[cfg(feature = "miniscript")] -pub use changeset::*; -#[cfg(feature = "miniscript")] pub use indexer::keychain_txout; +#[cfg(feature = "miniscript")] +pub use spk_iter::*; #[cfg(feature = "sqlite")] pub mod sqlite; #[cfg(feature = "sqlite")] diff --git a/crates/hwi/src/lib.rs b/crates/hwi/src/lib.rs index e0672275..80649112 100644 --- a/crates/hwi/src/lib.rs +++ b/crates/hwi/src/lib.rs @@ -34,7 +34,7 @@ //! # } //! ``` //! -//! [`TransactionSigner`]: bdk_wallet::wallet::signer::TransactionSigner +//! [`TransactionSigner`]: bdk_wallet::signer::TransactionSigner mod signer; pub use signer::*; diff --git a/crates/hwi/src/signer.rs b/crates/hwi/src/signer.rs index bbb62661..f1b569e3 100644 --- a/crates/hwi/src/signer.rs +++ b/crates/hwi/src/signer.rs @@ -83,7 +83,7 @@ impl TransactionSigner for HWISigner { // Arc::new(custom_signer), // ); // -// let addr = wallet.get_address(bdk_wallet::wallet::AddressIndex::LastUnused); +// let addr = wallet.get_address(bdk_wallet::AddressIndex::LastUnused); // let mut builder = wallet.build_tx(); // builder.drain_to(addr.script_pubkey()).drain_wallet(); // let (mut psbt, _) = builder.finish().unwrap(); diff --git a/crates/wallet/Cargo.toml b/crates/wallet/Cargo.toml index 6f69f48d..d7c2c75a 100644 --- a/crates/wallet/Cargo.toml +++ b/crates/wallet/Cargo.toml @@ -25,7 +25,7 @@ bdk_file_store = { path = "../file_store", version = "0.13.0", optional = true } bip39 = { version = "2.0", optional = true } [features] -default = ["std", "file_store"] +default = ["std"] std = ["bitcoin/std", "bitcoin/rand-std", "miniscript/std", "bdk_chain/std"] compiler = ["miniscript/compiler"] all-keys = ["keys-bip39"] diff --git a/crates/wallet/README.md b/crates/wallet/README.md index 2e5b2cc8..423cf2e7 100644 --- a/crates/wallet/README.md +++ b/crates/wallet/README.md @@ -57,7 +57,7 @@ that the `Wallet` can use to update its view of the chain. ## Persistence -To persist `Wallet` state data use a data store crate that reads and writes [`bdk_chain::WalletChangeSet`]. +To persist `Wallet` state data use a data store crate that reads and writes [`ChangeSet`]. **Implementations** @@ -122,7 +122,7 @@ println!("Your new receive address is: {}", receive_address.address); - + @@ -147,7 +147,7 @@ println!("Your new receive address is: {}", receive_address.address); - + diff --git a/crates/wallet/examples/policy.rs b/crates/wallet/examples/policy.rs index e748c3fd..6e0c8269 100644 --- a/crates/wallet/examples/policy.rs +++ b/crates/wallet/examples/policy.rs @@ -14,7 +14,7 @@ use std::error::Error; use bdk_wallet::bitcoin::Network; use bdk_wallet::descriptor::{policy::BuildSatisfaction, ExtractPolicy, IntoWalletDescriptor}; -use bdk_wallet::wallet::signer::SignersContainer; +use bdk_wallet::signer::SignersContainer; /// This example describes the use of the BDK's [`bdk_wallet::descriptor::policy`] module. /// @@ -38,7 +38,7 @@ fn main() -> Result<(), Box> { // While the `keymap` can be used to create a `SignerContainer`. // // The `SignerContainer` can sign for `PSBT`s. - // a bdk_wallet::wallet internally uses these to handle transaction signing. + // a `bdk_wallet::Wallet` internally uses these to handle transaction signing. // But they can be used as independent tools also. let (wallet_desc, keymap) = desc.into_wallet_descriptor(&secp, Network::Testnet)?; diff --git a/crates/wallet/src/descriptor/policy.rs b/crates/wallet/src/descriptor/policy.rs index 076b9c3c..6fb4013f 100644 --- a/crates/wallet/src/descriptor/policy.rs +++ b/crates/wallet/src/descriptor/policy.rs @@ -21,7 +21,7 @@ //! ``` //! # use std::sync::Arc; //! # use bdk_wallet::descriptor::*; -//! # use bdk_wallet::wallet::signer::*; +//! # use bdk_wallet::signer::*; //! # use bdk_wallet::bitcoin::secp256k1::Secp256k1; //! use bdk_wallet::descriptor::policy::BuildSatisfaction; //! let secp = Secp256k1::new(); diff --git a/crates/wallet/src/lib.rs b/crates/wallet/src/lib.rs index da304a26..a4abe5f1 100644 --- a/crates/wallet/src/lib.rs +++ b/crates/wallet/src/lib.rs @@ -15,43 +15,36 @@ extern crate std; #[doc(hidden)] #[macro_use] pub extern crate alloc; - +pub extern crate bdk_chain as chain; +#[cfg(feature = "file_store")] +pub extern crate bdk_file_store as file_store; +#[cfg(feature = "keys-bip39")] +pub extern crate bip39; pub extern crate bitcoin; pub extern crate miniscript; -extern crate serde; -extern crate serde_json; - -#[cfg(feature = "keys-bip39")] -extern crate bip39; +pub extern crate serde; +pub extern crate serde_json; pub mod descriptor; pub mod keys; pub mod psbt; -pub(crate) mod types; -pub mod wallet; +mod types; +mod wallet; +pub(crate) use bdk_chain::collections; +#[cfg(feature = "sqlite")] +pub use bdk_chain::rusqlite; +#[cfg(feature = "sqlite")] +pub use bdk_chain::sqlite; pub use descriptor::template; pub use descriptor::HdKeyPaths; +pub use signer; +pub use signer::SignOptions; +pub use tx_builder::*; pub use types::*; -pub use wallet::signer; -pub use wallet::signer::SignOptions; -pub use wallet::tx_builder::TxBuilder; -pub use wallet::ChangeSet; -pub use wallet::CreateParams; -pub use wallet::LoadParams; -pub use wallet::PersistedWallet; -pub use wallet::Wallet; +pub use wallet::*; /// Get the version of [`bdk_wallet`](crate) at runtime. pub fn version() -> &'static str { env!("CARGO_PKG_VERSION", "unknown") } - -pub use bdk_chain as chain; -pub(crate) use bdk_chain::collections; -#[cfg(feature = "sqlite")] -pub use bdk_chain::rusqlite; -#[cfg(feature = "sqlite")] -pub use bdk_chain::sqlite; - -pub use chain::WalletChangeSet; diff --git a/crates/wallet/src/wallet/changeset.rs b/crates/wallet/src/wallet/changeset.rs new file mode 100644 index 00000000..8031f07a --- /dev/null +++ b/crates/wallet/src/wallet/changeset.rs @@ -0,0 +1,208 @@ +use bdk_chain::{ + indexed_tx_graph, keychain_txout, local_chain, tx_graph, ConfirmationBlockTime, Merge, +}; +use miniscript::{Descriptor, DescriptorPublicKey}; + +type IndexedTxGraphChangeSet = + indexed_tx_graph::ChangeSet; + +/// A changeset for [`Wallet`](crate::Wallet). +#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)] +pub struct ChangeSet { + /// Descriptor for recipient addresses. + pub descriptor: Option>, + /// Descriptor for change addresses. + pub change_descriptor: Option>, + /// Stores the network type of the transaction data. + pub network: Option, + /// Changes to the [`LocalChain`](local_chain::LocalChain). + pub local_chain: local_chain::ChangeSet, + /// Changes to [`TxGraph`](tx_graph::TxGraph). + pub tx_graph: tx_graph::ChangeSet, + /// Changes to [`KeychainTxOutIndex`](keychain_txout::KeychainTxOutIndex). + pub indexer: keychain_txout::ChangeSet, +} + +impl Merge for ChangeSet { + /// Merge another [`ChangeSet`] into itself. + fn merge(&mut self, other: Self) { + if other.descriptor.is_some() { + debug_assert!( + self.descriptor.is_none() || self.descriptor == other.descriptor, + "descriptor must never change" + ); + self.descriptor = other.descriptor; + } + if other.change_descriptor.is_some() { + debug_assert!( + self.change_descriptor.is_none() + || self.change_descriptor == other.change_descriptor, + "change descriptor must never change" + ); + } + if other.network.is_some() { + debug_assert!( + self.network.is_none() || self.network == other.network, + "network must never change" + ); + self.network = other.network; + } + + Merge::merge(&mut self.local_chain, other.local_chain); + Merge::merge(&mut self.tx_graph, other.tx_graph); + Merge::merge(&mut self.indexer, other.indexer); + } + + fn is_empty(&self) -> bool { + self.descriptor.is_none() + && self.change_descriptor.is_none() + && self.network.is_none() + && self.local_chain.is_empty() + && self.tx_graph.is_empty() + && self.indexer.is_empty() + } +} + +#[cfg(feature = "sqlite")] +impl ChangeSet { + /// Schema name for wallet. + pub const WALLET_SCHEMA_NAME: &'static str = "bdk_wallet"; + /// Name of table to store wallet descriptors and network. + pub const WALLET_TABLE_NAME: &'static str = "bdk_wallet"; + + /// Initialize sqlite tables for wallet schema & table. + fn init_wallet_sqlite_tables( + db_tx: &chain::rusqlite::Transaction, + ) -> chain::rusqlite::Result<()> { + let schema_v0: &[&str] = &[&format!( + "CREATE TABLE {} ( \ + id INTEGER PRIMARY KEY NOT NULL CHECK (id = 0), \ + descriptor TEXT, \ + change_descriptor TEXT, \ + network TEXT \ + ) STRICT;", + Self::WALLET_TABLE_NAME, + )]; + crate::sqlite::migrate_schema(db_tx, Self::WALLET_SCHEMA_NAME, &[schema_v0]) + } + + /// Recover a [`ChangeSet`] from sqlite database. + pub fn from_sqlite(db_tx: &chain::rusqlite::Transaction) -> chain::rusqlite::Result { + Self::init_wallet_sqlite_tables(db_tx)?; + use crate::sqlite::Sql; + use chain::rusqlite::OptionalExtension; + use miniscript::{Descriptor, DescriptorPublicKey}; + + let mut changeset = Self::default(); + + let mut wallet_statement = db_tx.prepare(&format!( + "SELECT descriptor, change_descriptor, network FROM {}", + Self::WALLET_TABLE_NAME, + ))?; + let row = wallet_statement + .query_row([], |row| { + Ok(( + row.get::<_, Sql>>("descriptor")?, + row.get::<_, Sql>>("change_descriptor")?, + row.get::<_, Sql>("network")?, + )) + }) + .optional()?; + if let Some((Sql(desc), Sql(change_desc), Sql(network))) = row { + changeset.descriptor = Some(desc); + changeset.change_descriptor = Some(change_desc); + changeset.network = Some(network); + } + + changeset.local_chain = local_chain::ChangeSet::from_sqlite(db_tx)?; + changeset.tx_graph = tx_graph::ChangeSet::<_>::from_sqlite(db_tx)?; + changeset.indexer = keychain_txout::ChangeSet::from_sqlite(db_tx)?; + + Ok(changeset) + } + + /// Persist [`ChangeSet`] to sqlite database. + pub fn persist_to_sqlite( + &self, + db_tx: &chain::rusqlite::Transaction, + ) -> chain::rusqlite::Result<()> { + Self::init_wallet_sqlite_tables(db_tx)?; + use chain::rusqlite::named_params; + use chain::sqlite::Sql; + + let mut descriptor_statement = db_tx.prepare_cached(&format!( + "INSERT INTO {}(id, descriptor) VALUES(:id, :descriptor) ON CONFLICT(id) DO UPDATE SET descriptor=:descriptor", + Self::WALLET_TABLE_NAME, + ))?; + if let Some(descriptor) = &self.descriptor { + descriptor_statement.execute(named_params! { + ":id": 0, + ":descriptor": Sql(descriptor.clone()), + })?; + } + + let mut change_descriptor_statement = db_tx.prepare_cached(&format!( + "INSERT INTO {}(id, change_descriptor) VALUES(:id, :change_descriptor) ON CONFLICT(id) DO UPDATE SET change_descriptor=:change_descriptor", + Self::WALLET_TABLE_NAME, + ))?; + if let Some(change_descriptor) = &self.change_descriptor { + change_descriptor_statement.execute(named_params! { + ":id": 0, + ":change_descriptor": Sql(change_descriptor.clone()), + })?; + } + + let mut network_statement = db_tx.prepare_cached(&format!( + "INSERT INTO {}(id, network) VALUES(:id, :network) ON CONFLICT(id) DO UPDATE SET network=:network", + Self::WALLET_TABLE_NAME, + ))?; + if let Some(network) = self.network { + network_statement.execute(named_params! { + ":id": 0, + ":network": Sql(network), + })?; + } + + self.local_chain.persist_to_sqlite(db_tx)?; + self.tx_graph.persist_to_sqlite(db_tx)?; + self.indexer.persist_to_sqlite(db_tx)?; + Ok(()) + } +} + +impl From for ChangeSet { + fn from(chain: local_chain::ChangeSet) -> Self { + Self { + local_chain: chain, + ..Default::default() + } + } +} + +impl From for ChangeSet { + fn from(indexed_tx_graph: IndexedTxGraphChangeSet) -> Self { + Self { + tx_graph: indexed_tx_graph.tx_graph, + indexer: indexed_tx_graph.indexer, + ..Default::default() + } + } +} + +impl From> for ChangeSet { + fn from(tx_graph: tx_graph::ChangeSet) -> Self { + Self { + tx_graph, + ..Default::default() + } + } +} + +impl From for ChangeSet { + fn from(indexer: keychain_txout::ChangeSet) -> Self { + Self { + indexer, + ..Default::default() + } + } +} diff --git a/crates/wallet/src/wallet/coin_selection.rs b/crates/wallet/src/wallet/coin_selection.rs index 301e5775..4cd90037 100644 --- a/crates/wallet/src/wallet/coin_selection.rs +++ b/crates/wallet/src/wallet/coin_selection.rs @@ -26,10 +26,10 @@ //! ``` //! # use std::str::FromStr; //! # use bitcoin::*; -//! # use bdk_wallet::wallet::{self, ChangeSet, coin_selection::*, coin_selection}; -//! # use bdk_wallet::wallet::error::CreateTxError; +//! # use bdk_wallet::{self, ChangeSet, coin_selection::*, coin_selection}; +//! # use bdk_wallet::error::CreateTxError; //! # use bdk_wallet::*; -//! # use bdk_wallet::wallet::coin_selection::decide_change; +//! # use bdk_wallet::coin_selection::decide_change; //! # use anyhow::Error; //! #[derive(Debug)] //! struct AlwaysSpendEverything; diff --git a/crates/wallet/src/wallet/export.rs b/crates/wallet/src/wallet/export.rs index fbb72b7e..8e4d8a4e 100644 --- a/crates/wallet/src/wallet/export.rs +++ b/crates/wallet/src/wallet/export.rs @@ -20,7 +20,7 @@ //! ``` //! # use std::str::FromStr; //! # use bitcoin::*; -//! # use bdk_wallet::wallet::export::*; +//! # use bdk_wallet::export::*; //! # use bdk_wallet::*; //! let import = r#"{ //! "descriptor": "wpkh([c258d2e4\/84h\/1h\/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe\/0\/*)", @@ -41,7 +41,7 @@ //! ### Export a `Wallet` //! ``` //! # use bitcoin::*; -//! # use bdk_wallet::wallet::export::*; +//! # use bdk_wallet::export::*; //! # use bdk_wallet::*; //! let wallet = CreateParams::new( //! "wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/0/*)", diff --git a/crates/wallet/src/wallet/hardwaresigner.rs b/crates/wallet/src/wallet/hardwaresigner.rs index d7273394..3ec8d9a5 100644 --- a/crates/wallet/src/wallet/hardwaresigner.rs +++ b/crates/wallet/src/wallet/hardwaresigner.rs @@ -16,8 +16,8 @@ //! ```no_run //! # use bdk_wallet::bitcoin::Network; //! # use bdk_wallet::signer::SignerOrdering; -//! # use bdk_wallet::wallet::hardwaresigner::HWISigner; -//! # use bdk_wallet::wallet::AddressIndex::New; +//! # use bdk_wallet::hardwaresigner::HWISigner; +//! # use bdk_wallet::AddressIndex::New; //! # use bdk_wallet::{CreateParams, KeychainKind, SignOptions}; //! # use hwi::HWIClient; //! # use std::sync::Arc; diff --git a/crates/wallet/src/wallet/mod.rs b/crates/wallet/src/wallet/mod.rs index 5e8ad9ee..30fcb3c6 100644 --- a/crates/wallet/src/wallet/mod.rs +++ b/crates/wallet/src/wallet/mod.rs @@ -55,11 +55,13 @@ use miniscript::{ use bdk_chain::tx_graph::CalculateFeeError; +mod changeset; pub mod coin_selection; pub mod export; mod params; pub mod signer; pub mod tx_builder; +pub use changeset::*; pub use params::*; mod persisted; pub use persisted::*; @@ -155,9 +157,6 @@ impl From for Update { } } -/// The changes made to a wallet by applying an [`Update`]. -pub type ChangeSet = bdk_chain::WalletChangeSet; - /// A derived address and the index it was found at. /// For convenience this automatically derefs to `Address` #[derive(Debug, PartialEq, Eq)] @@ -1123,8 +1122,8 @@ impl Wallet { /// # use std::str::FromStr; /// # use bitcoin::*; /// # use bdk_wallet::*; - /// # use bdk_wallet::wallet::ChangeSet; - /// # use bdk_wallet::wallet::error::CreateTxError; + /// # use bdk_wallet::ChangeSet; + /// # use bdk_wallet::error::CreateTxError; /// # use anyhow::Error; /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)"; /// # let mut wallet = doctest_wallet!(); @@ -1487,8 +1486,8 @@ impl Wallet { /// # use std::str::FromStr; /// # use bitcoin::*; /// # use bdk_wallet::*; - /// # use bdk_wallet::wallet::ChangeSet; - /// # use bdk_wallet::wallet::error::CreateTxError; + /// # use bdk_wallet::ChangeSet; + /// # use bdk_wallet::error::CreateTxError; /// # use anyhow::Error; /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)"; /// # let mut wallet = doctest_wallet!(); @@ -1665,8 +1664,8 @@ impl Wallet { /// # use std::str::FromStr; /// # use bitcoin::*; /// # use bdk_wallet::*; - /// # use bdk_wallet::wallet::ChangeSet; - /// # use bdk_wallet::wallet::error::CreateTxError; + /// # use bdk_wallet::ChangeSet; + /// # use bdk_wallet::error::CreateTxError; /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)"; /// # let mut wallet = doctest_wallet!(); /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked(); @@ -2453,8 +2452,7 @@ macro_rules! doctest_wallet { () => {{ use $crate::bitcoin::{BlockHash, Transaction, absolute, TxOut, Network, hashes::Hash}; use $crate::chain::{ConfirmationBlockTime, BlockId, TxGraph}; - use $crate::wallet::{Update, CreateParams}; - use $crate::KeychainKind; + use $crate::{Update, CreateParams, KeychainKind}; let descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/0/*)"; let change_descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/1/*)"; diff --git a/crates/wallet/src/wallet/persisted.rs b/crates/wallet/src/wallet/persisted.rs index fce8ad05..1a0450e2 100644 --- a/crates/wallet/src/wallet/persisted.rs +++ b/crates/wallet/src/wallet/persisted.rs @@ -1,16 +1,14 @@ use core::fmt; -use crate::wallet::{ChangeSet, CreateParams, LoadError, LoadParams}; use crate::{descriptor::DescriptorError, Wallet}; -use bdk_chain::{Merge, PersistWith}; /// Represents a persisted wallet. pub type PersistedWallet = bdk_chain::Persisted; #[cfg(feature = "sqlite")] -impl<'c> PersistWith> for Wallet { - type CreateParams = CreateParams; - type LoadParams = LoadParams; +impl<'c> chain::PersistWith> for Wallet { + type CreateParams = crate::CreateParams; + type LoadParams = crate::LoadParams; type CreateError = CreateWithPersistError; type LoadError = LoadWithPersistError; @@ -34,8 +32,9 @@ impl<'c> PersistWith> for Wallet { conn: &mut bdk_chain::sqlite::Transaction<'c>, params: Self::LoadParams, ) -> Result, Self::LoadError> { - let changeset = ChangeSet::from_sqlite(conn).map_err(LoadWithPersistError::Persist)?; - if changeset.is_empty() { + let changeset = + crate::ChangeSet::from_sqlite(conn).map_err(LoadWithPersistError::Persist)?; + if chain::Merge::is_empty(&changeset) { return Ok(None); } Self::load_with_params(changeset, params).map_err(LoadWithPersistError::InvalidChangeSet) @@ -54,9 +53,9 @@ impl<'c> PersistWith> for Wallet { } #[cfg(feature = "sqlite")] -impl PersistWith for Wallet { - type CreateParams = CreateParams; - type LoadParams = LoadParams; +impl chain::PersistWith for Wallet { + type CreateParams = crate::CreateParams; + type LoadParams = crate::LoadParams; type CreateError = CreateWithPersistError; type LoadError = LoadWithPersistError; @@ -67,7 +66,7 @@ impl PersistWith for Wallet { params: Self::CreateParams, ) -> Result { let mut db_tx = db.transaction().map_err(CreateWithPersistError::Persist)?; - let wallet = PersistWith::create(&mut db_tx, params)?; + let wallet = chain::PersistWith::create(&mut db_tx, params)?; db_tx.commit().map_err(CreateWithPersistError::Persist)?; Ok(wallet) } @@ -77,7 +76,7 @@ impl PersistWith for Wallet { params: Self::LoadParams, ) -> Result, Self::LoadError> { let mut db_tx = db.transaction().map_err(LoadWithPersistError::Persist)?; - let wallet_opt = PersistWith::load(&mut db_tx, params)?; + let wallet_opt = chain::PersistWith::load(&mut db_tx, params)?; db_tx.commit().map_err(LoadWithPersistError::Persist)?; Ok(wallet_opt) } @@ -87,22 +86,23 @@ impl PersistWith for Wallet { db: &mut bdk_chain::sqlite::Connection, ) -> Result { let mut db_tx = db.transaction()?; - let has_changes = PersistWith::persist(self, &mut db_tx)?; + let has_changes = chain::PersistWith::persist(self, &mut db_tx)?; db_tx.commit()?; Ok(has_changes) } } #[cfg(feature = "file_store")] -impl PersistWith> for Wallet { - type CreateParams = CreateParams; - type LoadParams = LoadParams; +impl chain::PersistWith> for Wallet { + type CreateParams = crate::CreateParams; + type LoadParams = crate::LoadParams; type CreateError = CreateWithPersistError; - type LoadError = LoadWithPersistError>; + type LoadError = + LoadWithPersistError>; type PersistError = std::io::Error; fn create( - db: &mut bdk_file_store::Store, + db: &mut bdk_file_store::Store, params: Self::CreateParams, ) -> Result { let mut wallet = @@ -115,7 +115,7 @@ impl PersistWith> for Wallet { } fn load( - db: &mut bdk_file_store::Store, + db: &mut bdk_file_store::Store, params: Self::LoadParams, ) -> Result, Self::LoadError> { let changeset = db @@ -127,7 +127,7 @@ impl PersistWith> for Wallet { fn persist( &mut self, - db: &mut bdk_file_store::Store, + db: &mut bdk_file_store::Store, ) -> Result { if let Some(changeset) = self.take_staged() { db.append_changeset(&changeset)?; @@ -143,7 +143,7 @@ pub enum LoadWithPersistError { /// Error from persistence. Persist(E), /// Occurs when the loaded changeset cannot construct [`Wallet`]. - InvalidChangeSet(LoadError), + InvalidChangeSet(crate::LoadError), } impl fmt::Display for LoadWithPersistError { diff --git a/crates/wallet/src/wallet/tx_builder.rs b/crates/wallet/src/wallet/tx_builder.rs index 4651be35..9c309122 100644 --- a/crates/wallet/src/wallet/tx_builder.rs +++ b/crates/wallet/src/wallet/tx_builder.rs @@ -17,8 +17,8 @@ //! # use std::str::FromStr; //! # use bitcoin::*; //! # use bdk_wallet::*; -//! # use bdk_wallet::wallet::ChangeSet; -//! # use bdk_wallet::wallet::error::CreateTxError; +//! # use bdk_wallet::ChangeSet; +//! # use bdk_wallet::error::CreateTxError; //! # use anyhow::Error; //! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked(); //! # let mut wallet = doctest_wallet!(); @@ -69,11 +69,11 @@ use crate::{KeychainKind, LocalOutput, Utxo, WeightedUtxo}; /// /// ``` /// # use bdk_wallet::*; -/// # use bdk_wallet::wallet::tx_builder::*; +/// # use bdk_wallet::tx_builder::*; /// # use bitcoin::*; /// # use core::str::FromStr; -/// # use bdk_wallet::wallet::ChangeSet; -/// # use bdk_wallet::wallet::error::CreateTxError; +/// # use bdk_wallet::ChangeSet; +/// # use bdk_wallet::error::CreateTxError; /// # use anyhow::Error; /// # let mut wallet = doctest_wallet!(); /// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked(); @@ -641,8 +641,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// # use std::str::FromStr; /// # use bitcoin::*; /// # use bdk_wallet::*; - /// # use bdk_wallet::wallet::ChangeSet; - /// # use bdk_wallet::wallet::error::CreateTxError; + /// # use bdk_wallet::ChangeSet; + /// # use bdk_wallet::error::CreateTxError; /// # use anyhow::Error; /// # let to_address = /// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt") diff --git a/crates/wallet/tests/common.rs b/crates/wallet/tests/common.rs index 131b0bd7..0cdbda5a 100644 --- a/crates/wallet/tests/common.rs +++ b/crates/wallet/tests/common.rs @@ -1,9 +1,6 @@ #![allow(unused)] use bdk_chain::{BlockId, ConfirmationBlockTime, ConfirmationTime, TxGraph}; -use bdk_wallet::{ - wallet::{CreateParams, Update, Wallet}, - KeychainKind, LocalOutput, -}; +use bdk_wallet::{CreateParams, KeychainKind, LocalOutput, Update, Wallet}; use bitcoin::{ hashes::Hash, transaction, Address, Amount, BlockHash, FeeRate, Network, OutPoint, Transaction, TxIn, TxOut, Txid, diff --git a/crates/wallet/tests/wallet.rs b/crates/wallet/tests/wallet.rs index 2965d424..edd2827b 100644 --- a/crates/wallet/tests/wallet.rs +++ b/crates/wallet/tests/wallet.rs @@ -7,14 +7,14 @@ use anyhow::Context; use assert_matches::assert_matches; use bdk_chain::{BlockId, ConfirmationTime}; use bdk_chain::{PersistWith, COINBASE_MATURITY}; +use bdk_wallet::coin_selection::{self, LargestFirstCoinSelection}; use bdk_wallet::descriptor::{calc_checksum, DescriptorError, IntoWalletDescriptor}; +use bdk_wallet::error::CreateTxError; use bdk_wallet::psbt::PsbtUtils; use bdk_wallet::signer::{SignOptions, SignerError}; -use bdk_wallet::wallet::coin_selection::{self, LargestFirstCoinSelection}; -use bdk_wallet::wallet::error::CreateTxError; -use bdk_wallet::wallet::tx_builder::AddForeignUtxoError; -use bdk_wallet::wallet::{AddressInfo, Balance, CreateParams, LoadParams, Wallet}; +use bdk_wallet::tx_builder::AddForeignUtxoError; use bdk_wallet::KeychainKind; +use bdk_wallet::{AddressInfo, Balance, CreateParams, LoadParams, Wallet}; use bitcoin::hashes::Hash; use bitcoin::key::Secp256k1; use bitcoin::psbt; @@ -79,7 +79,7 @@ fn receive_output_in_latest_block(wallet: &mut Wallet, value: u64) -> OutPoint { } fn insert_seen_at(wallet: &mut Wallet, txid: Txid, seen_at: u64) { - use bdk_wallet::wallet::Update; + use bdk_wallet::Update; let mut graph = bdk_chain::TxGraph::default(); let _ = graph.insert_seen_at(txid, seen_at); wallet @@ -774,7 +774,7 @@ fn test_create_tx_absolute_high_fee() { #[test] fn test_create_tx_add_change() { - use bdk_wallet::wallet::tx_builder::TxOrdering; + use bdk_wallet::tx_builder::TxOrdering; let seed = [0; 32]; let mut rng: StdRng = SeedableRng::from_seed(seed); let (mut wallet, _) = get_funded_wallet_wpkh(); @@ -839,7 +839,7 @@ fn test_create_tx_ordering_respected() { project_utxo(tx_a).cmp(&project_utxo(tx_b)) }; - let custom_bip69_ordering = bdk_wallet::wallet::tx_builder::TxOrdering::Custom { + let custom_bip69_ordering = bdk_wallet::tx_builder::TxOrdering::Custom { input_sort: Arc::new(bip69_txin_cmp), output_sort: Arc::new(bip69_txout_cmp), }; diff --git a/example-crates/wallet_electrum/Cargo.toml b/example-crates/wallet_electrum/Cargo.toml index 24f26b0e..10b662e8 100644 --- a/example-crates/wallet_electrum/Cargo.toml +++ b/example-crates/wallet_electrum/Cargo.toml @@ -4,7 +4,6 @@ version = "0.2.0" edition = "2021" [dependencies] -bdk_wallet = { path = "../../crates/wallet", feature = ["file_store"] } +bdk_wallet = { path = "../../crates/wallet", features = ["file_store"] } bdk_electrum = { path = "../../crates/electrum" } -bdk_file_store = { path = "../../crates/file_store" } anyhow = "1" diff --git a/example-crates/wallet_electrum/src/main.rs b/example-crates/wallet_electrum/src/main.rs index 6291a412..4913db9a 100644 --- a/example-crates/wallet_electrum/src/main.rs +++ b/example-crates/wallet_electrum/src/main.rs @@ -1,11 +1,11 @@ -use bdk_wallet::wallet::CreateParams; -use bdk_wallet::wallet::LoadParams; +use bdk_wallet::file_store::Store; +use bdk_wallet::CreateParams; +use bdk_wallet::LoadParams; use std::io::Write; use std::str::FromStr; use bdk_electrum::electrum_client; use bdk_electrum::BdkElectrumClient; -use bdk_file_store::Store; use bdk_wallet::bitcoin::Network; use bdk_wallet::bitcoin::{Address, Amount}; use bdk_wallet::chain::collections::HashSet; @@ -24,8 +24,7 @@ const ELECTRUM_URL: &str = "ssl://electrum.blockstream.info:60002"; fn main() -> Result<(), anyhow::Error> { let db_path = "bdk-electrum-example.db"; - let mut db = - Store::::open_or_create_new(DB_MAGIC.as_bytes(), db_path)?; + let mut db = Store::::open_or_create_new(DB_MAGIC.as_bytes(), db_path)?; let load_params = LoadParams::with_descriptors(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?; let create_params = CreateParams::new(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?; diff --git a/example-crates/wallet_esplora_async/src/main.rs b/example-crates/wallet_esplora_async/src/main.rs index 96d1faf9..efdf2f66 100644 --- a/example-crates/wallet_esplora_async/src/main.rs +++ b/example-crates/wallet_esplora_async/src/main.rs @@ -5,8 +5,7 @@ use bdk_esplora::{esplora_client, EsploraAsyncExt}; use bdk_wallet::{ bitcoin::{Amount, Network}, rusqlite::Connection, - wallet::{CreateParams, LoadParams}, - KeychainKind, SignOptions, + CreateParams, KeychainKind, LoadParams, SignOptions, }; const SEND_AMOUNT: Amount = Amount::from_sat(5000); diff --git a/example-crates/wallet_esplora_blocking/Cargo.toml b/example-crates/wallet_esplora_blocking/Cargo.toml index 857660ac..4228c983 100644 --- a/example-crates/wallet_esplora_blocking/Cargo.toml +++ b/example-crates/wallet_esplora_blocking/Cargo.toml @@ -7,7 +7,6 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bdk_wallet = { path = "../../crates/wallet" } +bdk_wallet = { path = "../../crates/wallet", features = ["file_store"] } bdk_esplora = { path = "../../crates/esplora", features = ["blocking"] } -bdk_file_store = { path = "../../crates/file_store" } anyhow = "1" diff --git a/example-crates/wallet_esplora_blocking/src/main.rs b/example-crates/wallet_esplora_blocking/src/main.rs index 2d2146ef..8075561b 100644 --- a/example-crates/wallet_esplora_blocking/src/main.rs +++ b/example-crates/wallet_esplora_blocking/src/main.rs @@ -1,11 +1,10 @@ use std::{collections::BTreeSet, io::Write}; use bdk_esplora::{esplora_client, EsploraExt}; -use bdk_file_store::Store; use bdk_wallet::{ bitcoin::{Amount, Network}, - wallet::{CreateParams, LoadParams}, - KeychainKind, SignOptions, + file_store::Store, + CreateParams, KeychainKind, LoadParams, SignOptions, }; const DB_MAGIC: &str = "bdk_wallet_esplora_example"; @@ -20,8 +19,7 @@ const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7 const ESPLORA_URL: &str = "http://signet.bitcoindevkit.net"; fn main() -> Result<(), anyhow::Error> { - let mut db = - Store::::open_or_create_new(DB_MAGIC.as_bytes(), DB_PATH)?; + let mut db = Store::::open_or_create_new(DB_MAGIC.as_bytes(), DB_PATH)?; let load_params = LoadParams::with_descriptors(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?; let create_params = CreateParams::new(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?; diff --git a/example-crates/wallet_rpc/Cargo.toml b/example-crates/wallet_rpc/Cargo.toml index 9e37415b..ffda1d3e 100644 --- a/example-crates/wallet_rpc/Cargo.toml +++ b/example-crates/wallet_rpc/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" [dependencies] bdk_wallet = { path = "../../crates/wallet", features = ["file_store"] } -bdk_file_store = { path = "../../crates/file_store" } bdk_bitcoind_rpc = { path = "../../crates/bitcoind_rpc" } anyhow = "1" diff --git a/example-crates/wallet_rpc/src/main.rs b/example-crates/wallet_rpc/src/main.rs index 99d1f49d..fea8947a 100644 --- a/example-crates/wallet_rpc/src/main.rs +++ b/example-crates/wallet_rpc/src/main.rs @@ -2,10 +2,10 @@ use bdk_bitcoind_rpc::{ bitcoincore_rpc::{Auth, Client, RpcApi}, Emitter, }; -use bdk_file_store::Store; use bdk_wallet::{ bitcoin::{Block, Network, Transaction}, - wallet::{CreateParams, LoadParams}, + file_store::Store, + CreateParams, LoadParams, }; use clap::{self, Parser}; use std::{path::PathBuf, sync::mpsc::sync_channel, thread::spawn, time::Instant}; @@ -86,10 +86,8 @@ fn main() -> anyhow::Result<()> { ); let start_load_wallet = Instant::now(); - let mut db = Store::::open_or_create_new( - DB_MAGIC.as_bytes(), - args.db_path, - )?; + let mut db = + Store::::open_or_create_new(DB_MAGIC.as_bytes(), args.db_path)?; let load_params = LoadParams::with_descriptors(&args.descriptor, &args.change_descriptor, args.network)?;