pub struct Wallet { /* 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:
- output descriptors from which it can derive addresses.
signer
s that can contribute signatures to addresses instantiated from the descriptors.
The user is responsible for loading and writing wallet changes which are represented as
ChangeSet
s (see take_staged
). Also see individual functions and example for instructions
on when Wallet
state needs to be persisted.
The Wallet
descriptor (external) and change descriptor (internal) must not derive the same
script pubkeys. See KeychainTxOutIndex::insert_descriptor()
for more details.
Implementations§
Source§impl Wallet
impl Wallet
Sourcepub fn create_single<D>(descriptor: D) -> CreateParams
pub fn create_single<D>(descriptor: D) -> CreateParams
Build a new single descriptor Wallet
.
If you have previously created a wallet, use load
instead.
§Note
Only use this method when creating a wallet designed to be used with a single
descriptor and keychain. Otherwise the recommended way to construct a new wallet is
by using Wallet::create
. It’s worth noting that not all features are available
with single descriptor wallets, for example setting a change_policy
on TxBuilder
and related methods such as do_not_spend_change
. This is because all payments are
received on the external keychain (including change), and without a change keychain
BDK lacks enough information to distinguish between change and outside payments.
Additionally because this wallet has no internal (change) keychain, all methods that
require a KeychainKind
as input, e.g. reveal_next_address
should only be called
using the External
variant. In most cases passing Internal
is treated as the
equivalent of External
but this behavior must not be relied on.
§Example
// Create a wallet that is persisted to SQLite database.
use bdk_wallet::rusqlite::Connection;
let mut conn = Connection::open(file_path)?;
let wallet = Wallet::create_single(EXTERNAL_DESC)
.network(Network::Testnet)
.create_wallet(&mut conn)?;
Sourcepub fn create<D>(descriptor: D, change_descriptor: D) -> CreateParams
pub fn create<D>(descriptor: D, change_descriptor: D) -> CreateParams
Build a new Wallet
.
If you have previously created a wallet, use load
instead.
§Synopsis
// Create a non-persisted wallet.
let wallet = Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
.network(Network::Testnet)
.create_wallet_no_persist()?;
// Create a wallet that is persisted to SQLite database.
use bdk_wallet::rusqlite::Connection;
let mut conn = Connection::open(file_path)?;
let wallet = Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
.network(Network::Testnet)
.create_wallet(&mut conn)?;
Sourcepub fn create_from_two_path_descriptor<D>(
two_path_descriptor: D,
) -> CreateParams
pub fn create_from_two_path_descriptor<D>( two_path_descriptor: D, ) -> CreateParams
Build a new Wallet
from a two-path descriptor.
This function parses a multipath descriptor with exactly 2 paths and creates a wallet
using the existing receive and change wallet creation logic. Note that you can only use this
method with public extended keys (xpub
prefix) to create watch-only wallets.
Multipath descriptors follow BIP 389 and allow defining both receive and change
derivation paths in a single descriptor using the <0;1>
syntax.
If you have previously created a wallet, use load
instead.
§Errors
Returns an error if the descriptor is invalid, not a 2-path multipath descriptor, or if
the descriptor provided contains an extended private key (xprv
prefix).
§Synopsis
let wallet = Wallet::create_from_two_path_descriptor(TWO_PATH_DESC)
.network(Network::Testnet)
.create_wallet_no_persist()
.unwrap();
// The multipath descriptor automatically creates separate receive and change descriptors
let receive_addr = wallet.peek_address(KeychainKind::External, 0); // Uses path /0/*
let change_addr = wallet.peek_address(KeychainKind::Internal, 0); // Uses path /1/*
assert_ne!(receive_addr.address, change_addr.address);
Sourcepub fn create_with_params(params: CreateParams) -> Result<Self, DescriptorError>
pub fn create_with_params(params: CreateParams) -> Result<Self, DescriptorError>
Create a new Wallet
with given params
.
Refer to Wallet::create
for more.
Sourcepub fn load() -> LoadParams
pub fn load() -> LoadParams
Build Wallet
by loading from persistence or ChangeSet
.
Note that the descriptor secret keys are not persisted to the db. You can add
signers after-the-fact with Wallet::add_signer
or Wallet::set_keymap
. You
can also add keys when building the wallet by using LoadParams::keymap
. Finally
you can check the wallet’s descriptors are what you expect with LoadParams::descriptor
which will try to populate signers if LoadParams::extract_keys
is enabled.
§Synopsis
// Load a wallet from changeset (no persistence).
let wallet = Wallet::load()
.load_wallet_no_persist(changeset)?
.expect("must have data to load wallet");
// Load a wallet that is persisted to SQLite database.
let mut conn = bdk_wallet::rusqlite::Connection::open(file_path)?;
let mut wallet = Wallet::load()
// check loaded descriptors matches these values and extract private keys
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
.extract_keys()
// you can also manually add private keys
.keymap(KeychainKind::External, external_keymap)
.keymap(KeychainKind::Internal, internal_keymap)
// ensure loaded wallet's genesis hash matches this value
.check_genesis_hash(genesis_hash)
// set a lookahead for our indexer
.lookahead(101)
.load_wallet(&mut conn)?
.expect("must have data to load wallet");
Sourcepub fn load_with_params(
changeset: ChangeSet,
params: LoadParams,
) -> Result<Option<Self>, LoadError>
pub fn load_with_params( changeset: ChangeSet, params: LoadParams, ) -> Result<Option<Self>, LoadError>
Load Wallet
from the given previously persisted ChangeSet
and params
.
Returns Ok(None)
if the changeset is empty. Refer to Wallet::load
for more.
Sourcepub fn keychains(
&self,
) -> impl Iterator<Item = (KeychainKind, &ExtendedDescriptor)>
pub fn keychains( &self, ) -> impl Iterator<Item = (KeychainKind, &ExtendedDescriptor)>
Iterator over all keychains in this wallet
Sourcepub fn peek_address(&self, keychain: KeychainKind, index: u32) -> AddressInfo
pub fn peek_address(&self, keychain: KeychainKind, index: u32) -> AddressInfo
Sourcepub fn reveal_next_address(&mut self, keychain: KeychainKind) -> AddressInfo
pub fn reveal_next_address(&mut self, keychain: KeychainKind) -> AddressInfo
Attempt to reveal the next address of the given keychain
.
This will increment the keychain’s derivation index. If the keychain’s descriptor doesn’t contain a wildcard or every address is already revealed up to the maximum derivation index defined in BIP32, then the last revealed address will be returned.
WARNING: To avoid address reuse you must persist the changes resulting from one or more calls to this method before closing the wallet. For example:
use bdk_chain::rusqlite::Connection;
let mut conn = Connection::open_in_memory().expect("must open connection");
let mut wallet = LoadParams::new()
.load_wallet(&mut conn)
.expect("database is okay")
.expect("database has data");
let next_address = wallet.reveal_next_address(KeychainKind::External);
wallet.persist(&mut conn).expect("write is okay");
// Now it's safe to show the user their next address!
println!("Next address: {}", next_address.address);
Sourcepub fn reveal_addresses_to(
&mut self,
keychain: KeychainKind,
index: u32,
) -> impl Iterator<Item = AddressInfo> + '_
pub fn reveal_addresses_to( &mut self, keychain: KeychainKind, index: u32, ) -> impl Iterator<Item = AddressInfo> + '_
Reveal addresses up to and including the target index
and return an iterator
of newly revealed addresses.
If the target index
is unreachable, we make a best effort to reveal up to the last
possible index. If all addresses up to the given index
are already revealed, then
no new addresses are returned.
WARNING: To avoid address reuse you must persist the changes resulting from one or more
calls to this method before closing the wallet. See Wallet::reveal_next_address
.
Sourcepub fn next_unused_address(&mut self, keychain: KeychainKind) -> AddressInfo
pub fn next_unused_address(&mut self, keychain: KeychainKind) -> AddressInfo
Get the next unused address for the given keychain
, i.e. the address with the lowest
derivation index that hasn’t been used in a transaction.
This will attempt to reveal a new address if all previously revealed addresses have
been used, in which case the returned address will be the same as calling
Wallet::reveal_next_address
.
WARNING: To avoid address reuse you must persist the changes resulting from one or more
calls to this method before closing the wallet. See Wallet::reveal_next_address
.
Sourcepub fn mark_used(&mut self, keychain: KeychainKind, index: u32) -> bool
pub fn mark_used(&mut self, keychain: KeychainKind, index: u32) -> bool
Marks an address used of the given keychain
at index
.
Returns whether the given index was present and then removed from the unused set.
Sourcepub fn unmark_used(&mut self, keychain: KeychainKind, index: u32) -> bool
pub fn unmark_used(&mut self, keychain: KeychainKind, index: u32) -> bool
Undoes the effect of mark_used
and returns whether the index
was inserted
back into the unused set.
Since this is only a superficial marker, it will have no effect if the address at the given
index
was actually used, i.e. the wallet has previously indexed a tx output for the
derived spk.
Sourcepub fn list_unused_addresses(
&self,
keychain: KeychainKind,
) -> impl DoubleEndedIterator<Item = AddressInfo> + '_
pub fn list_unused_addresses( &self, keychain: KeychainKind, ) -> impl DoubleEndedIterator<Item = AddressInfo> + '_
List addresses that are revealed but unused.
Note if the returned iterator is empty you can reveal more addresses
by using reveal_next_address
or
reveal_addresses_to
.
Sourcepub fn is_mine(&self, script: ScriptBuf) -> bool
pub fn is_mine(&self, script: ScriptBuf) -> bool
Return whether or not a script
is part of this wallet (either internal or external)
Sourcepub fn derivation_of_spk(&self, spk: ScriptBuf) -> Option<(KeychainKind, u32)>
pub fn derivation_of_spk(&self, spk: ScriptBuf) -> Option<(KeychainKind, u32)>
Finds how the wallet derived the script pubkey spk
.
Will only return Some(_)
if the wallet has given out the spk.
Sourcepub fn list_unspent(&self) -> impl Iterator<Item = LocalOutput> + '_
pub fn list_unspent(&self) -> impl Iterator<Item = LocalOutput> + '_
Return the list of unspent outputs of this wallet
Sourcepub fn tx_details(&self, txid: Txid) -> Option<TxDetails>
pub fn tx_details(&self, txid: Txid) -> Option<TxDetails>
Sourcepub fn list_output(&self) -> impl Iterator<Item = LocalOutput> + '_
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.
Sourcepub fn checkpoints(&self) -> CheckPointIter
pub fn checkpoints(&self) -> CheckPointIter
Get all the checkpoints the wallet is currently storing indexed by height.
Sourcepub fn latest_checkpoint(&self) -> CheckPoint
pub fn latest_checkpoint(&self) -> CheckPoint
Returns the latest checkpoint.
Sourcepub fn all_unbounded_spk_iters(
&self,
) -> BTreeMap<KeychainKind, impl Iterator<Item = Indexed<ScriptBuf>> + Clone>
pub fn all_unbounded_spk_iters( &self, ) -> BTreeMap<KeychainKind, impl Iterator<Item = Indexed<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).
Sourcepub fn unbounded_spk_iter(
&self,
keychain: KeychainKind,
) -> impl Iterator<Item = Indexed<ScriptBuf>> + Clone
pub fn unbounded_spk_iter( &self, keychain: KeychainKind, ) -> impl Iterator<Item = Indexed<ScriptBuf>> + Clone
Get an unbounded script pubkey iterator for the given keychain
.
See all_unbounded_spk_iters
for more documentation
Sourcepub fn get_utxo(&self, op: OutPoint) -> Option<LocalOutput>
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.
Sourcepub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut)
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
.
WARNINGS: This should only be used to add TxOut
s that the wallet does not own. Only
insert TxOut
s that you trust the values for!
You must persist the changes resulting from one or more calls to this method if you need
the inserted TxOut
data to be reloaded after closing the wallet.
See Wallet::reveal_next_address
.
Sourcepub fn calculate_fee(
&self,
tx: &Transaction,
) -> Result<Amount, CalculateFeeError>
pub fn calculate_fee( &self, tx: &Transaction, ) -> Result<Amount, CalculateFeeError>
Calculates the fee of a given transaction. Returns Amount::ZERO
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().expect("tx");
let fee = wallet.calculate_fee(tx).expect("fee");
Sourcepub fn calculate_fee_rate(
&self,
tx: &Transaction,
) -> Result<FeeRate, CalculateFeeError>
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().expect("tx");
let fee_rate = wallet.calculate_fee_rate(tx).expect("fee rate");
Sourcepub fn sent_and_received(&self, tx: &Transaction) -> (Amount, Amount)
pub fn sent_and_received(&self, tx: &Transaction) -> (Amount, Amount)
Compute the tx
’s sent and received Amount
s.
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("tx exists").tx_node.tx;
let (sent, received) = wallet.sent_and_received(&tx);
let tx = &psbt.clone().extract_tx().expect("tx");
let (sent, received) = wallet.sent_and_received(tx);
Sourcepub fn get_tx(&self, txid: Txid) -> Option<WalletTx<'_>>
pub fn get_tx(&self, txid: Txid) -> Option<WalletTx<'_>>
Get a single transaction from the wallet as a WalletTx
(if the transaction exists).
WalletTx
contains the full transaction alongside meta-data such as:
- Blocks that the transaction is
Anchor
ed 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::Anchor;
use bdk_wallet::{chain::ChainPosition, Wallet};
let wallet_tx = wallet.get_tx(my_txid).expect("panic if tx does not exist");
// get reference to full transaction
println!("my tx: {:#?}", wallet_tx.tx_node.tx);
// list all transaction anchors
for anchor in wallet_tx.tx_node.anchors {
println!(
"tx is anchored by block of hash {}",
anchor.anchor_block().hash
);
}
// get confirmation status of transaction
match wallet_tx.chain_position {
ChainPosition::Confirmed {
anchor,
transitively: None,
} => println!(
"tx is confirmed at height {}, we know this since {}:{} is in the best chain",
anchor.block_id.height, anchor.block_id.height, anchor.block_id.hash,
),
ChainPosition::Confirmed {
anchor,
transitively: Some(_),
} => println!(
"tx is an ancestor of a tx anchored in {}:{}",
anchor.block_id.height, anchor.block_id.hash,
),
ChainPosition::Unconfirmed { first_seen, last_seen } => println!(
"tx is first seen at {:?}, last seen at {:?}, it is unconfirmed as it is not anchored in the best chain",
first_seen, last_seen
),
}
Sourcepub fn transactions<'a>(&'a self) -> impl Iterator<Item = WalletTx<'a>> + 'a
pub fn transactions<'a>(&'a self) -> impl Iterator<Item = WalletTx<'a>> + 'a
Iterate over relevant and canonical transactions in the wallet.
A transaction is relevant when it spends from or spends to at least one tracked output. A transaction is canonical when it is confirmed in the best chain, or does not conflict with any transaction confirmed in the best chain.
To iterate over all transactions, including those that are irrelevant and not canonical, use
TxGraph::full_txs
.
To iterate over all canonical transactions, including those that are irrelevant, use
TxGraph::list_canonical_txs
.
Sourcepub fn transactions_sort_by<F>(&self, compare: F) -> Vec<WalletTx<'_>> ⓘ
pub fn transactions_sort_by<F>(&self, compare: F) -> Vec<WalletTx<'_>> ⓘ
Array of relevant and canonical transactions in the wallet sorted with a comparator function.
This is a helper method equivalent to collecting the result of Wallet::transactions
into a Vec
and then sorting it.
§Example
// Transactions by chain position: first unconfirmed then descending by confirmed height.
let sorted_txs: Vec<WalletTx> =
wallet.transactions_sort_by(|tx1, tx2| tx2.chain_position.cmp(&tx1.chain_position));
Sourcepub fn balance(&self) -> Balance
pub fn balance(&self) -> Balance
Return the balance, separated into available, trusted-pending, untrusted-pending, and immature values.
Sourcepub fn add_signer(
&mut self,
keychain: KeychainKind,
ordering: SignerOrdering,
signer: Arc<dyn TransactionSigner>,
)
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.
Sourcepub fn set_keymap(&mut self, keychain: KeychainKind, keymap: KeyMap)
pub fn set_keymap(&mut self, keychain: KeychainKind, keymap: KeyMap)
Set the keymap for a given keychain.
Note this does nothing if the given keychain has no descriptor because we won’t know the context (segwit, taproot, etc) in which to create signatures.
Sourcepub fn set_keymaps(
&mut self,
keymaps: impl IntoIterator<Item = (KeychainKind, KeyMap)>,
)
pub fn set_keymaps( &mut self, keymaps: impl IntoIterator<Item = (KeychainKind, KeyMap)>, )
Set the keymap for each keychain.
Sourcepub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer>
pub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer>
Get the signers
§Example
let descriptor = "wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/1'/0'/0/*)";
let change_descriptor = "wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/1'/0'/1/*)";
let wallet = Wallet::create(descriptor, change_descriptor)
.network(Network::Testnet)
.create_wallet_no_persist()?;
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>>(())
Sourcepub fn build_tx(&mut self) -> TxBuilder<'_, DefaultCoinSelectionAlgorithm>
pub fn build_tx(&mut self) -> TxBuilder<'_, DefaultCoinSelectionAlgorithm>
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(), Amount::from_sat(50_000));
builder.finish()?
};
// sign and broadcast ...
Sourcepub fn build_fee_bump(
&mut self,
txid: Txid,
) -> Result<TxBuilder<'_, DefaultCoinSelectionAlgorithm>, BuildFeeBumpError>
pub fn build_fee_bump( &mut self, txid: Txid, ) -> Result<TxBuilder<'_, DefaultCoinSelectionAlgorithm>, 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(), Amount::from_sat(50_000));
builder.finish()?
};
let _ = wallet.sign(&mut psbt, SignOptions::default())?;
let tx = psbt.clone().extract_tx().expect("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.compute_txid())?;
builder
.fee_rate(FeeRate::from_sat_per_vb(5).expect("valid feerate"));
builder.finish()?
};
let _ = wallet.sign(&mut psbt, SignOptions::default())?;
let fee_bumped_tx = psbt.extract_tx();
// broadcast fee_bumped_tx to replace original
Sourcepub fn sign(
&self,
psbt: &mut Psbt,
sign_options: SignOptions,
) -> Result<bool, SignerError>
pub fn sign( &self, psbt: &mut Psbt, 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(), Amount::from_sat(50_000));
builder.finish()?
};
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
assert!(finalized, "we should have signed all the inputs");
Sourcepub fn policies(
&self,
keychain: KeychainKind,
) -> Result<Option<Policy>, DescriptorError>
pub fn policies( &self, keychain: KeychainKind, ) -> Result<Option<Policy>, DescriptorError>
Return the spending policies for the wallet’s descriptor
Sourcepub fn public_descriptor(&self, keychain: KeychainKind) -> &ExtendedDescriptor
pub fn public_descriptor(&self, keychain: KeychainKind) -> &ExtendedDescriptor
Returns the descriptor used to create addresses for a particular keychain
.
It’s the “public” version of the wallet’s descriptor, meaning a new descriptor that has the same structure but with the all secret keys replaced by their corresponding public key. This can be used to build a watch-only version of a wallet.
Sourcepub fn finalize_psbt(
&self,
psbt: &mut Psbt,
sign_options: SignOptions,
) -> Result<bool, SignerError>
pub fn finalize_psbt( &self, psbt: &mut Psbt, 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,
and BIP371
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.
Sourcepub fn secp_ctx(&self) -> &Secp256k1<All>
pub fn secp_ctx(&self) -> &Secp256k1<All>
Return the secp256k1 context used for all signing operations
Sourcepub fn derivation_index(&self, keychain: KeychainKind) -> Option<u32>
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.
Sourcepub fn next_derivation_index(&self, keychain: KeychainKind) -> u32
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
Sourcepub fn cancel_tx(&mut self, tx: &Transaction)
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.
Sourcepub fn get_psbt_input(
&self,
utxo: LocalOutput,
sighash_type: Option<PsbtSighashType>,
only_witness_utxo: bool,
) -> Result<Input, CreateTxError>
pub fn get_psbt_input( &self, utxo: LocalOutput, sighash_type: Option<PsbtSighashType>, only_witness_utxo: bool, ) -> Result<Input, CreateTxError>
get the corresponding PSBT Input for a LocalUtxo
Sourcepub fn descriptor_checksum(&self, keychain: KeychainKind) -> String
pub fn descriptor_checksum(&self, keychain: KeychainKind) -> String
Return the checksum of the public descriptor associated to keychain
Internally calls Self::public_descriptor
to fetch the right descriptor
Sourcepub fn apply_update(
&mut self,
update: impl Into<Update>,
) -> Result<(), CannotConnectError>
pub fn apply_update( &mut self, update: impl Into<Update>, ) -> Result<(), CannotConnectError>
Applies an update to the wallet and stages the changes (but does not persist them).
Usually you create an update
by interacting with some blockchain data source and inserting
transactions related to your wallet into it.
After applying updates you should persist the staged wallet changes. For an example of how
to persist staged wallet changes see Wallet::reveal_next_address
.
Sourcepub fn apply_update_events(
&mut self,
update: impl Into<Update>,
) -> Result<Vec<WalletEvent>, CannotConnectError>
pub fn apply_update_events( &mut self, update: impl Into<Update>, ) -> Result<Vec<WalletEvent>, CannotConnectError>
Applies an update to the wallet, stages the changes, and returns events.
Usually you create an update
by interacting with some blockchain data source and inserting
transactions related to your wallet into it. Staged changes are NOT persisted.
After applying updates you should process the events in your app before persisting the
staged wallet changes. For an example of how to persist staged wallet changes see
Wallet::reveal_next_address
.
use bdk_wallet::event::WalletEvent;
let events = wallet.apply_update_events(wallet_update)?;
// Handle wallet relevant events from this update.
events.iter().for_each(|event| {
match event {
// The chain tip changed.
WalletEvent::ChainTipChanged { old_tip, new_tip } => {
todo!() // handle event
}
// An unconfirmed tx is now confirmed in a block.
WalletEvent::TxConfirmed {
txid,
tx,
block_time,
old_block_time: None,
} => {
todo!() // handle event
}
// A confirmed tx is now confirmed in a new block (reorg).
WalletEvent::TxConfirmed {
txid,
tx,
block_time,
old_block_time: Some(old_block_time),
} => {
todo!() // handle event
}
// A new unconfirmed tx was seen in the mempool.
WalletEvent::TxUnconfirmed {
txid,
tx,
old_block_time: None,
} => {
todo!() // handle event
}
// A previously confirmed tx in now unconfirmed in the mempool (reorg).
WalletEvent::TxUnconfirmed {
txid,
tx,
old_block_time: Some(old_block_time),
} => {
todo!() // handle event
}
// An unconfirmed tx was replaced in the mempool (RBF or double spent input).
WalletEvent::TxReplaced {
txid,
tx,
conflicts,
} => {
todo!() // handle event
}
// An unconfirmed tx was dropped from the mempool (fee too low).
WalletEvent::TxDropped { txid, tx } => {
todo!() // handle event
}
_ => {
// unexpected event, do nothing
}
}
// take staged wallet changes
let staged = wallet.take_staged();
// persist staged changes
});
Sourcepub fn staged(&self) -> Option<&ChangeSet>
pub fn staged(&self) -> Option<&ChangeSet>
Get a reference of the staged ChangeSet
that is yet to be committed (if any).
Sourcepub fn staged_mut(&mut self) -> Option<&mut ChangeSet>
pub fn staged_mut(&mut self) -> Option<&mut ChangeSet>
Get a mutable reference of the staged ChangeSet
that is yet to be committed (if any).
Sourcepub fn take_staged(&mut self) -> Option<ChangeSet>
pub fn take_staged(&mut self) -> Option<ChangeSet>
Take the staged ChangeSet
to be persisted now (if any).
Sourcepub fn tx_graph(&self) -> &TxGraph<ConfirmationBlockTime>
pub fn tx_graph(&self) -> &TxGraph<ConfirmationBlockTime>
Get a reference to the inner TxGraph
.
Sourcepub fn spk_index(&self) -> &KeychainTxOutIndex<KeychainKind>
pub fn spk_index(&self) -> &KeychainTxOutIndex<KeychainKind>
Get a reference to the inner KeychainTxOutIndex
.
Sourcepub fn local_chain(&self) -> &LocalChain
pub fn local_chain(&self) -> &LocalChain
Get a reference to the inner LocalChain
.
Sourcepub fn apply_block(
&mut self,
block: &Block,
height: u32,
) -> Result<(), CannotConnectError>
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.
Sourcepub fn apply_block_connected_to(
&mut self,
block: &Block,
height: u32,
connected_to: BlockId,
) -> Result<(), ApplyHeaderError>
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
.
WARNING: You must persist the changes resulting from one or more calls to this method
if you need the inserted block data to be reloaded after closing the wallet.
See Wallet::reveal_next_address
.
Sourcepub fn apply_unconfirmed_txs<T: Into<Arc<Transaction>>>(
&mut self,
unconfirmed_txs: impl IntoIterator<Item = (T, u64)>,
)
pub fn apply_unconfirmed_txs<T: Into<Arc<Transaction>>>( &mut self, unconfirmed_txs: impl IntoIterator<Item = (T, 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.
WARNING: You must persist the changes resulting from one or more calls to this method
if you need the applied unconfirmed transactions to be reloaded after closing the wallet.
See Wallet::reveal_next_address
.
Sourcepub fn apply_evicted_txs(
&mut self,
evicted_txs: impl IntoIterator<Item = (Txid, u64)>,
)
pub fn apply_evicted_txs( &mut self, evicted_txs: impl IntoIterator<Item = (Txid, u64)>, )
Apply evictions of the given transaction IDs with their associated timestamps.
This function is used to mark specific unconfirmed transactions as evicted from the mempool.
Eviction means that these transactions are not considered canonical by default, and will
no longer be part of the wallet’s transactions
set. This can happen for example when
a transaction is dropped from the mempool due to low fees or conflicts with another
transaction.
Only transactions that are currently unconfirmed and canonical are considered for eviction. Transactions that are not relevant to the wallet are ignored. Note that an evicted transaction can become canonical again if it is later observed on-chain or seen in the mempool with a higher priority (e.g., due to a fee bump).
§Parameters
evicted_txs
: An iterator of (Txid, u64)
tuples, where:
Txid
: The transaction ID of the transaction to be evicted.u64
: The timestamp indicating when the transaction was evicted from the mempool. This will usually correspond to the time of the latest chain sync. See docs forstart_sync_with_revealed_spks
.
§Notes
- Not all blockchain backends support automatic mempool eviction handling - this method may
be used in such cases. It can also be used to negate the effect of
apply_unconfirmed_txs
for a particular transaction without the need for an additional sync. - The changes are staged in the wallet’s internal state and must be persisted to ensure they
are retained across wallet restarts. Use
Wallet::take_staged
to retrieve the staged changes and persist them to your database of choice. - Evicted transactions are removed from the wallet’s canonical transaction set, but the data remains in the wallet’s internal transaction graph for historical purposes.
- Ensure that the timestamps provided are accurate and monotonically increasing, as they influence the wallet’s canonicalization logic.
Source§impl Wallet
Methods to construct sync/full-scan requests for spk-based chain sources.
impl Wallet
Methods to construct sync/full-scan requests for spk-based chain sources.
Sourcepub fn start_sync_with_revealed_spks_at(
&self,
start_time: u64,
) -> SyncRequestBuilder<(KeychainKind, u32)>
pub fn start_sync_with_revealed_spks_at( &self, start_time: u64, ) -> SyncRequestBuilder<(KeychainKind, u32)>
Create a partial SyncRequest
for all revealed spks at start_time
.
The start_time
is used to record the time that a mempool transaction was last seen
(or evicted). See Wallet::start_sync_with_revealed_spks
for more.
Sourcepub fn start_sync_with_revealed_spks(
&self,
) -> SyncRequestBuilder<(KeychainKind, u32)>
Available on crate feature std
only.
pub fn start_sync_with_revealed_spks( &self, ) -> SyncRequestBuilder<(KeychainKind, u32)>
std
only.Create a partial SyncRequest
for this wallet for all revealed spks.
This is the first step when performing a spk-based wallet partial sync, the returned
SyncRequest
collects all revealed script pubkeys from the wallet keychain needed to
start a blockchain sync with a spk based blockchain client.
The time of the sync is the current system time and is used to record the
tx last-seen for mempool transactions. Or if an expected transaction is missing
or evicted, it is the time of the eviction. Note that timestamps may only increase
to be counted by the tx graph. To supply your own start time see
Wallet::start_sync_with_revealed_spks_at
.
Sourcepub fn start_full_scan(&self) -> FullScanRequestBuilder<KeychainKind>
Available on crate feature std
only.
pub fn start_full_scan(&self) -> FullScanRequestBuilder<KeychainKind>
std
only.Create a `FullScanRequest for this wallet.
This is the first step when performing a spk-based wallet full scan, the returned `FullScanRequest collects iterators for the wallet’s keychain script pub keys needed to start a blockchain full scan with a spk based blockchain client.
This operation is generally only used when importing or restoring a previously used wallet in which the list of used scripts is not known.
The time of the scan is the current system time and is used to record the tx last-seen for
mempool transactions. To supply your own start time see Wallet::start_full_scan_at
.
Sourcepub fn start_full_scan_at(
&self,
start_time: u64,
) -> FullScanRequestBuilder<KeychainKind>
pub fn start_full_scan_at( &self, start_time: u64, ) -> FullScanRequestBuilder<KeychainKind>
Create a FullScanRequest
builder at start_time
.