///
/// [`signer`]: crate::signer
#[derive(Debug)]
-pub struct Wallet<D = ()> {
+pub struct Wallet {
signers: Arc<SignersContainer>,
change_signers: Arc<SignersContainer>,
chain: LocalChain,
indexed_graph: IndexedTxGraph<ConfirmationTimeHeightAnchor, KeychainTxOutIndex<KeychainKind>>,
- persist: Persist<D, ChangeSet>,
+ persist: Persist<ChangeSet>,
network: Network,
secp: SecpCtx,
}
Self::new(descriptor, change_descriptor, (), network).map_err(|e| match e {
NewError::NonEmptyDatabase => unreachable!("mock-database cannot have data"),
NewError::Descriptor(e) => e,
- NewError::Write(_) => unreachable!("mock-write must always succeed"),
+ NewError::Persist(_) => unreachable!("mock-write must always succeed"),
})
}
.map_err(|e| match e {
NewError::NonEmptyDatabase => unreachable!("mock-database cannot have data"),
NewError::Descriptor(e) => e,
- NewError::Write(_) => unreachable!("mock-write must always succeed"),
+ NewError::Persist(_) => unreachable!("mock-write must always succeed"),
})
}
}
-impl<D> Wallet<D>
-where
- D: PersistBackend<ChangeSet, WriteError = core::convert::Infallible>,
-{
+impl Wallet {
/// 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`].
/// [`new`]: Wallet::new
/// [`new_with_genesis_hash`]: Wallet::new_with_genesis_hash
#[derive(Debug)]
-pub enum NewError<W> {
+pub enum NewError {
/// Database already has data.
NonEmptyDatabase,
/// There was problem with the passed-in descriptor(s).
Descriptor(crate::descriptor::DescriptorError),
/// We were unable to write the wallet's data to the persistence backend.
- Write(W),
+ Persist(anyhow::Error),
}
-impl<W> fmt::Display for NewError<W>
-where
- W: fmt::Display,
-{
+impl fmt::Display for NewError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NewError::NonEmptyDatabase => write!(
"database already has data - use `load` or `new_or_load` methods instead"
),
NewError::Descriptor(e) => e.fmt(f),
- NewError::Write(e) => e.fmt(f),
+ NewError::Persist(e) => e.fmt(f),
}
}
}
#[cfg(feature = "std")]
-impl<W> std::error::Error for NewError<W> where W: core::fmt::Display + core::fmt::Debug {}
+impl std::error::Error for NewError {}
/// The error type when loading a [`Wallet`] from persistence.
///
///
/// [`load`]: Wallet::load
#[derive(Debug)]
-pub enum LoadError<L> {
+pub enum LoadError {
/// There was a problem with the passed-in descriptor(s).
Descriptor(crate::descriptor::DescriptorError),
/// Loading data from the persistence backend failed.
- Load(L),
+ Persist(anyhow::Error),
/// Wallet not initialized, persistence backend is empty.
NotInitialized,
/// Data loaded from persistence is missing network type.
MissingGenesis,
}
-impl<L> fmt::Display for LoadError<L>
-where
- L: fmt::Display,
-{
+impl fmt::Display for LoadError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LoadError::Descriptor(e) => e.fmt(f),
- LoadError::Load(e) => e.fmt(f),
+ LoadError::Persist(e) => e.fmt(f),
LoadError::NotInitialized => {
write!(f, "wallet is not initialized, persistence backend is empty")
}
}
#[cfg(feature = "std")]
-impl<L> std::error::Error for LoadError<L> where L: core::fmt::Display + core::fmt::Debug {}
+impl std::error::Error for LoadError {}
/// Error type for when we try load a [`Wallet`] from persistence and creating it if non-existent.
///
/// [`new_or_load`]: Wallet::new_or_load
/// [`new_or_load_with_genesis_hash`]: Wallet::new_or_load_with_genesis_hash
#[derive(Debug)]
-pub enum NewOrLoadError<W, L> {
+pub enum NewOrLoadError {
/// There is a problem with the passed-in descriptor.
Descriptor(crate::descriptor::DescriptorError),
- /// Writing to the persistence backend failed.
- Write(W),
- /// Loading from the persistence backend failed.
- Load(L),
+ /// Either writing to or loading from the persistence backend failed.
+ Persist(anyhow::Error),
/// Wallet is not initialized, persistence backend is empty.
NotInitialized,
/// The loaded genesis hash does not match what was provided.
},
}
-impl<W, L> fmt::Display for NewOrLoadError<W, L>
-where
- W: fmt::Display,
- L: fmt::Display,
-{
+impl fmt::Display for NewOrLoadError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NewOrLoadError::Descriptor(e) => e.fmt(f),
- NewOrLoadError::Write(e) => write!(f, "failed to write to persistence: {}", e),
- NewOrLoadError::Load(e) => write!(f, "failed to load from persistence: {}", e),
+ NewOrLoadError::Persist(e) => write!(
+ f,
+ "failed to either write to or load from persistence, {}",
+ e
+ ),
NewOrLoadError::NotInitialized => {
write!(f, "wallet is not initialized, persistence backend is empty")
}
}
#[cfg(feature = "std")]
-impl<W, L> std::error::Error for NewOrLoadError<W, L>
-where
- W: core::fmt::Display + core::fmt::Debug,
- L: core::fmt::Display + core::fmt::Debug,
-{
-}
+impl std::error::Error for NewOrLoadError {}
/// An error that may occur when inserting a transaction into [`Wallet`].
#[derive(Debug)]
#[cfg(feature = "std")]
impl std::error::Error for ApplyBlockError {}
-impl<D> Wallet<D> {
+impl Wallet {
/// Initialize an empty [`Wallet`].
pub fn new<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
- db: D,
+ db: impl PersistBackend<ChangeSet> + Send + Sync + 'static,
network: Network,
- ) -> Result<Self, NewError<D::WriteError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<Self, NewError> {
let genesis_hash = genesis_block(network).block_hash();
Self::new_with_genesis_hash(descriptor, change_descriptor, db, network, genesis_hash)
}
pub fn new_with_genesis_hash<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
- mut db: D,
+ mut db: impl PersistBackend<ChangeSet> + Send + Sync + 'static,
network: Network,
genesis_hash: BlockHash,
- ) -> Result<Self, NewError<D::WriteError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<Self, NewError> {
if let Ok(changeset) = db.load_from_persistence() {
if changeset.is_some() {
return Err(NewError::NonEmptyDatabase);
indexed_tx_graph: indexed_graph.initial_changeset(),
network: Some(network),
});
- persist.commit().map_err(NewError::Write)?;
+ persist.commit().map_err(NewError::Persist)?;
Ok(Wallet {
signers,
pub fn load<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
- mut db: D,
- ) -> Result<Self, LoadError<D::LoadError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ mut db: impl PersistBackend<ChangeSet> + Send + Sync + 'static,
+ ) -> Result<Self, LoadError> {
let changeset = db
.load_from_persistence()
- .map_err(LoadError::Load)?
+ .map_err(LoadError::Persist)?
.ok_or(LoadError::NotInitialized)?;
Self::load_from_changeset(descriptor, change_descriptor, db, changeset)
}
fn load_from_changeset<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
- db: D,
+ db: impl PersistBackend<ChangeSet> + Send + Sync + 'static,
changeset: ChangeSet,
- ) -> Result<Self, LoadError<D::LoadError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<Self, LoadError> {
let secp = Secp256k1::new();
let network = changeset.network.ok_or(LoadError::MissingNetwork)?;
let chain =
pub fn new_or_load<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
- db: D,
+ db: impl PersistBackend<ChangeSet> + Send + Sync + 'static,
network: Network,
- ) -> Result<Self, NewOrLoadError<D::WriteError, D::LoadError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<Self, NewOrLoadError> {
let genesis_hash = genesis_block(network).block_hash();
Self::new_or_load_with_genesis_hash(
descriptor,
pub fn new_or_load_with_genesis_hash<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
- mut db: D,
+ mut db: impl PersistBackend<ChangeSet> + Send + Sync + 'static,
network: Network,
genesis_hash: BlockHash,
- ) -> Result<Self, NewOrLoadError<D::WriteError, D::LoadError>>
- where
- D: PersistBackend<ChangeSet>,
- {
- let changeset = db.load_from_persistence().map_err(NewOrLoadError::Load)?;
+ ) -> Result<Self, NewOrLoadError> {
+ let changeset = db
+ .load_from_persistence()
+ .map_err(NewOrLoadError::Persist)?;
match changeset {
Some(changeset) => {
let wallet =
Self::load_from_changeset(descriptor, change_descriptor, db, changeset)
.map_err(|e| match e {
LoadError::Descriptor(e) => NewOrLoadError::Descriptor(e),
- LoadError::Load(e) => NewOrLoadError::Load(e),
+ LoadError::Persist(e) => NewOrLoadError::Persist(e),
LoadError::NotInitialized => NewOrLoadError::NotInitialized,
LoadError::MissingNetwork => {
NewOrLoadError::LoadedNetworkDoesNotMatch {
unreachable!("database is already checked to have no data")
}
NewError::Descriptor(e) => NewOrLoadError::Descriptor(e),
- NewError::Write(e) => NewOrLoadError::Write(e),
+ NewError::Persist(e) => NewOrLoadError::Persist(e),
}),
}
}
///
/// This panics when the caller requests for an address of derivation index greater than the
/// BIP32 max index.
- pub fn try_get_address(
- &mut self,
- address_index: AddressIndex,
- ) -> Result<AddressInfo, D::WriteError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ pub fn try_get_address(&mut self, address_index: AddressIndex) -> anyhow::Result<AddressInfo> {
self._get_address(KeychainKind::External, address_index)
}
pub fn try_get_internal_address(
&mut self,
address_index: AddressIndex,
- ) -> Result<AddressInfo, D::WriteError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> anyhow::Result<AddressInfo> {
self._get_address(KeychainKind::Internal, address_index)
}
&mut self,
keychain: KeychainKind,
address_index: AddressIndex,
- ) -> Result<AddressInfo, D::WriteError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> anyhow::Result<AddressInfo> {
let keychain = self.map_keychain(keychain);
let txout_index = &mut self.indexed_graph.index;
let (index, spk, changeset) = match address_index {
/// [`list_unspent`]: Self::list_unspent
/// [`list_output`]: Self::list_output
/// [`commit`]: Self::commit
- pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut)
- where
- D: PersistBackend<ChangeSet>,
- {
+ pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) {
let additions = self.indexed_graph.insert_txout(outpoint, txout);
self.persist.stage(ChangeSet::from(additions));
}
/// ```rust, no_run
/// # use bitcoin::Txid;
/// # use bdk::Wallet;
- /// # let mut wallet: Wallet<()> = todo!();
+ /// # let mut wallet: Wallet = todo!();
/// # let txid:Txid = todo!();
/// let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
/// let fee = wallet.calculate_fee(&tx).expect("fee");
/// ```rust, no_run
/// # use bitcoin::Psbt;
/// # use bdk::Wallet;
- /// # let mut wallet: Wallet<()> = todo!();
+ /// # let mut wallet: Wallet = todo!();
/// # let mut psbt: Psbt = todo!();
/// let tx = &psbt.clone().extract_tx().expect("tx");
/// let fee = wallet.calculate_fee(tx).expect("fee");
/// ```rust, no_run
/// # use bitcoin::Txid;
/// # use bdk::Wallet;
- /// # let mut wallet: Wallet<()> = todo!();
+ /// # let mut wallet: Wallet = todo!();
/// # let txid:Txid = todo!();
/// let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
/// let fee_rate = wallet.calculate_fee_rate(&tx).expect("fee rate");
/// ```rust, no_run
/// # use bitcoin::Psbt;
/// # use bdk::Wallet;
- /// # let mut wallet: Wallet<()> = todo!();
+ /// # let mut wallet: Wallet = todo!();
/// # let mut psbt: Psbt = todo!();
/// let tx = &psbt.clone().extract_tx().expect("tx");
/// let fee_rate = wallet.calculate_fee_rate(tx).expect("fee rate");
/// ```rust, no_run
/// # use bitcoin::Txid;
/// # use bdk::Wallet;
- /// # let mut wallet: Wallet<()> = todo!();
+ /// # let mut wallet: Wallet = todo!();
/// # let txid:Txid = todo!();
/// let tx = wallet.get_tx(txid).expect("tx exists").tx_node.tx;
/// let (sent, received) = wallet.sent_and_received(&tx);
/// ```rust, no_run
/// # use bitcoin::Psbt;
/// # use bdk::Wallet;
- /// # let mut wallet: Wallet<()> = todo!();
+ /// # let mut wallet: Wallet = todo!();
/// # let mut psbt: Psbt = todo!();
/// let tx = &psbt.clone().extract_tx().expect("tx");
/// let (sent, received) = wallet.sent_and_received(tx);
/// ```rust, no_run
/// use bdk::{chain::ChainPosition, Wallet};
/// use bdk_chain::Anchor;
- /// # let wallet: Wallet<()> = todo!();
+ /// # let wallet: Wallet = todo!();
/// # let my_txid: bitcoin::Txid = todo!();
///
/// let canonical_tx = wallet.get_tx(my_txid).expect("panic if tx does not exist");
pub fn insert_checkpoint(
&mut self,
block_id: BlockId,
- ) -> Result<bool, local_chain::AlterCheckPointError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<bool, local_chain::AlterCheckPointError> {
let changeset = self.chain.insert_block(block_id)?;
let changed = !changeset.is_empty();
self.persist.stage(changeset.into());
&mut self,
tx: Transaction,
position: ConfirmationTime,
- ) -> Result<bool, InsertTxError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<bool, InsertTxError> {
let (anchor, last_seen) = match position {
ConfirmationTime::Confirmed { height, time } => {
// anchor tx to checkpoint with lowest height that is >= position's height
/// ```
///
/// [`TxBuilder`]: crate::TxBuilder
- pub fn build_tx(&mut self) -> TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, CreateTx> {
+ pub fn build_tx(&mut self) -> TxBuilder<'_, DefaultCoinSelectionAlgorithm, CreateTx> {
TxBuilder {
wallet: alloc::rc::Rc::new(core::cell::RefCell::new(self)),
params: TxParams::default(),
&mut self,
coin_selection: Cs,
params: TxParams,
- ) -> Result<Psbt, CreateTxError<D::WriteError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<Psbt, CreateTxError> {
let external_descriptor = self
.indexed_graph
.index
let internal_policy = internal_descriptor
.as_ref()
.map(|desc| {
- Ok::<_, CreateTxError<D::WriteError>>(
+ Ok::<_, CreateTxError>(
desc.extract_policy(&self.change_signers, BuildSatisfaction::None, &self.secp)?
.unwrap(),
)
)?;
let internal_requirements = internal_policy
.map(|policy| {
- Ok::<_, CreateTxError<D::WriteError>>(
+ Ok::<_, CreateTxError>(
policy.get_condition(
params
.internal_policy_path
pub fn build_fee_bump(
&mut self,
txid: Txid,
- ) -> Result<TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, BumpFee>, BuildFeeBumpError> {
+ ) -> Result<TxBuilder<'_, DefaultCoinSelectionAlgorithm, BumpFee>, BuildFeeBumpError> {
let graph = self.indexed_graph.graph();
let txout_index = &self.indexed_graph.index;
let chain_tip = self.chain.tip().block_id();
tx: Transaction,
selected: Vec<Utxo>,
params: TxParams,
- ) -> Result<Psbt, CreateTxError<D::WriteError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<Psbt, CreateTxError> {
let mut psbt = Psbt::from_unsigned_tx(tx)?;
if params.add_global_xpubs {
utxo: LocalOutput,
sighash_type: Option<psbt::PsbtSighashType>,
only_witness_utxo: bool,
- ) -> Result<psbt::Input, CreateTxError<D::WriteError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<psbt::Input, CreateTxError> {
// Try to find the prev_script in our db to figure out if this is internal or external,
// and the derivation index
let (keychain, child) = self
/// transactions related to your wallet into it.
///
/// [`commit`]: Self::commit
- pub fn apply_update(&mut self, update: Update) -> Result<(), CannotConnectError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ pub fn apply_update(&mut self, update: Update) -> Result<(), CannotConnectError> {
let mut changeset = match update.chain {
Some(chain_update) => ChangeSet::from(self.chain.apply_update(chain_update)?),
None => ChangeSet::default(),
changeset.append(ChangeSet::from(
self.indexed_graph.apply_update(update.graph),
));
-
self.persist.stage(changeset);
Ok(())
}
/// This returns whether the `update` resulted in any changes.
///
/// [`staged`]: Self::staged
- pub fn commit(&mut self) -> Result<bool, D::WriteError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ pub fn commit(&mut self) -> anyhow::Result<bool> {
self.persist.commit().map(|c| c.is_some())
}
/// Returns the changes that will be committed with the next call to [`commit`].
///
/// [`commit`]: Self::commit
- pub fn staged(&self) -> &ChangeSet
- where
- D: PersistBackend<ChangeSet>,
- {
+ pub fn staged(&self) -> &ChangeSet {
self.persist.staged()
}
/// with `prev_blockhash` and `height-1` as the `connected_to` parameter.
///
/// [`apply_block_connected_to`]: Self::apply_block_connected_to
- pub fn apply_block(&mut self, block: &Block, height: u32) -> Result<(), CannotConnectError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ pub fn apply_block(&mut self, block: &Block, height: u32) -> Result<(), CannotConnectError> {
let connected_to = match height.checked_sub(1) {
Some(prev_height) => BlockId {
height: prev_height,
block: &Block,
height: u32,
connected_to: BlockId,
- ) -> Result<(), ApplyHeaderError>
- where
- D: PersistBackend<ChangeSet>,
- {
+ ) -> Result<(), ApplyHeaderError> {
let mut changeset = ChangeSet::default();
changeset.append(
self.chain
pub fn apply_unconfirmed_txs<'t>(
&mut self,
unconfirmed_txs: impl IntoIterator<Item = (&'t Transaction, u64)>,
- ) where
- D: PersistBackend<ChangeSet>,
- {
+ ) {
let indexed_graph_changeset = self
.indexed_graph
.batch_insert_relevant_unconfirmed(unconfirmed_txs);
}
}
-impl<D> AsRef<bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor>> for Wallet<D> {
+impl AsRef<bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor>> for Wallet {
fn as_ref(&self) -> &bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor> {
self.indexed_graph.graph()
}
use core::fmt;
use core::marker::PhantomData;
-use bdk_chain::PersistBackend;
use bitcoin::psbt::{self, Psbt};
use bitcoin::script::PushBytes;
use bitcoin::{absolute, FeeRate, OutPoint, ScriptBuf, Sequence, Transaction, Txid};
use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
-use super::{ChangeSet, CreateTxError, Wallet};
+use super::{CreateTxError, Wallet};
use crate::collections::{BTreeMap, HashSet};
use crate::{KeychainKind, LocalOutput, Utxo, WeightedUtxo};
/// [`finish`]: Self::finish
/// [`coin_selection`]: Self::coin_selection
#[derive(Debug)]
-pub struct TxBuilder<'a, D, Cs, Ctx> {
- pub(crate) wallet: Rc<RefCell<&'a mut Wallet<D>>>,
+pub struct TxBuilder<'a, Cs, Ctx> {
+ pub(crate) wallet: Rc<RefCell<&'a mut Wallet>>,
pub(crate) params: TxParams,
pub(crate) coin_selection: Cs,
pub(crate) phantom: PhantomData<Ctx>,
}
}
-impl<'a, D, Cs: Clone, Ctx> Clone for TxBuilder<'a, D, Cs, Ctx> {
+impl<'a, Cs: Clone, Ctx> Clone for TxBuilder<'a, Cs, Ctx> {
fn clone(&self) -> Self {
TxBuilder {
wallet: self.wallet.clone(),
}
// methods supported by both contexts, for any CoinSelectionAlgorithm
-impl<'a, D, Cs, Ctx> TxBuilder<'a, D, Cs, Ctx> {
+impl<'a, Cs, Ctx> TxBuilder<'a, Cs, Ctx> {
/// Set a custom fee rate.
///
/// This method sets the mining fee paid by the transaction as a rate on its size.
pub fn coin_selection<P: CoinSelectionAlgorithm>(
self,
coin_selection: P,
- ) -> TxBuilder<'a, D, P, Ctx> {
+ ) -> TxBuilder<'a, P, Ctx> {
TxBuilder {
wallet: self.wallet,
params: self.params,
}
}
-impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx> TxBuilder<'a, D, Cs, Ctx> {
+impl<'a, Cs: CoinSelectionAlgorithm, Ctx> TxBuilder<'a, Cs, Ctx> {
/// Finish building the transaction.
///
/// Returns a new [`Psbt`] per [`BIP174`].
///
/// [`BIP174`]: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
- pub fn finish(self) -> Result<Psbt, CreateTxError<D::WriteError>>
- where
- D: PersistBackend<ChangeSet>,
- {
+ pub fn finish(self) -> Result<Psbt, CreateTxError> {
self.wallet
.borrow_mut()
.create_tx(self.coin_selection, self.params)
#[cfg(feature = "std")]
impl std::error::Error for AllowShrinkingError {}
-impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs, CreateTx> {
+impl<'a, Cs: CoinSelectionAlgorithm> TxBuilder<'a, Cs, CreateTx> {
/// Replace the recipients already added with a new list
pub fn set_recipients(&mut self, recipients: Vec<(ScriptBuf, u64)>) -> &mut Self {
self.params.recipients = recipients;
}
// methods supported only by bump_fee
-impl<'a, D> TxBuilder<'a, D, DefaultCoinSelectionAlgorithm, BumpFee> {
+impl<'a> TxBuilder<'a, DefaultCoinSelectionAlgorithm, BumpFee> {
/// Explicitly tells the wallet that it is allowed to reduce the amount of the output matching this
/// `script_pubkey` in order to bump the transaction fee. Without specifying this the wallet
/// will attempt to find a change output to shrink instead.