refactor!: move WalletChangeSet to bdk_wallet and fix import paths
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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 use descriptor::template;
|
||||
pub use descriptor::HdKeyPaths;
|
||||
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;
|
||||
|
||||
/// 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 descriptor::template;
|
||||
pub use descriptor::HdKeyPaths;
|
||||
pub use signer;
|
||||
pub use signer::SignOptions;
|
||||
pub use tx_builder::*;
|
||||
pub use types::*;
|
||||
pub use wallet::*;
|
||||
|
||||
pub use chain::WalletChangeSet;
|
||||
/// Get the version of [`bdk_wallet`](crate) at runtime.
|
||||
pub fn version() -> &'static str {
|
||||
env!("CARGO_PKG_VERSION", "unknown")
|
||||
}
|
||||
|
||||
208
crates/wallet/src/wallet/changeset.rs
Normal file
208
crates/wallet/src/wallet/changeset.rs
Normal file
@@ -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<ConfirmationBlockTime, keychain_txout::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<DescriptorPublicKey>>,
|
||||
/// Descriptor for change addresses.
|
||||
pub change_descriptor: Option<Descriptor<DescriptorPublicKey>>,
|
||||
/// Stores the network type of the transaction data.
|
||||
pub network: Option<bitcoin::Network>,
|
||||
/// 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<ConfirmationBlockTime>,
|
||||
/// 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> {
|
||||
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<DescriptorPublicKey>>>("descriptor")?,
|
||||
row.get::<_, Sql<Descriptor<DescriptorPublicKey>>>("change_descriptor")?,
|
||||
row.get::<_, Sql<bitcoin::Network>>("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<local_chain::ChangeSet> for ChangeSet {
|
||||
fn from(chain: local_chain::ChangeSet) -> Self {
|
||||
Self {
|
||||
local_chain: chain,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IndexedTxGraphChangeSet> 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<tx_graph::ChangeSet<ConfirmationBlockTime>> for ChangeSet {
|
||||
fn from(tx_graph: tx_graph::ChangeSet<ConfirmationBlockTime>) -> Self {
|
||||
Self {
|
||||
tx_graph,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<keychain_txout::ChangeSet> for ChangeSet {
|
||||
fn from(indexer: keychain_txout::ChangeSet) -> Self {
|
||||
Self {
|
||||
indexer,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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/*)",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<SyncResult> 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/*)";
|
||||
|
||||
|
||||
@@ -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<Wallet>;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
impl<'c> PersistWith<bdk_chain::sqlite::Transaction<'c>> for Wallet {
|
||||
type CreateParams = CreateParams;
|
||||
type LoadParams = LoadParams;
|
||||
impl<'c> chain::PersistWith<bdk_chain::sqlite::Transaction<'c>> for Wallet {
|
||||
type CreateParams = crate::CreateParams;
|
||||
type LoadParams = crate::LoadParams;
|
||||
|
||||
type CreateError = CreateWithPersistError<bdk_chain::rusqlite::Error>;
|
||||
type LoadError = LoadWithPersistError<bdk_chain::rusqlite::Error>;
|
||||
@@ -34,8 +32,9 @@ impl<'c> PersistWith<bdk_chain::sqlite::Transaction<'c>> for Wallet {
|
||||
conn: &mut bdk_chain::sqlite::Transaction<'c>,
|
||||
params: Self::LoadParams,
|
||||
) -> Result<Option<Self>, 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<bdk_chain::sqlite::Transaction<'c>> for Wallet {
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
impl PersistWith<bdk_chain::sqlite::Connection> for Wallet {
|
||||
type CreateParams = CreateParams;
|
||||
type LoadParams = LoadParams;
|
||||
impl chain::PersistWith<bdk_chain::sqlite::Connection> for Wallet {
|
||||
type CreateParams = crate::CreateParams;
|
||||
type LoadParams = crate::LoadParams;
|
||||
|
||||
type CreateError = CreateWithPersistError<bdk_chain::rusqlite::Error>;
|
||||
type LoadError = LoadWithPersistError<bdk_chain::rusqlite::Error>;
|
||||
@@ -67,7 +66,7 @@ impl PersistWith<bdk_chain::sqlite::Connection> for Wallet {
|
||||
params: Self::CreateParams,
|
||||
) -> Result<Self, Self::CreateError> {
|
||||
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<bdk_chain::sqlite::Connection> for Wallet {
|
||||
params: Self::LoadParams,
|
||||
) -> Result<Option<Self>, 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<bdk_chain::sqlite::Connection> for Wallet {
|
||||
db: &mut bdk_chain::sqlite::Connection,
|
||||
) -> Result<bool, Self::PersistError> {
|
||||
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<bdk_file_store::Store<ChangeSet>> for Wallet {
|
||||
type CreateParams = CreateParams;
|
||||
type LoadParams = LoadParams;
|
||||
impl chain::PersistWith<bdk_file_store::Store<crate::ChangeSet>> for Wallet {
|
||||
type CreateParams = crate::CreateParams;
|
||||
type LoadParams = crate::LoadParams;
|
||||
type CreateError = CreateWithPersistError<std::io::Error>;
|
||||
type LoadError = LoadWithPersistError<bdk_file_store::AggregateChangesetsError<ChangeSet>>;
|
||||
type LoadError =
|
||||
LoadWithPersistError<bdk_file_store::AggregateChangesetsError<crate::ChangeSet>>;
|
||||
type PersistError = std::io::Error;
|
||||
|
||||
fn create(
|
||||
db: &mut bdk_file_store::Store<ChangeSet>,
|
||||
db: &mut bdk_file_store::Store<crate::ChangeSet>,
|
||||
params: Self::CreateParams,
|
||||
) -> Result<Self, Self::CreateError> {
|
||||
let mut wallet =
|
||||
@@ -115,7 +115,7 @@ impl PersistWith<bdk_file_store::Store<ChangeSet>> for Wallet {
|
||||
}
|
||||
|
||||
fn load(
|
||||
db: &mut bdk_file_store::Store<ChangeSet>,
|
||||
db: &mut bdk_file_store::Store<crate::ChangeSet>,
|
||||
params: Self::LoadParams,
|
||||
) -> Result<Option<Self>, Self::LoadError> {
|
||||
let changeset = db
|
||||
@@ -127,7 +127,7 @@ impl PersistWith<bdk_file_store::Store<ChangeSet>> for Wallet {
|
||||
|
||||
fn persist(
|
||||
&mut self,
|
||||
db: &mut bdk_file_store::Store<ChangeSet>,
|
||||
db: &mut bdk_file_store::Store<crate::ChangeSet>,
|
||||
) -> Result<bool, Self::PersistError> {
|
||||
if let Some(changeset) = self.take_staged() {
|
||||
db.append_changeset(&changeset)?;
|
||||
@@ -143,7 +143,7 @@ pub enum LoadWithPersistError<E> {
|
||||
/// Error from persistence.
|
||||
Persist(E),
|
||||
/// Occurs when the loaded changeset cannot construct [`Wallet`].
|
||||
InvalidChangeSet(LoadError),
|
||||
InvalidChangeSet(crate::LoadError),
|
||||
}
|
||||
|
||||
impl<E: fmt::Display> fmt::Display for LoadWithPersistError<E> {
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user