Struct bdk::wallet::Wallet

source ·
pub struct Wallet<D = ()> { /* private fields */ }
Expand description

A Bitcoin wallet

The Wallet acts as a way of coherently interfacing with output descriptors and related transactions. Its main components are:

  1. output descriptors from which it can derive addresses.
  2. signers that can contribute signatures to addresses instantiated from the descriptors.

Implementations§

source§

impl Wallet

source

pub fn new_no_persist<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: Option<E>, network: Network ) -> Result<Self, DescriptorError>

Creates a wallet that does not persist data.

source

pub fn new_no_persist_with_genesis_hash<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: Option<E>, network: Network, genesis_hash: BlockHash ) -> Result<Self, DescriptorError>

Creates a wallet that does not persist data, with a custom genesis hash.

source§

impl<D> Wallet<D>
where D: PersistBackend<ChangeSet, WriteError = Infallible>,

source

pub fn get_address(&mut self, address_index: AddressIndex) -> AddressInfo

Infallibly return a derived address using the external descriptor, see AddressIndex for available address index selection strategies. If none of the keys in the descriptor are derivable (i.e. does not end with /*) then the same address will always be returned for any AddressIndex.

§Panics

This panics when the caller requests for an address of derivation index greater than the BIP32 max index.

source

pub fn get_internal_address( &mut self, address_index: AddressIndex ) -> AddressInfo

Infallibly return a derived address using the internal (change) descriptor.

If the wallet doesn’t have an internal descriptor it will use the external descriptor.

see AddressIndex for available address index selection strategies. If none of the keys in the descriptor are derivable (i.e. does not end with /*) then the same address will always be returned for any AddressIndex.

§Panics

This panics when the caller requests for an address of derivation index greater than the BIP32 max index.

source§

impl<D> Wallet<D>

source

pub fn new<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: Option<E>, db: D, network: Network ) -> Result<Self, NewError<D::WriteError>>

Initialize an empty Wallet.

source

pub fn new_with_genesis_hash<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: Option<E>, db: D, network: Network, genesis_hash: BlockHash ) -> Result<Self, NewError<D::WriteError>>

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.

source

pub fn load<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: Option<E>, db: D ) -> Result<Self, LoadError<D::LoadError>>

Load Wallet from the given persistence backend.

source

pub fn new_or_load<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: Option<E>, db: D, network: Network ) -> Result<Self, NewOrLoadError<D::WriteError, D::LoadError>>

Either loads Wallet from persistence, or initializes it if it does not exist.

This method will fail if the loaded Wallet has different parameters to those provided.

source

pub fn new_or_load_with_genesis_hash<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: Option<E>, db: D, network: Network, genesis_hash: BlockHash ) -> Result<Self, NewOrLoadError<D::WriteError, D::LoadError>>

Either loads Wallet from persistence, or initializes it if it does not exist (with a custom genesis hash).

This method will fail if the loaded Wallet 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.

source

pub fn network(&self) -> Network

Get the Bitcoin network the wallet is using.

source

pub fn keychains(&self) -> &BTreeMap<KeychainKind, ExtendedDescriptor>

Iterator over all keychains in this wallet

source

pub fn try_get_address( &mut self, address_index: AddressIndex ) -> Result<AddressInfo, D::WriteError>

Return a derived address using the external descriptor, see AddressIndex for available address index selection strategies. If none of the keys in the descriptor are derivable (i.e. does not end with /*) then the same address will always be returned for any AddressIndex.

A PersistBackend<ChangeSet>::WriteError will result if unable to persist the new address to the PersistBackend.

§Panics

This panics when the caller requests for an address of derivation index greater than the BIP32 max index.

source

pub fn try_get_internal_address( &mut self, address_index: AddressIndex ) -> Result<AddressInfo, D::WriteError>

Return a derived address using the internal (change) descriptor.

If the wallet doesn’t have an internal descriptor it will use the external descriptor.

A PersistBackend<ChangeSet>::WriteError will result if unable to persist the new address to the PersistBackend.

see AddressIndex for available address index selection strategies. If none of the keys in the descriptor are derivable (i.e. does not end with /*) then the same address will always be returned for any AddressIndex.

§Panics

This panics when the caller requests for an address of derivation index greater than the BIP32 max index.

source

pub fn is_mine(&self, script: &Script) -> bool

Return whether or not a script is part of this wallet (either internal or external)

source

pub fn derivation_of_spk(&self, spk: &Script) -> Option<(KeychainKind, u32)>

Finds how the wallet derived the script pubkey spk.

Will only return Some(_) if the wallet has given out the spk.

source

pub fn list_unspent(&self) -> impl Iterator<Item = LocalOutput> + '_

Return the list of unspent outputs of this wallet

source

pub fn list_output(&self) -> impl Iterator<Item = LocalOutput> + '_

List all relevant outputs (includes both spent and unspent, confirmed and unconfirmed).

To list only unspent outputs (UTXOs), use Wallet::list_unspent instead.

source

pub fn checkpoints(&self) -> CheckPointIter

Get all the checkpoints the wallet is currently storing indexed by height.

source

pub fn latest_checkpoint(&self) -> CheckPoint

Returns the latest checkpoint.

source

pub fn all_unbounded_spk_iters( &self ) -> BTreeMap<KeychainKind, impl Iterator<Item = (u32, ScriptBuf)> + Clone>

Get unbounded script pubkey iterators for both Internal and External keychains.

This is intended to be used when doing a full scan of your addresses (e.g. after restoring from seed words). You pass the BTreeMap of iterators to a blockchain data source (e.g. electrum server) which will go through each address until it reaches a stop gap.

Note carefully that iterators go over all script pubkeys on the keychains (not what script pubkeys the wallet is storing internally).

source

pub fn unbounded_spk_iter( &self, keychain: KeychainKind ) -> impl Iterator<Item = (u32, ScriptBuf)> + Clone

Get an unbounded script pubkey iterator for the given keychain.

See all_unbounded_spk_iters for more documentation

source

pub fn get_utxo(&self, op: OutPoint) -> Option<LocalOutput>

Returns the utxo owned by this wallet corresponding to outpoint if it exists in the wallet’s database.

source

pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut)

Inserts a TxOut at OutPoint into the wallet’s transaction graph.

This is used for providing a previous output’s value so that we can use calculate_fee or calculate_fee_rate on a given transaction. Outputs inserted with this method will not be returned in list_unspent or list_output.

Any inserted TxOuts are not persisted until commit is called.

WARNING: This should only be used to add TxOuts that the wallet does not own. Only insert TxOuts that you trust the values for!

source

pub fn calculate_fee(&self, tx: &Transaction) -> Result<u64, CalculateFeeError>

Calculates the fee of a given transaction. Returns 0 if tx is a coinbase transaction.

To calculate the fee for a Transaction with inputs not owned by this wallet you must manually insert the TxOut(s) into the tx graph using the insert_txout function.

Note tx does not have to be in the graph for this to work.

§Examples
let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
let fee = wallet.calculate_fee(tx).expect("fee");
let tx = &psbt.clone().extract_tx();
let fee = wallet.calculate_fee(tx).expect("fee");
source

pub fn calculate_fee_rate( &self, tx: &Transaction ) -> Result<FeeRate, CalculateFeeError>

Calculate the FeeRate for a given transaction.

To calculate the fee rate for a Transaction with inputs not owned by this wallet you must manually insert the TxOut(s) into the tx graph using the insert_txout function.

Note tx does not have to be in the graph for this to work.

§Examples
let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
let fee_rate = wallet.calculate_fee_rate(tx).expect("fee rate");
let tx = &psbt.clone().extract_tx();
let fee_rate = wallet.calculate_fee_rate(tx).expect("fee rate");
source

pub fn sent_and_received(&self, tx: &Transaction) -> (u64, u64)

Compute the tx’s sent and received amounts (in satoshis).

This method returns a tuple (sent, received). Sent is the sum of the txin amounts that spend from previous txouts tracked by this wallet. Received is the summation of this tx’s outputs that send to script pubkeys tracked by this wallet.

§Examples
let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
let (sent, received) = wallet.sent_and_received(tx);
let tx = &psbt.clone().extract_tx();
let (sent, received) = wallet.sent_and_received(tx);
source

pub fn get_tx( &self, txid: Txid ) -> Option<CanonicalTx<'_, Transaction, ConfirmationTimeHeightAnchor>>

Get a single transaction from the wallet as a CanonicalTx (if the transaction exists).

CanonicalTx contains the full transaction alongside meta-data such as:

  • Blocks that the transaction is Anchored in. These may or may not be blocks that exist in the best chain.
  • The ChainPosition of the transaction in the best chain - whether the transaction is confirmed or unconfirmed. If the transaction is confirmed, the anchor which proves the confirmation is provided. If the transaction is unconfirmed, the unix timestamp of when the transaction was last seen in the mempool is provided.
use bdk::{chain::ChainPosition, Wallet};
use bdk_chain::Anchor;

let canonical_tx = wallet.get_tx(my_txid).expect("panic if tx does not exist");

// get reference to full transaction
println!("my tx: {:#?}", canonical_tx.tx_node.tx);

// list all transaction anchors
for anchor in canonical_tx.tx_node.anchors {
    println!(
        "tx is anchored by block of hash {}",
        anchor.anchor_block().hash
    );
}

// get confirmation status of transaction
match canonical_tx.chain_position {
    ChainPosition::Confirmed(anchor) => println!(
        "tx is confirmed at height {}, we know this since {}:{} is in the best chain",
        anchor.confirmation_height, anchor.anchor_block.height, anchor.anchor_block.hash,
    ),
    ChainPosition::Unconfirmed(last_seen) => println!(
        "tx is last seen at {}, it is unconfirmed as it is not anchored in the best chain",
        last_seen,
    ),
}
source

pub fn insert_checkpoint( &mut self, block_id: BlockId ) -> Result<bool, AlterCheckPointError>

Add a new checkpoint to the wallet’s internal view of the chain. This stages but does not commit the change.

Returns whether anything changed with the insertion (e.g. false if checkpoint was already there).

source

pub fn insert_tx( &mut self, tx: Transaction, position: ConfirmationTime ) -> Result<bool, InsertTxError>

Add a transaction to the wallet’s internal view of the chain. This stages but does not commit the change.

Returns whether anything changed with the transaction insertion (e.g. false if the transaction was already inserted at the same position).

A tx can be rejected if position has a height greater than the latest_checkpoint. Therefore you should use insert_checkpoint to insert new checkpoints before manually inserting new transactions.

WARNING: If position is confirmed, we anchor the tx to a the lowest checkpoint that is >= the position’s height. The caller is responsible for ensuring the tx exists in our local view of the best chain’s history.

source

pub fn transactions( &self ) -> impl Iterator<Item = CanonicalTx<'_, Transaction, ConfirmationTimeHeightAnchor>> + '_

Iterate over the transactions in the wallet.

source

pub fn get_balance(&self) -> Balance

Return the balance, separated into available, trusted-pending, untrusted-pending and immature values.

source

pub fn add_signer( &mut self, keychain: KeychainKind, ordering: SignerOrdering, signer: Arc<dyn TransactionSigner> )

Add an external signer

See the signer module for an example.

source

pub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer>

Get the signers

§Example
let wallet = Wallet::new_no_persist("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet)?;
for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
    // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
    println!("secret_key: {}", secret_key);
}

Ok::<(), Box<dyn std::error::Error>>(())
source

pub fn build_tx( &mut self ) -> TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, CreateTx>

Start building a transaction.

This returns a blank TxBuilder from which you can specify the parameters for the transaction.

§Example
let psbt = {
   let mut builder =  wallet.build_tx();
   builder
       .add_recipient(to_address.script_pubkey(), 50_000);
   builder.finish()?
};

// sign and broadcast ...
source

pub fn build_fee_bump( &mut self, txid: Txid ) -> Result<TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, BumpFee>, BuildFeeBumpError>

Bump the fee of a transaction previously created with this wallet.

Returns an error if the transaction is already confirmed or doesn’t explicitly signal replace by fee (RBF). If the transaction can be fee bumped then it returns a TxBuilder pre-populated with the inputs and outputs of the original transaction.

§Example
let mut psbt = {
    let mut builder = wallet.build_tx();
    builder
        .add_recipient(to_address.script_pubkey(), 50_000)
        .enable_rbf();
    builder.finish()?
};
let _ = wallet.sign(&mut psbt, SignOptions::default())?;
let tx = psbt.extract_tx();
// broadcast tx but it's taking too long to confirm so we want to bump the fee
let mut psbt =  {
    let mut builder = wallet.build_fee_bump(tx.txid())?;
    builder
        .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0));
    builder.finish()?
};

let _ = wallet.sign(&mut psbt, SignOptions::default())?;
let fee_bumped_tx = psbt.extract_tx();
// broadcast fee_bumped_tx to replace original
source

pub fn sign( &self, psbt: &mut PartiallySignedTransaction, sign_options: SignOptions ) -> Result<bool, SignerError>

Sign a transaction with all the wallet’s signers, in the order specified by every signer’s SignerOrdering. This function returns the Result type with an encapsulated bool that has the value true if the PSBT was finalized, or false otherwise.

The SignOptions can be used to tweak the behavior of the software signers, and the way the transaction is finalized at the end. Note that it can’t be guaranteed that every signers will follow the options, but the “software signers” (WIF keys and xprv) defined in this library will.

§Example
let mut psbt = {
    let mut builder = wallet.build_tx();
    builder.add_recipient(to_address.script_pubkey(), 50_000);
    builder.finish()?
};
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
assert!(finalized, "we should have signed all the inputs");
source

pub fn policies( &self, keychain: KeychainKind ) -> Result<Option<Policy>, DescriptorError>

Return the spending policies for the wallet’s descriptor

source

pub fn public_descriptor( &self, keychain: KeychainKind ) -> Option<&ExtendedDescriptor>

Return the “public” version of the wallet’s descriptor, meaning a new descriptor that has the same structure but with every secret key removed

This can be used to build a watch-only version of a wallet

source

pub fn finalize_psbt( &self, psbt: &mut PartiallySignedTransaction, sign_options: SignOptions ) -> Result<bool, SignerError>

Finalize a PSBT, i.e., for each input determine if sufficient data is available to pass validation and construct the respective scriptSig or scriptWitness. Please refer to BIP174 for further information.

Returns true if the PSBT could be finalized, and false otherwise.

The SignOptions can be used to tweak the behavior of the finalizer.

source

pub fn secp_ctx(&self) -> &Secp256k1<All>

Return the secp256k1 context used for all signing operations

source

pub fn get_descriptor_for_keychain( &self, keychain: KeychainKind ) -> &ExtendedDescriptor

Returns the descriptor used to create addresses for a particular keychain.

source

pub fn derivation_index(&self, keychain: KeychainKind) -> Option<u32>

The derivation index of this wallet. It will return None if it has not derived any addresses. Otherwise, it will return the index of the highest address it has derived.

source

pub fn next_derivation_index(&self, keychain: KeychainKind) -> u32

The index of the next address that you would get if you were to ask the wallet for a new address

source

pub fn cancel_tx(&mut self, tx: &Transaction)

Informs the wallet that you no longer intend to broadcast a tx that was built from it.

This frees up the change address used when creating the tx for use in future transactions.

source

pub fn get_psbt_input( &self, utxo: LocalOutput, sighash_type: Option<PsbtSighashType>, only_witness_utxo: bool ) -> Result<Input, CreateTxError<D::WriteError>>

get the corresponding PSBT Input for a LocalUtxo

source

pub fn descriptor_checksum(&self, keychain: KeychainKind) -> String

Return the checksum of the public descriptor associated to keychain

Internally calls Self::get_descriptor_for_keychain to fetch the right descriptor

source

pub fn apply_update(&mut self, update: Update) -> Result<(), CannotConnectError>

Applies an update to the wallet and stages the changes (but does not commit them).

Usually you create an update by interacting with some blockchain data source and inserting transactions related to your wallet into it.

source

pub fn commit(&mut self) -> Result<bool, D::WriteError>

Commits all currently staged changed to the persistence backend returning and error when this fails.

This returns whether the update resulted in any changes.

source

pub fn staged(&self) -> &ChangeSet

Returns the changes that will be committed with the next call to commit.

source

pub fn tx_graph(&self) -> &TxGraph<ConfirmationTimeHeightAnchor>

Get a reference to the inner TxGraph.

source

pub fn spk_index(&self) -> &KeychainTxOutIndex<KeychainKind>

Get a reference to the inner KeychainTxOutIndex.

source

pub fn local_chain(&self) -> &LocalChain

Get a reference to the inner LocalChain.

source

pub fn apply_block( &mut self, block: &Block, height: u32 ) -> Result<(), CannotConnectError>

Introduces a block of height to the wallet, and tries to connect it to the prev_blockhash of the block’s header.

This is a convenience method that is equivalent to calling apply_block_connected_to with prev_blockhash and height-1 as the connected_to parameter.

source

pub fn apply_block_connected_to( &mut self, block: &Block, height: u32, connected_to: BlockId ) -> Result<(), ApplyHeaderError>

Applies relevant transactions from block of height to the wallet, and connects the block to the internal chain.

The connected_to parameter informs the wallet how this block connects to the internal LocalChain. Relevant transactions are filtered from the block and inserted into the internal TxGraph.

source

pub fn apply_unconfirmed_txs<'t>( &mut self, unconfirmed_txs: impl IntoIterator<Item = (&'t Transaction, u64)> )

Apply relevant unconfirmed transactions to the wallet.

Transactions that are not relevant are filtered out.

This method takes in an iterator of (tx, last_seen) where last_seen is the timestamp of when the transaction was last seen in the mempool. This is used for conflict resolution when there is conflicting unconfirmed transactions. The transaction with the later last_seen is prioritized.

Trait Implementations§

source§

impl<D> AsRef<TxGraph<ConfirmationTimeHeightAnchor>> for Wallet<D>

source§

fn as_ref(&self) -> &TxGraph<ConfirmationTimeHeightAnchor>

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<D: Debug> Debug for Wallet<D>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<D = ()> !RefUnwindSafe for Wallet<D>

§

impl<D> Send for Wallet<D>
where D: Send,

§

impl<D> Sync for Wallet<D>
where D: Sync,

§

impl<D> Unpin for Wallet<D>
where D: Unpin,

§

impl<D = ()> !UnwindSafe for Wallet<D>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V