jitash_bdk/wallet/
mod.rs

1// Bitcoin Dev Kit
2// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
3//
4// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
5//
6// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
7// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
9// You may not use this file except in accordance with one or both of these
10// licenses.
11
12//! Wallet
13//!
14//! This module defines the [`Wallet`] structure.
15
16use std::cell::RefCell;
17use std::collections::HashMap;
18use std::collections::{BTreeMap, HashSet};
19use std::fmt;
20use std::ops::Deref;
21use std::str::FromStr;
22use std::sync::Arc;
23
24use bitcoin::secp256k1::Secp256k1;
25
26use bitcoin::consensus::encode::serialize;
27use bitcoin::util::psbt;
28use bitcoin::{
29    Address, EcdsaSighashType, LockTime, Network, OutPoint, SchnorrSighashType, Script, Sequence,
30    Transaction, TxOut, Txid, Witness,
31};
32
33use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
34
35#[allow(unused_imports)]
36use log::{debug, error, info, trace};
37
38pub mod coin_selection;
39pub mod export;
40pub mod signer;
41pub mod time;
42pub mod tx_builder;
43pub(crate) mod utils;
44#[cfg(feature = "verify")]
45#[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
46pub mod verify;
47
48#[cfg(feature = "hardware-signer")]
49#[cfg_attr(docsrs, doc(cfg(feature = "hardware-signer")))]
50pub mod hardwaresigner;
51
52pub use utils::IsDust;
53
54use coin_selection::DefaultCoinSelectionAlgorithm;
55use signer::{SignOptions, SignerOrdering, SignersContainer, TransactionSigner};
56use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxParams};
57use utils::{check_nsequence_rbf, After, Older, SecpCtx};
58
59use crate::blockchain::{GetHeight, NoopProgress, Progress, WalletSync};
60use crate::database::memory::MemoryDatabase;
61use crate::database::{AnyDatabase, BatchDatabase, BatchOperations, DatabaseUtils, SyncTime};
62use crate::descriptor::checksum::calc_checksum_bytes_internal;
63use crate::descriptor::policy::BuildSatisfaction;
64use crate::descriptor::{
65    calc_checksum, into_wallet_descriptor_checked, DerivedDescriptor, DescriptorMeta,
66    ExtendedDescriptor, ExtractPolicy, IntoWalletDescriptor, Policy, XKeyUtils,
67};
68use crate::error::{Error, MiniscriptPsbtError};
69use crate::psbt::PsbtUtils;
70use crate::signer::SignerError;
71use crate::testutils;
72use crate::types::*;
73use crate::wallet::coin_selection::Excess::{Change, NoChange};
74
75const CACHE_ADDR_BATCH_SIZE: u32 = 100;
76const COINBASE_MATURITY: u32 = 100;
77
78/// A Bitcoin wallet
79///
80/// The `Wallet` struct acts as a way of coherently interfacing with output descriptors and related transactions.
81/// Its main components are:
82///
83/// 1. output *descriptors* from which it can derive addresses.
84/// 2. A [`Database`] where it tracks transactions and utxos related to the descriptors.
85/// 3. [`signer`]s that can contribute signatures to addresses instantiated from the descriptors.
86///
87/// [`Database`]: crate::database::Database
88/// [`signer`]: crate::signer
89#[derive(Debug)]
90pub struct Wallet<D> {
91    descriptor: ExtendedDescriptor,
92    change_descriptor: Option<ExtendedDescriptor>,
93
94    signers: Arc<SignersContainer>,
95    change_signers: Arc<SignersContainer>,
96
97    network: Network,
98
99    database: RefCell<D>,
100
101    secp: SecpCtx,
102}
103
104/// The address index selection strategy to use to derived an address from the wallet's external
105/// descriptor. See [`Wallet::get_address`]. If you're unsure which one to use use `WalletIndex::New`.
106#[derive(Debug)]
107pub enum AddressIndex {
108    /// Return a new address after incrementing the current descriptor index.
109    New,
110    /// Return the address for the current descriptor index if it has not been used in a received
111    /// transaction. Otherwise return a new address as with [`AddressIndex::New`].
112    ///
113    /// Use with caution, if the wallet has not yet detected an address has been used it could
114    /// return an already used address. This function is primarily meant for situations where the
115    /// caller is untrusted; for example when deriving donation addresses on-demand for a public
116    /// web page.
117    LastUnused,
118    /// Return the address for a specific descriptor index. Does not change the current descriptor
119    /// index used by `AddressIndex::New` and `AddressIndex::LastUsed`.
120    ///
121    /// Use with caution, if an index is given that is less than the current descriptor index
122    /// then the returned address may have already been used.
123    Peek(u32),
124    /// Return the address for a specific descriptor index and reset the current descriptor index
125    /// used by `AddressIndex::New` and `AddressIndex::LastUsed` to this value.
126    ///
127    /// Use with caution, if an index is given that is less than the current descriptor index
128    /// then the returned address and subsequent addresses returned by calls to `AddressIndex::New`
129    /// and `AddressIndex::LastUsed` may have already been used. Also if the index is reset to a
130    /// value earlier than the [`crate::blockchain::Blockchain`] stop_gap (default is 20) then a
131    /// larger stop_gap should be used to monitor for all possibly used addresses.
132    Reset(u32),
133}
134
135/// A derived address and the index it was found at.
136/// For convenience this automatically derefs to `Address`
137#[derive(Debug, PartialEq, Eq)]
138pub struct AddressInfo {
139    /// Child index of this address
140    pub index: u32,
141    /// Address
142    pub address: Address,
143    /// Type of keychain
144    pub keychain: KeychainKind,
145}
146
147impl Deref for AddressInfo {
148    type Target = Address;
149
150    fn deref(&self) -> &Self::Target {
151        &self.address
152    }
153}
154
155impl fmt::Display for AddressInfo {
156    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157        write!(f, "{}", self.address)
158    }
159}
160
161#[derive(Debug, Default)]
162/// Options to a [`sync`].
163///
164/// [`sync`]: Wallet::sync
165pub struct SyncOptions {
166    /// The progress tracker which may be informed when progress is made.
167    pub progress: Option<Box<dyn Progress>>,
168}
169
170impl<D> Wallet<D>
171where
172    D: BatchDatabase,
173{
174    #[deprecated = "Just use Wallet::new -- all wallets are offline now!"]
175    /// Create a new "offline" wallet
176    pub fn new_offline<E: IntoWalletDescriptor>(
177        descriptor: E,
178        change_descriptor: Option<E>,
179        network: Network,
180        database: D,
181    ) -> Result<Self, Error> {
182        Self::new(descriptor, change_descriptor, network, database)
183    }
184
185    /// Create a wallet.
186    ///
187    /// The only way this can fail is if the descriptors passed in do not match the checksums in `database`.
188    pub fn new<E: IntoWalletDescriptor>(
189        descriptor: E,
190        change_descriptor: Option<E>,
191        network: Network,
192        mut database: D,
193    ) -> Result<Self, Error> {
194        let secp = Secp256k1::new();
195
196        let (descriptor, keymap) = into_wallet_descriptor_checked(descriptor, &secp, network)?;
197        Self::db_checksum(
198            &mut database,
199            &descriptor.to_string(),
200            KeychainKind::External,
201        )?;
202        let signers = Arc::new(SignersContainer::build(keymap, &descriptor, &secp));
203        let (change_descriptor, change_signers) = match change_descriptor {
204            Some(desc) => {
205                let (change_descriptor, change_keymap) =
206                    into_wallet_descriptor_checked(desc, &secp, network)?;
207                Self::db_checksum(
208                    &mut database,
209                    &change_descriptor.to_string(),
210                    KeychainKind::Internal,
211                )?;
212
213                let change_signers = Arc::new(SignersContainer::build(
214                    change_keymap,
215                    &change_descriptor,
216                    &secp,
217                ));
218
219                (Some(change_descriptor), change_signers)
220            }
221            None => (None, Arc::new(SignersContainer::new())),
222        };
223
224        Ok(Wallet {
225            descriptor,
226            change_descriptor,
227            signers,
228            change_signers,
229            network,
230            database: RefCell::new(database),
231            secp,
232        })
233    }
234
235    /// This checks the checksum within [`BatchDatabase`] twice (if needed). The first time with the
236    /// actual checksum, and the second time with the checksum of `descriptor+checksum`. The second
237    /// check is necessary for backwards compatibility of a checksum-inception bug.
238    fn db_checksum(db: &mut D, desc: &str, kind: KeychainKind) -> Result<(), Error> {
239        let checksum = calc_checksum_bytes_internal(desc, true)?;
240        if db.check_descriptor_checksum(kind, checksum).is_ok() {
241            return Ok(());
242        }
243
244        let checksum_inception = calc_checksum_bytes_internal(desc, false)?;
245        db.check_descriptor_checksum(kind, checksum_inception)
246    }
247
248    /// Get the Bitcoin network the wallet is using.
249    pub fn network(&self) -> Network {
250        self.network
251    }
252
253    // Return a newly derived address for the specified `keychain`.
254    fn get_new_address(&self, keychain: KeychainKind) -> Result<AddressInfo, Error> {
255        let incremented_index = self.fetch_and_increment_index(keychain)?;
256
257        let address_result = self
258            .get_descriptor_for_keychain(keychain)
259            .at_derivation_index(incremented_index)
260            .address(self.network);
261
262        address_result
263            .map(|address| AddressInfo {
264                address,
265                index: incremented_index,
266                keychain,
267            })
268            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
269    }
270
271    // Return the the last previously derived address for `keychain` if it has not been used in a
272    // received transaction. Otherwise return a new address using [`Wallet::get_new_address`].
273    fn get_unused_address(&self, keychain: KeychainKind) -> Result<AddressInfo, Error> {
274        let current_index = self.fetch_index(keychain)?;
275
276        let derived_key = self
277            .get_descriptor_for_keychain(keychain)
278            .at_derivation_index(current_index);
279
280        let script_pubkey = derived_key.script_pubkey();
281
282        let found_used = self
283            .list_transactions(true)?
284            .iter()
285            .flat_map(|tx_details| tx_details.transaction.as_ref())
286            .flat_map(|tx| tx.output.iter())
287            .any(|o| o.script_pubkey == script_pubkey);
288
289        if found_used {
290            self.get_new_address(keychain)
291        } else {
292            derived_key
293                .address(self.network)
294                .map(|address| AddressInfo {
295                    address,
296                    index: current_index,
297                    keychain,
298                })
299                .map_err(|_| Error::ScriptDoesntHaveAddressForm)
300        }
301    }
302
303    // Return derived address for the descriptor of given [`KeychainKind`] at a specific index
304    fn peek_address(&self, index: u32, keychain: KeychainKind) -> Result<AddressInfo, Error> {
305        self.get_descriptor_for_keychain(keychain)
306            .at_derivation_index(index)
307            .address(self.network)
308            .map(|address| AddressInfo {
309                index,
310                address,
311                keychain,
312            })
313            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
314    }
315
316    // Return derived address for `keychain` at a specific index and reset current
317    // address index
318    fn reset_address(&self, index: u32, keychain: KeychainKind) -> Result<AddressInfo, Error> {
319        self.set_index(keychain, index)?;
320
321        self.get_descriptor_for_keychain(keychain)
322            .at_derivation_index(index)
323            .address(self.network)
324            .map(|address| AddressInfo {
325                index,
326                address,
327                keychain,
328            })
329            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
330    }
331
332    /// Return a derived address using the external descriptor, see [`AddressIndex`] for
333    /// available address index selection strategies. If none of the keys in the descriptor are derivable
334    /// (i.e. does not end with /*) then the same address will always be returned for any [`AddressIndex`].
335    pub fn get_address(&self, address_index: AddressIndex) -> Result<AddressInfo, Error> {
336        self._get_address(address_index, KeychainKind::External)
337    }
338
339    /// Return a derived address using the internal (change) descriptor.
340    ///
341    /// If the wallet doesn't have an internal descriptor it will use the external descriptor.
342    ///
343    /// see [`AddressIndex`] for available address index selection strategies. If none of the keys
344    /// in the descriptor are derivable (i.e. does not end with /*) then the same address will always
345    /// be returned for any [`AddressIndex`].
346    pub fn get_internal_address(&self, address_index: AddressIndex) -> Result<AddressInfo, Error> {
347        self._get_address(address_index, KeychainKind::Internal)
348    }
349
350    fn _get_address(
351        &self,
352        address_index: AddressIndex,
353        keychain: KeychainKind,
354    ) -> Result<AddressInfo, Error> {
355        match address_index {
356            AddressIndex::New => self.get_new_address(keychain),
357            AddressIndex::LastUnused => self.get_unused_address(keychain),
358            AddressIndex::Peek(index) => self.peek_address(index, keychain),
359            AddressIndex::Reset(index) => self.reset_address(index, keychain),
360        }
361    }
362
363    /// Ensures that there are at least `max_addresses` addresses cached in the database if the
364    /// descriptor is derivable, or 1 address if it is not.
365    /// Will return `Ok(true)` if there are new addresses generated (either external or internal),
366    /// and `Ok(false)` if all the required addresses are already cached. This function is useful to
367    /// explicitly cache addresses in a wallet to do things like check [`Wallet::is_mine`] on
368    /// transaction output scripts.
369    pub fn ensure_addresses_cached(&self, max_addresses: u32) -> Result<bool, Error> {
370        let mut new_addresses_cached = false;
371        let max_address = match self.descriptor.has_wildcard() {
372            false => 0,
373            true => max_addresses,
374        };
375        debug!("max_address {}", max_address);
376        if self
377            .database
378            .borrow()
379            .get_script_pubkey_from_path(KeychainKind::External, max_address.saturating_sub(1))?
380            .is_none()
381        {
382            debug!("caching external addresses");
383            new_addresses_cached = true;
384            self.cache_addresses(KeychainKind::External, 0, max_address)?;
385        }
386
387        if let Some(change_descriptor) = &self.change_descriptor {
388            let max_address = match change_descriptor.has_wildcard() {
389                false => 0,
390                true => max_addresses,
391            };
392
393            if self
394                .database
395                .borrow()
396                .get_script_pubkey_from_path(KeychainKind::Internal, max_address.saturating_sub(1))?
397                .is_none()
398            {
399                debug!("caching internal addresses");
400                new_addresses_cached = true;
401                self.cache_addresses(KeychainKind::Internal, 0, max_address)?;
402            }
403        }
404        Ok(new_addresses_cached)
405    }
406
407    /// Return whether or not a `script` is part of this wallet (either internal or external)
408    pub fn is_mine(&self, script: &Script) -> Result<bool, Error> {
409        self.database.borrow().is_mine(script)
410    }
411
412    /// Return the list of unspent outputs of this wallet
413    ///
414    /// Note that this method only operates on the internal database, which first needs to be
415    /// [`Wallet::sync`] manually.
416    pub fn list_unspent(&self) -> Result<Vec<LocalUtxo>, Error> {
417        Ok(self
418            .database
419            .borrow()
420            .iter_utxos()?
421            .into_iter()
422            .filter(|l| !l.is_spent)
423            .collect())
424    }
425
426    /// Returns the `UTXO` owned by this wallet corresponding to `outpoint` if it exists in the
427    /// wallet's database.
428    pub fn get_utxo(&self, outpoint: OutPoint) -> Result<Option<LocalUtxo>, Error> {
429        self.database.borrow().get_utxo(&outpoint)
430    }
431
432    /// Return a single transactions made and received by the wallet
433    ///
434    /// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
435    /// `include_raw` is `true`.
436    ///
437    /// Note that this method only operates on the internal database, which first needs to be
438    /// [`Wallet::sync`] manually.
439    pub fn get_tx(
440        &self,
441        txid: &Txid,
442        include_raw: bool,
443    ) -> Result<Option<TransactionDetails>, Error> {
444        self.database.borrow().get_tx(txid, include_raw)
445    }
446
447    /// Return an unsorted list of transactions made and received by the wallet
448    ///
449    /// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
450    /// `include_raw` is `true`.
451    ///
452    /// To sort transactions, the following code can be used:
453    /// ```no_run
454    /// # let mut tx_list: Vec<jitash_bdk::TransactionDetails> = vec![];
455    /// tx_list.sort_by(|a, b| {
456    ///     b.confirmation_time
457    ///         .as_ref()
458    ///         .map(|t| t.height)
459    ///         .cmp(&a.confirmation_time.as_ref().map(|t| t.height))
460    /// });
461    /// ```
462    ///
463    /// Note that this method only operates on the internal database, which first needs to be
464    /// [`Wallet::sync`] manually.
465    pub fn list_transactions(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
466        self.database.borrow().iter_txs(include_raw)
467    }
468
469    /// Return the balance, separated into available, trusted-pending, untrusted-pending and immature
470    /// values.
471    ///
472    /// Note that this method only operates on the internal database, which first needs to be
473    /// [`Wallet::sync`] manually.
474    pub fn get_balance(&self) -> Result<Balance, Error> {
475        let mut immature = 0;
476        let mut trusted_pending = 0;
477        let mut untrusted_pending = 0;
478        let mut confirmed = 0;
479        let utxos = self.list_unspent()?;
480        let database = self.database.borrow();
481        let last_sync_height = match database
482            .get_sync_time()?
483            .map(|sync_time| sync_time.block_time.height)
484        {
485            Some(height) => height,
486            // None means database was never synced
487            None => return Ok(Balance::default()),
488        };
489        for u in utxos {
490            // Unwrap used since utxo set is created from database
491            let tx = database
492                .get_tx(&u.outpoint.txid, true)?
493                .expect("Transaction not found in database");
494            if let Some(tx_conf_time) = &tx.confirmation_time {
495                if tx.transaction.expect("No transaction").is_coin_base()
496                    && (last_sync_height - tx_conf_time.height) < COINBASE_MATURITY
497                {
498                    immature += u.txout.value;
499                } else {
500                    confirmed += u.txout.value;
501                }
502            } else if u.keychain == KeychainKind::Internal {
503                trusted_pending += u.txout.value;
504            } else {
505                untrusted_pending += u.txout.value;
506            }
507        }
508
509        Ok(Balance {
510            immature,
511            trusted_pending,
512            untrusted_pending,
513            confirmed,
514        })
515    }
516
517    /// Add an external signer
518    ///
519    /// See [the `signer` module](signer) for an example.
520    pub fn add_signer(
521        &mut self,
522        keychain: KeychainKind,
523        ordering: SignerOrdering,
524        signer: Arc<dyn TransactionSigner>,
525    ) {
526        let signers = match keychain {
527            KeychainKind::External => Arc::make_mut(&mut self.signers),
528            KeychainKind::Internal => Arc::make_mut(&mut self.change_signers),
529        };
530
531        signers.add_external(signer.id(&self.secp), ordering, signer);
532    }
533
534    /// Get the signers
535    ///
536    /// ## Example
537    ///
538    /// ```
539    /// # use jitash_bdk::{Wallet, KeychainKind};
540    /// # use jitash_bdk::bitcoin::Network;
541    /// # use jitash_bdk::database::MemoryDatabase;
542    /// let wallet = Wallet::new("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet, MemoryDatabase::new())?;
543    /// for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
544    ///     // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
545    ///     println!("secret_key: {}", secret_key);
546    /// }
547    ///
548    /// Ok::<(), Box<dyn std::error::Error>>(())
549    /// ```
550    pub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer> {
551        match keychain {
552            KeychainKind::External => Arc::clone(&self.signers),
553            KeychainKind::Internal => Arc::clone(&self.change_signers),
554        }
555    }
556
557    /// Start building a transaction.
558    ///
559    /// This returns a blank [`TxBuilder`] from which you can specify the parameters for the transaction.
560    ///
561    /// ## Example
562    ///
563    /// ```
564    /// # use std::str::FromStr;
565    /// # use bitcoin::*;
566    /// # use jitash_bdk::*;
567    /// # use jitash_bdk::database::*;
568    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
569    /// # let wallet = doctest_wallet!();
570    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
571    /// let (psbt, details) = {
572    ///    let mut builder =  wallet.build_tx();
573    ///    builder
574    ///        .add_recipient(to_address.script_pubkey(), 50_000);
575    ///    builder.finish()?
576    /// };
577    ///
578    /// // sign and broadcast ...
579    /// # Ok::<(), jitash_bdk::Error>(())
580    /// ```
581    ///
582    /// [`TxBuilder`]: crate::TxBuilder
583    pub fn build_tx(&self) -> TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, CreateTx> {
584        TxBuilder {
585            wallet: self,
586            params: TxParams::default(),
587            coin_selection: DefaultCoinSelectionAlgorithm::default(),
588            phantom: core::marker::PhantomData,
589        }
590    }
591
592    pub(crate) fn create_tx<Cs: coin_selection::CoinSelectionAlgorithm<D>>(
593        &self,
594        coin_selection: Cs,
595        params: TxParams,
596    ) -> Result<(psbt::PartiallySignedTransaction, TransactionDetails), Error> {
597        let external_policy = self
598            .descriptor
599            .extract_policy(&self.signers, BuildSatisfaction::None, &self.secp)?
600            .unwrap();
601        let internal_policy = self
602            .change_descriptor
603            .as_ref()
604            .map(|desc| {
605                Ok::<_, Error>(
606                    desc.extract_policy(&self.change_signers, BuildSatisfaction::None, &self.secp)?
607                        .unwrap(),
608                )
609            })
610            .transpose()?;
611
612        // The policy allows spending external outputs, but it requires a policy path that hasn't been
613        // provided
614        if params.change_policy != tx_builder::ChangeSpendPolicy::OnlyChange
615            && external_policy.requires_path()
616            && params.external_policy_path.is_none()
617        {
618            return Err(Error::SpendingPolicyRequired(KeychainKind::External));
619        };
620        // Same for the internal_policy path, if present
621        if let Some(internal_policy) = &internal_policy {
622            if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeForbidden
623                && internal_policy.requires_path()
624                && params.internal_policy_path.is_none()
625            {
626                return Err(Error::SpendingPolicyRequired(KeychainKind::Internal));
627            };
628        }
629
630        let external_requirements = external_policy.get_condition(
631            params
632                .external_policy_path
633                .as_ref()
634                .unwrap_or(&BTreeMap::new()),
635        )?;
636        let internal_requirements = internal_policy
637            .map(|policy| {
638                Ok::<_, Error>(
639                    policy.get_condition(
640                        params
641                            .internal_policy_path
642                            .as_ref()
643                            .unwrap_or(&BTreeMap::new()),
644                    )?,
645                )
646            })
647            .transpose()?;
648
649        let requirements =
650            external_requirements.merge(&internal_requirements.unwrap_or_default())?;
651        debug!("Policy requirements: {:?}", requirements);
652
653        let version = match params.version {
654            Some(tx_builder::Version(0)) => {
655                return Err(Error::Generic("Invalid version `0`".into()))
656            }
657            Some(tx_builder::Version(1)) if requirements.csv.is_some() => {
658                return Err(Error::Generic(
659                    "TxBuilder requested version `1`, but at least `2` is needed to use OP_CSV"
660                        .into(),
661                ))
662            }
663            Some(tx_builder::Version(x)) => x,
664            None if requirements.csv.is_some() => 2,
665            _ => 1,
666        };
667
668        // We use a match here instead of a map_or_else as it's way more readable :)
669        let current_height = match params.current_height {
670            // If they didn't tell us the current height, we assume it's the latest sync height.
671            None => self.database().get_sync_time()?.map(|sync_time| {
672                LockTime::from_height(sync_time.block_time.height).expect("Invalid height")
673            }),
674            h => h,
675        };
676
677        let lock_time = match params.locktime {
678            // When no nLockTime is specified, we try to prevent fee sniping, if possible
679            None => {
680                // Fee sniping can be partially prevented by setting the timelock
681                // to current_height. If we don't know the current_height,
682                // we default to 0.
683                let fee_sniping_height = current_height.unwrap_or(LockTime::ZERO);
684
685                // We choose the biggest between the required nlocktime and the fee sniping
686                // height
687                match requirements.timelock {
688                    // No requirement, just use the fee_sniping_height
689                    None => fee_sniping_height,
690                    // There's a block-based requirement, but the value is lower than the fee_sniping_height
691                    Some(value @ LockTime::Blocks(_)) if value < fee_sniping_height => fee_sniping_height,
692                    // There's a time-based requirement or a block-based requirement greater
693                    // than the fee_sniping_height use that value
694                    Some(value) => value,
695                }
696            }
697            // Specific nLockTime required and we have no constraints, so just set to that value
698            Some(x) if requirements.timelock.is_none() => x,
699            // Specific nLockTime required and it's compatible with the constraints
700            Some(x) if requirements.timelock.unwrap().is_same_unit(x) && x >= requirements.timelock.unwrap() => x,
701            // Invalid nLockTime required
702            Some(x) => return Err(Error::Generic(format!("TxBuilder requested timelock of `{:?}`, but at least `{:?}` is required to spend from this script", x, requirements.timelock.unwrap())))
703        };
704
705        let n_sequence = match (params.rbf, requirements.csv) {
706            // No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
707            (None, None) if lock_time != LockTime::ZERO => Sequence::ENABLE_LOCKTIME_NO_RBF,
708            // No RBF, CSV or nLockTime, make the transaction final
709            (None, None) => Sequence::MAX,
710
711            // No RBF requested, use the value from CSV. Note that this value is by definition
712            // non-final, so even if a timelock is enabled this nSequence is fine, hence why we
713            // don't bother checking for it here. The same is true for all the other branches below
714            (None, Some(csv)) => csv,
715
716            // RBF with a specific value but that value is too high
717            (Some(tx_builder::RbfValue::Value(rbf)), _) if !rbf.is_rbf() => {
718                return Err(Error::Generic(
719                    "Cannot enable RBF with a nSequence >= 0xFFFFFFFE".into(),
720                ))
721            }
722            // RBF with a specific value requested, but the value is incompatible with CSV
723            (Some(tx_builder::RbfValue::Value(rbf)), Some(csv))
724                if !check_nsequence_rbf(rbf, csv) =>
725            {
726                return Err(Error::Generic(format!(
727                    "Cannot enable RBF with nSequence `{:?}` given a required OP_CSV of `{:?}`",
728                    rbf, csv
729                )))
730            }
731
732            // RBF enabled with the default value with CSV also enabled. CSV takes precedence
733            (Some(tx_builder::RbfValue::Default), Some(csv)) => csv,
734            // Valid RBF, either default or with a specific value. We ignore the `CSV` value
735            // because we've already checked it before
736            (Some(rbf), _) => rbf.get_value(),
737        };
738
739        let (fee_rate, mut fee_amount) = match params
740            .fee_policy
741            .as_ref()
742            .unwrap_or(&FeePolicy::FeeRate(FeeRate::default()))
743        {
744            //FIXME: see https://github.com/bitcoindevkit/bdk/issues/256
745            FeePolicy::FeeAmount(fee) => {
746                if let Some(previous_fee) = params.bumping_fee {
747                    if *fee < previous_fee.absolute {
748                        return Err(Error::FeeTooLow {
749                            required: previous_fee.absolute,
750                        });
751                    }
752                }
753                (FeeRate::from_sat_per_vb(0.0), *fee)
754            }
755            FeePolicy::FeeRate(rate) => {
756                if let Some(previous_fee) = params.bumping_fee {
757                    let required_feerate = FeeRate::from_sat_per_vb(previous_fee.rate + 1.0);
758                    if *rate < required_feerate {
759                        return Err(Error::FeeRateTooLow {
760                            required: required_feerate,
761                        });
762                    }
763                }
764                (*rate, 0)
765            }
766        };
767
768        let mut tx = Transaction {
769            version,
770            lock_time: lock_time.into(),
771            input: vec![],
772            output: vec![],
773        };
774
775        if params.manually_selected_only && params.utxos.is_empty() {
776            return Err(Error::NoUtxosSelected);
777        }
778
779        // we keep it as a float while we accumulate it, and only round it at the end
780        let mut outgoing: u64 = 0;
781        let mut received: u64 = 0;
782
783        let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
784
785        for (index, (script_pubkey, value)) in recipients.enumerate() {
786            if !params.allow_dust
787                && value.is_dust(script_pubkey)
788                && !script_pubkey.is_provably_unspendable()
789            {
790                return Err(Error::OutputBelowDustLimit(index));
791            }
792
793            if self.is_mine(script_pubkey)? {
794                received += value;
795            }
796
797            let new_out = TxOut {
798                script_pubkey: script_pubkey.clone(),
799                value,
800            };
801
802            tx.output.push(new_out);
803
804            outgoing += value;
805        }
806
807        fee_amount += fee_rate.fee_wu(tx.weight());
808
809        // Segwit transactions' header is 2WU larger than legacy txs' header,
810        // as they contain a witness marker (1WU) and a witness flag (1WU) (see BIP144).
811        // At this point we really don't know if the resulting transaction will be segwit
812        // or legacy, so we just add this 2WU to the fee_amount - overshooting the fee amount
813        // is better than undershooting it.
814        // If we pass a fee_amount that is slightly higher than the final fee_amount, we
815        // end up with a transaction with a slightly higher fee rate than the requested one.
816        // If, instead, we undershoot, we may end up with a feerate lower than the requested one
817        // - we might come up with non broadcastable txs!
818        fee_amount += fee_rate.fee_wu(2);
819
820        if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeAllowed
821            && self.change_descriptor.is_none()
822        {
823            return Err(Error::Generic(
824                "The `change_policy` can be set only if the wallet has a change_descriptor".into(),
825            ));
826        }
827
828        let (required_utxos, optional_utxos) = self.preselect_utxos(
829            params.change_policy,
830            &params.unspendable,
831            params.utxos.clone(),
832            params.drain_wallet,
833            params.manually_selected_only,
834            params.bumping_fee.is_some(), // we mandate confirmed transactions if we're bumping the fee
835            current_height.map(LockTime::to_consensus_u32),
836        )?;
837
838        // get drain script
839        let drain_script = match params.drain_to {
840            Some(ref drain_recipient) => drain_recipient.clone(),
841            None => self
842                .get_internal_address(AddressIndex::New)?
843                .address
844                .script_pubkey(),
845        };
846
847        let coin_selection = coin_selection.coin_select(
848            self.database.borrow().deref(),
849            required_utxos,
850            optional_utxos,
851            fee_rate,
852            outgoing + fee_amount,
853            &drain_script,
854        )?;
855        fee_amount += coin_selection.fee_amount;
856        let excess = &coin_selection.excess;
857
858        tx.input = coin_selection
859            .selected
860            .iter()
861            .map(|u| bitcoin::TxIn {
862                previous_output: u.outpoint(),
863                script_sig: Script::default(),
864                sequence: n_sequence,
865                witness: Witness::new(),
866            })
867            .collect();
868
869        if tx.output.is_empty() {
870            // Uh oh, our transaction has no outputs.
871            // We allow this when:
872            // - We have a drain_to address and the utxos we must spend (this happens,
873            // for example, when we RBF)
874            // - We have a drain_to address and drain_wallet set
875            // Otherwise, we don't know who we should send the funds to, and how much
876            // we should send!
877            if params.drain_to.is_some() && (params.drain_wallet || !params.utxos.is_empty()) {
878                if let NoChange {
879                    dust_threshold,
880                    remaining_amount,
881                    change_fee,
882                } = excess
883                {
884                    return Err(Error::InsufficientFunds {
885                        needed: *dust_threshold,
886                        available: remaining_amount.saturating_sub(*change_fee),
887                    });
888                }
889            } else {
890                return Err(Error::NoRecipients);
891            }
892        }
893
894        match excess {
895            NoChange {
896                remaining_amount, ..
897            } => fee_amount += remaining_amount,
898            Change { amount, fee } => {
899                if self.is_mine(&drain_script)? {
900                    received += amount;
901                }
902                fee_amount += fee;
903
904                // create drain output
905                let drain_output = TxOut {
906                    value: *amount,
907                    script_pubkey: drain_script,
908                };
909
910                // TODO: We should pay attention when adding a new output: this might increase
911                // the lenght of the "number of vouts" parameter by 2 bytes, potentially making
912                // our feerate too low
913                tx.output.push(drain_output);
914            }
915        };
916
917        // sort input/outputs according to the chosen algorithm
918        params.ordering.sort_tx(&mut tx);
919
920        let txid = tx.txid();
921        let sent = coin_selection.local_selected_amount();
922        let psbt = self.complete_transaction(tx, coin_selection.selected, params)?;
923
924        let transaction_details = TransactionDetails {
925            transaction: None,
926            txid,
927            confirmation_time: None,
928            received,
929            sent,
930            fee: Some(fee_amount),
931        };
932
933        Ok((psbt, transaction_details))
934    }
935
936    /// Bump the fee of a transaction previously created with this wallet.
937    ///
938    /// Returns an error if the transaction is already confirmed or doesn't explicitly signal
939    /// *replace by fee* (RBF). If the transaction can be fee bumped then it returns a [`TxBuilder`]
940    /// pre-populated with the inputs and outputs of the original transaction.
941    ///
942    /// ## Example
943    ///
944    /// ```no_run
945    /// # // TODO: remove norun -- bumping fee seems to need the tx in the wallet database first.
946    /// # use std::str::FromStr;
947    /// # use bitcoin::*;
948    /// # use jitash_bdk::*;
949    /// # use jitash_bdk::database::*;
950    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
951    /// # let wallet = doctest_wallet!();
952    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
953    /// let (mut psbt, _) = {
954    ///     let mut builder = wallet.build_tx();
955    ///     builder
956    ///         .add_recipient(to_address.script_pubkey(), 50_000)
957    ///         .enable_rbf();
958    ///     builder.finish()?
959    /// };
960    /// let _ = wallet.sign(&mut psbt, SignOptions::default())?;
961    /// let tx = psbt.extract_tx();
962    /// // broadcast tx but it's taking too long to confirm so we want to bump the fee
963    /// let (mut psbt, _) =  {
964    ///     let mut builder = wallet.build_fee_bump(tx.txid())?;
965    ///     builder
966    ///         .fee_rate(FeeRate::from_sat_per_vb(5.0));
967    ///     builder.finish()?
968    /// };
969    ///
970    /// let _ = wallet.sign(&mut psbt, SignOptions::default())?;
971    /// let fee_bumped_tx = psbt.extract_tx();
972    /// // broadcast fee_bumped_tx to replace original
973    /// # Ok::<(), jitash_bdk::Error>(())
974    /// ```
975    // TODO: support for merging multiple transactions while bumping the fees
976    pub fn build_fee_bump(
977        &self,
978        txid: Txid,
979    ) -> Result<TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, BumpFee>, Error> {
980        let mut details = match self.database.borrow().get_tx(&txid, true)? {
981            None => return Err(Error::TransactionNotFound),
982            Some(tx) if tx.transaction.is_none() => return Err(Error::TransactionNotFound),
983            Some(tx) if tx.confirmation_time.is_some() => return Err(Error::TransactionConfirmed),
984            Some(tx) => tx,
985        };
986        let mut tx = details.transaction.take().unwrap();
987        if !tx
988            .input
989            .iter()
990            .any(|txin| txin.sequence.to_consensus_u32() <= 0xFFFFFFFD)
991        {
992            return Err(Error::IrreplaceableTransaction);
993        }
994
995        let feerate = FeeRate::from_wu(details.fee.ok_or(Error::FeeRateUnavailable)?, tx.weight());
996
997        // remove the inputs from the tx and process them
998        let original_txin = tx.input.drain(..).collect::<Vec<_>>();
999        let original_utxos = original_txin
1000            .iter()
1001            .map(|txin| -> Result<_, Error> {
1002                let txout = self
1003                    .database
1004                    .borrow()
1005                    .get_previous_output(&txin.previous_output)?
1006                    .ok_or(Error::UnknownUtxo)?;
1007
1008                let (weight, keychain) = match self
1009                    .database
1010                    .borrow()
1011                    .get_path_from_script_pubkey(&txout.script_pubkey)?
1012                {
1013                    Some((keychain, _)) => (
1014                        self._get_descriptor_for_keychain(keychain)
1015                            .0
1016                            .max_satisfaction_weight()
1017                            .unwrap(),
1018                        keychain,
1019                    ),
1020                    None => {
1021                        // estimate the weight based on the scriptsig/witness size present in the
1022                        // original transaction
1023                        let weight =
1024                            serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len();
1025                        (weight, KeychainKind::External)
1026                    }
1027                };
1028
1029                let utxo = LocalUtxo {
1030                    outpoint: txin.previous_output,
1031                    txout,
1032                    keychain,
1033                    is_spent: true,
1034                };
1035
1036                Ok(WeightedUtxo {
1037                    satisfaction_weight: weight,
1038                    utxo: Utxo::Local(utxo),
1039                })
1040            })
1041            .collect::<Result<Vec<_>, _>>()?;
1042
1043        if tx.output.len() > 1 {
1044            let mut change_index = None;
1045            for (index, txout) in tx.output.iter().enumerate() {
1046                let (_, change_type) = self._get_descriptor_for_keychain(KeychainKind::Internal);
1047                match self
1048                    .database
1049                    .borrow()
1050                    .get_path_from_script_pubkey(&txout.script_pubkey)?
1051                {
1052                    Some((keychain, _)) if keychain == change_type => change_index = Some(index),
1053                    _ => {}
1054                }
1055            }
1056
1057            if let Some(change_index) = change_index {
1058                tx.output.remove(change_index);
1059            }
1060        }
1061
1062        let params = TxParams {
1063            // TODO: figure out what rbf option should be?
1064            version: Some(tx_builder::Version(tx.version)),
1065            recipients: tx
1066                .output
1067                .into_iter()
1068                .map(|txout| (txout.script_pubkey, txout.value))
1069                .collect(),
1070            utxos: original_utxos,
1071            bumping_fee: Some(tx_builder::PreviousFee {
1072                absolute: details.fee.ok_or(Error::FeeRateUnavailable)?,
1073                rate: feerate.as_sat_per_vb(),
1074            }),
1075            ..Default::default()
1076        };
1077
1078        Ok(TxBuilder {
1079            wallet: self,
1080            params,
1081            coin_selection: DefaultCoinSelectionAlgorithm::default(),
1082            phantom: core::marker::PhantomData,
1083        })
1084    }
1085
1086    /// Sign a transaction with all the wallet's signers, in the order specified by every signer's
1087    /// [`SignerOrdering`]. This function returns the `Result` type with an encapsulated `bool` that has the value true if the PSBT was finalized, or false otherwise.
1088    ///
1089    /// The [`SignOptions`] can be used to tweak the behavior of the software signers, and the way
1090    /// the transaction is finalized at the end. Note that it can't be guaranteed that *every*
1091    /// signers will follow the options, but the "software signers" (WIF keys and `xprv`) defined
1092    /// in this library will.
1093    ///
1094    /// ## Example
1095    ///
1096    /// ```
1097    /// # use std::str::FromStr;
1098    /// # use bitcoin::*;
1099    /// # use jitash_bdk::*;
1100    /// # use jitash_bdk::database::*;
1101    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
1102    /// # let wallet = doctest_wallet!();
1103    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
1104    /// let (mut psbt, _) = {
1105    ///     let mut builder = wallet.build_tx();
1106    ///     builder.add_recipient(to_address.script_pubkey(), 50_000);
1107    ///     builder.finish()?
1108    /// };
1109    /// let  finalized = wallet.sign(&mut psbt, SignOptions::default())?;
1110    /// assert!(finalized, "we should have signed all the inputs");
1111    /// # Ok::<(), jitash_bdk::Error>(())
1112    pub fn sign(
1113        &self,
1114        psbt: &mut psbt::PartiallySignedTransaction,
1115        sign_options: SignOptions,
1116    ) -> Result<bool, Error> {
1117        // This adds all the PSBT metadata for the inputs, which will help us later figure out how
1118        // to derive our keys
1119        self.update_psbt_with_descriptor(psbt)?;
1120
1121        // If we aren't allowed to use `witness_utxo`, ensure that every input (except p2tr and finalized ones)
1122        // has the `non_witness_utxo`
1123        if !sign_options.trust_witness_utxo
1124            && psbt
1125                .inputs
1126                .iter()
1127                .filter(|i| i.final_script_witness.is_none() && i.final_script_sig.is_none())
1128                .filter(|i| i.tap_internal_key.is_none() && i.tap_merkle_root.is_none())
1129                .any(|i| i.non_witness_utxo.is_none())
1130        {
1131            return Err(Error::Signer(signer::SignerError::MissingNonWitnessUtxo));
1132        }
1133
1134        // If the user hasn't explicitly opted-in, refuse to sign the transaction unless every input
1135        // is using `SIGHASH_ALL` or `SIGHASH_DEFAULT` for taproot
1136        if !sign_options.allow_all_sighashes
1137            && !psbt.inputs.iter().all(|i| {
1138                i.sighash_type.is_none()
1139                    || i.sighash_type == Some(EcdsaSighashType::All.into())
1140                    || i.sighash_type == Some(SchnorrSighashType::All.into())
1141                    || i.sighash_type == Some(SchnorrSighashType::Default.into())
1142            })
1143        {
1144            return Err(Error::Signer(signer::SignerError::NonStandardSighash));
1145        }
1146
1147        for signer in self
1148            .signers
1149            .signers()
1150            .iter()
1151            .chain(self.change_signers.signers().iter())
1152        {
1153            signer.sign_transaction(psbt, &sign_options, &self.secp)?;
1154        }
1155
1156        // attempt to finalize
1157        if sign_options.try_finalize {
1158            self.finalize_psbt(psbt, sign_options)
1159        } else {
1160            Ok(false)
1161        }
1162    }
1163
1164    /// Return the spending policies for the wallet's descriptor
1165    pub fn policies(&self, keychain: KeychainKind) -> Result<Option<Policy>, Error> {
1166        match (keychain, self.change_descriptor.as_ref()) {
1167            (KeychainKind::External, _) => Ok(self.descriptor.extract_policy(
1168                &self.signers,
1169                BuildSatisfaction::None,
1170                &self.secp,
1171            )?),
1172            (KeychainKind::Internal, None) => Ok(None),
1173            (KeychainKind::Internal, Some(desc)) => Ok(desc.extract_policy(
1174                &self.change_signers,
1175                BuildSatisfaction::None,
1176                &self.secp,
1177            )?),
1178        }
1179    }
1180
1181    /// Return the "public" version of the wallet's descriptor, meaning a new descriptor that has
1182    /// the same structure but with every secret key removed
1183    ///
1184    /// This can be used to build a watch-only version of a wallet
1185    pub fn public_descriptor(
1186        &self,
1187        keychain: KeychainKind,
1188    ) -> Result<Option<ExtendedDescriptor>, Error> {
1189        match (keychain, self.change_descriptor.as_ref()) {
1190            (KeychainKind::External, _) => Ok(Some(self.descriptor.clone())),
1191            (KeychainKind::Internal, None) => Ok(None),
1192            (KeychainKind::Internal, Some(desc)) => Ok(Some(desc.clone())),
1193        }
1194    }
1195
1196    /// Finalize a PSBT, i.e., for each input determine if sufficient data is available to pass
1197    /// validation and construct the respective `scriptSig` or `scriptWitness`. Please refer to
1198    /// [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#Input_Finalizer)
1199    /// for further information.
1200    ///
1201    /// Returns `true` if the PSBT could be finalized, and `false` otherwise.
1202    ///
1203    /// The [`SignOptions`] can be used to tweak the behavior of the finalizer.
1204    pub fn finalize_psbt(
1205        &self,
1206        psbt: &mut psbt::PartiallySignedTransaction,
1207        sign_options: SignOptions,
1208    ) -> Result<bool, Error> {
1209        let tx = &psbt.unsigned_tx;
1210        let mut finished = true;
1211
1212        for (n, input) in tx.input.iter().enumerate() {
1213            let psbt_input = &psbt
1214                .inputs
1215                .get(n)
1216                .ok_or(Error::Signer(SignerError::InputIndexOutOfRange))?;
1217            if psbt_input.final_script_sig.is_some() || psbt_input.final_script_witness.is_some() {
1218                continue;
1219            }
1220            // if the height is None in the database it means it's still unconfirmed, so consider
1221            // that as a very high value
1222            let create_height = self
1223                .database
1224                .borrow()
1225                .get_tx(&input.previous_output.txid, false)?
1226                .map(|tx| tx.confirmation_time.map(|c| c.height).unwrap_or(u32::MAX));
1227            let last_sync_height = self
1228                .database()
1229                .get_sync_time()?
1230                .map(|sync_time| sync_time.block_time.height);
1231            let current_height = sign_options.assume_height.or(last_sync_height);
1232
1233            debug!(
1234                "Input #{} - {}, using `create_height` = {:?}, `current_height` = {:?}",
1235                n, input.previous_output, create_height, current_height
1236            );
1237
1238            // - Try to derive the descriptor by looking at the txout. If it's in our database, we
1239            //   know exactly which `keychain` to use, and which derivation index it is
1240            // - If that fails, try to derive it by looking at the psbt input: the complete logic
1241            //   is in `src/descriptor/mod.rs`, but it will basically look at `bip32_derivation`,
1242            //   `redeem_script` and `witness_script` to determine the right derivation
1243            // - If that also fails, it will try it on the internal descriptor, if present
1244            let desc = psbt
1245                .get_utxo_for(n)
1246                .map(|txout| self.get_descriptor_for_txout(&txout))
1247                .transpose()?
1248                .flatten()
1249                .or_else(|| {
1250                    self.descriptor.derive_from_psbt_input(
1251                        psbt_input,
1252                        psbt.get_utxo_for(n),
1253                        &self.secp,
1254                    )
1255                })
1256                .or_else(|| {
1257                    self.change_descriptor.as_ref().and_then(|desc| {
1258                        desc.derive_from_psbt_input(psbt_input, psbt.get_utxo_for(n), &self.secp)
1259                    })
1260                });
1261
1262            match desc {
1263                Some(desc) => {
1264                    let mut tmp_input = bitcoin::TxIn::default();
1265                    match desc.satisfy(
1266                        &mut tmp_input,
1267                        (
1268                            PsbtInputSatisfier::new(psbt, n),
1269                            After::new(current_height, false),
1270                            Older::new(current_height, create_height, false),
1271                        ),
1272                    ) {
1273                        Ok(_) => {
1274                            let psbt_input = &mut psbt.inputs[n];
1275                            psbt_input.final_script_sig = Some(tmp_input.script_sig);
1276                            psbt_input.final_script_witness = Some(tmp_input.witness);
1277                            if sign_options.remove_partial_sigs {
1278                                psbt_input.partial_sigs.clear();
1279                            }
1280                        }
1281                        Err(e) => {
1282                            debug!("satisfy error {:?} for input {}", e, n);
1283                            finished = false
1284                        }
1285                    }
1286                }
1287                None => finished = false,
1288            }
1289        }
1290
1291        Ok(finished)
1292    }
1293
1294    /// Return the secp256k1 context used for all signing operations
1295    pub fn secp_ctx(&self) -> &SecpCtx {
1296        &self.secp
1297    }
1298
1299    /// Returns the descriptor used to create addresses for a particular `keychain`.
1300    pub fn get_descriptor_for_keychain(&self, keychain: KeychainKind) -> &ExtendedDescriptor {
1301        let (descriptor, _) = self._get_descriptor_for_keychain(keychain);
1302        descriptor
1303    }
1304
1305    // Internals
1306
1307    fn _get_descriptor_for_keychain(
1308        &self,
1309        keychain: KeychainKind,
1310    ) -> (&ExtendedDescriptor, KeychainKind) {
1311        match keychain {
1312            KeychainKind::Internal if self.change_descriptor.is_some() => (
1313                self.change_descriptor.as_ref().unwrap(),
1314                KeychainKind::Internal,
1315            ),
1316            _ => (&self.descriptor, KeychainKind::External),
1317        }
1318    }
1319
1320    fn get_descriptor_for_txout(&self, txout: &TxOut) -> Result<Option<DerivedDescriptor>, Error> {
1321        Ok(self
1322            .database
1323            .borrow()
1324            .get_path_from_script_pubkey(&txout.script_pubkey)?
1325            .map(|(keychain, child)| (self.get_descriptor_for_keychain(keychain), child))
1326            .map(|(desc, child)| desc.at_derivation_index(child)))
1327    }
1328
1329    fn fetch_and_increment_index(&self, keychain: KeychainKind) -> Result<u32, Error> {
1330        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
1331        let index = match descriptor.has_wildcard() {
1332            false => 0,
1333            true => self.database.borrow_mut().increment_last_index(keychain)?,
1334        };
1335
1336        if self
1337            .database
1338            .borrow()
1339            .get_script_pubkey_from_path(keychain, index)?
1340            .is_none()
1341        {
1342            self.cache_addresses(keychain, index, CACHE_ADDR_BATCH_SIZE)?;
1343        }
1344
1345        Ok(index)
1346    }
1347
1348    fn fetch_index(&self, keychain: KeychainKind) -> Result<u32, Error> {
1349        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
1350        let index = match descriptor.has_wildcard() {
1351            false => Some(0),
1352            true => self.database.borrow_mut().get_last_index(keychain)?,
1353        };
1354
1355        if let Some(i) = index {
1356            Ok(i)
1357        } else {
1358            self.fetch_and_increment_index(keychain)
1359        }
1360    }
1361
1362    fn set_index(&self, keychain: KeychainKind, index: u32) -> Result<(), Error> {
1363        self.database.borrow_mut().set_last_index(keychain, index)?;
1364        Ok(())
1365    }
1366
1367    fn cache_addresses(
1368        &self,
1369        keychain: KeychainKind,
1370        from: u32,
1371        mut count: u32,
1372    ) -> Result<(), Error> {
1373        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
1374        if !descriptor.has_wildcard() {
1375            if from > 0 {
1376                return Ok(());
1377            }
1378
1379            count = 1;
1380        }
1381
1382        let mut address_batch = self.database.borrow().begin_batch();
1383
1384        let start_time = time::Instant::new();
1385        for i in from..(from + count) {
1386            address_batch.set_script_pubkey(
1387                &descriptor.at_derivation_index(i).script_pubkey(),
1388                keychain,
1389                i,
1390            )?;
1391        }
1392
1393        info!(
1394            "Derivation of {} addresses from {} took {} ms",
1395            count,
1396            from,
1397            start_time.elapsed().as_millis()
1398        );
1399
1400        self.database.borrow_mut().commit_batch(address_batch)?;
1401
1402        Ok(())
1403    }
1404
1405    fn get_available_utxos(&self) -> Result<Vec<(LocalUtxo, usize)>, Error> {
1406        Ok(self
1407            .list_unspent()?
1408            .into_iter()
1409            .map(|utxo| {
1410                let keychain = utxo.keychain;
1411                (
1412                    utxo,
1413                    self.get_descriptor_for_keychain(keychain)
1414                        .max_satisfaction_weight()
1415                        .unwrap(),
1416                )
1417            })
1418            .collect())
1419    }
1420
1421    /// Given the options returns the list of utxos that must be used to form the
1422    /// transaction and any further that may be used if needed.
1423    #[allow(clippy::type_complexity)]
1424    #[allow(clippy::too_many_arguments)]
1425    fn preselect_utxos(
1426        &self,
1427        change_policy: tx_builder::ChangeSpendPolicy,
1428        unspendable: &HashSet<OutPoint>,
1429        manually_selected: Vec<WeightedUtxo>,
1430        must_use_all_available: bool,
1431        manual_only: bool,
1432        must_only_use_confirmed_tx: bool,
1433        current_height: Option<u32>,
1434    ) -> Result<(Vec<WeightedUtxo>, Vec<WeightedUtxo>), Error> {
1435        //    must_spend <- manually selected utxos
1436        //    may_spend  <- all other available utxos
1437        let mut may_spend = self.get_available_utxos()?;
1438
1439        may_spend.retain(|may_spend| {
1440            !manually_selected
1441                .iter()
1442                .any(|manually_selected| manually_selected.utxo.outpoint() == may_spend.0.outpoint)
1443        });
1444        let mut must_spend = manually_selected;
1445
1446        // NOTE: we are intentionally ignoring `unspendable` here. i.e manual
1447        // selection overrides unspendable.
1448        if manual_only {
1449            return Ok((must_spend, vec![]));
1450        }
1451
1452        let database = self.database.borrow();
1453        let satisfies_confirmed = may_spend
1454            .iter()
1455            .map(|u| {
1456                database
1457                    .get_tx(&u.0.outpoint.txid, true)
1458                    .map(|tx| match tx {
1459                        // We don't have the tx in the db for some reason,
1460                        // so we can't know for sure if it's mature or not.
1461                        // We prefer not to spend it.
1462                        None => false,
1463                        Some(tx) => {
1464                            // Whether the UTXO is mature and, if needed, confirmed
1465                            let mut spendable = true;
1466                            if must_only_use_confirmed_tx && tx.confirmation_time.is_none() {
1467                                return false;
1468                            }
1469                            if tx
1470                                .transaction
1471                                .expect("We specifically ask for the transaction above")
1472                                .is_coin_base()
1473                            {
1474                                if let Some(current_height) = current_height {
1475                                    match &tx.confirmation_time {
1476                                        Some(t) => {
1477                                            // https://github.com/bitcoin/bitcoin/blob/c5e67be03bb06a5d7885c55db1f016fbf2333fe3/src/validation.cpp#L373-L375
1478                                            spendable &= (current_height.saturating_sub(t.height))
1479                                                >= COINBASE_MATURITY;
1480                                        }
1481                                        None => spendable = false,
1482                                    }
1483                                }
1484                            }
1485                            spendable
1486                        }
1487                    })
1488            })
1489            .collect::<Result<Vec<_>, _>>()?;
1490
1491        let mut i = 0;
1492        may_spend.retain(|u| {
1493            let retain = change_policy.is_satisfied_by(&u.0)
1494                && !unspendable.contains(&u.0.outpoint)
1495                && satisfies_confirmed[i];
1496            i += 1;
1497            retain
1498        });
1499
1500        let mut may_spend = may_spend
1501            .into_iter()
1502            .map(|(local_utxo, satisfaction_weight)| WeightedUtxo {
1503                satisfaction_weight,
1504                utxo: Utxo::Local(local_utxo),
1505            })
1506            .collect();
1507
1508        if must_use_all_available {
1509            must_spend.append(&mut may_spend);
1510        }
1511
1512        Ok((must_spend, may_spend))
1513    }
1514
1515    fn complete_transaction(
1516        &self,
1517        tx: Transaction,
1518        selected: Vec<Utxo>,
1519        params: TxParams,
1520    ) -> Result<psbt::PartiallySignedTransaction, Error> {
1521        let mut psbt = psbt::PartiallySignedTransaction::from_unsigned_tx(tx)?;
1522
1523        if params.add_global_xpubs {
1524            let mut all_xpubs = self.descriptor.get_extended_keys()?;
1525            if let Some(change_descriptor) = &self.change_descriptor {
1526                all_xpubs.extend(change_descriptor.get_extended_keys()?);
1527            }
1528
1529            for xpub in all_xpubs {
1530                let origin = match xpub.origin {
1531                    Some(origin) => origin,
1532                    None if xpub.xkey.depth == 0 => {
1533                        (xpub.root_fingerprint(&self.secp), vec![].into())
1534                    }
1535                    _ => return Err(Error::MissingKeyOrigin(xpub.xkey.to_string())),
1536                };
1537
1538                psbt.xpub.insert(xpub.xkey, origin);
1539            }
1540        }
1541
1542        let mut lookup_output = selected
1543            .into_iter()
1544            .map(|utxo| (utxo.outpoint(), utxo))
1545            .collect::<HashMap<_, _>>();
1546
1547        // add metadata for the inputs
1548        for (psbt_input, input) in psbt.inputs.iter_mut().zip(psbt.unsigned_tx.input.iter()) {
1549            let utxo = match lookup_output.remove(&input.previous_output) {
1550                Some(utxo) => utxo,
1551                None => continue,
1552            };
1553
1554            match utxo {
1555                Utxo::Local(utxo) => {
1556                    *psbt_input =
1557                        match self.get_psbt_input(utxo, params.sighash, params.only_witness_utxo) {
1558                            Ok(psbt_input) => psbt_input,
1559                            Err(e) => match e {
1560                                Error::UnknownUtxo => psbt::Input {
1561                                    sighash_type: params.sighash,
1562                                    ..psbt::Input::default()
1563                                },
1564                                _ => return Err(e),
1565                            },
1566                        }
1567                }
1568                Utxo::Foreign {
1569                    psbt_input: foreign_psbt_input,
1570                    outpoint,
1571                } => {
1572                    let is_taproot = foreign_psbt_input
1573                        .witness_utxo
1574                        .as_ref()
1575                        .map(|txout| txout.script_pubkey.is_v1_p2tr())
1576                        .unwrap_or(false);
1577                    if !is_taproot
1578                        && !params.only_witness_utxo
1579                        && foreign_psbt_input.non_witness_utxo.is_none()
1580                    {
1581                        return Err(Error::Generic(format!(
1582                            "Missing non_witness_utxo on foreign utxo {}",
1583                            outpoint
1584                        )));
1585                    }
1586                    *psbt_input = *foreign_psbt_input;
1587                }
1588            }
1589        }
1590
1591        self.update_psbt_with_descriptor(&mut psbt)?;
1592
1593        Ok(psbt)
1594    }
1595
1596    pub fn cus_complete_transaction(
1597        &self,
1598        tx: Transaction,
1599    ) -> Result<psbt::PartiallySignedTransaction, Error> {
1600        let params = TxParams::default();
1601        // 获取 tx 中使用到的utxo
1602        let selected: Vec<Utxo> = self.list_unspent()
1603            .unwrap()
1604            .into_iter()
1605            .filter(|utxo| {
1606                tx.input
1607                    .iter()
1608                    .any(|tx_input| {
1609                        tx_input.previous_output.txid == utxo.outpoint.txid &&
1610                            tx_input.previous_output.vout == utxo.outpoint.vout
1611                    })
1612            })
1613            .map(|utxo| {
1614                Utxo::Local(utxo)
1615            })
1616            .collect();
1617
1618
1619        let mut psbt = psbt::PartiallySignedTransaction::from_unsigned_tx(tx)?;
1620
1621        if params.add_global_xpubs {
1622            let mut all_xpubs = self.descriptor.get_extended_keys()?;
1623            if let Some(change_descriptor) = &self.change_descriptor {
1624                all_xpubs.extend(change_descriptor.get_extended_keys()?);
1625            }
1626
1627            for xpub in all_xpubs {
1628                let origin = match xpub.origin {
1629                    Some(origin) => origin,
1630                    None if xpub.xkey.depth == 0 => {
1631                        (xpub.root_fingerprint(&self.secp), vec![].into())
1632                    }
1633                    _ => return Err(Error::MissingKeyOrigin(xpub.xkey.to_string())),
1634                };
1635
1636                psbt.xpub.insert(xpub.xkey, origin);
1637            }
1638        }
1639
1640        let mut lookup_output = selected
1641            .into_iter()
1642            .map(|utxo| (utxo.outpoint(), utxo))
1643            .collect::<HashMap<_, _>>();
1644
1645        // add metadata for the inputs
1646        for (psbt_input, input) in psbt.inputs.iter_mut().zip(psbt.unsigned_tx.input.iter()) {
1647            let utxo = match lookup_output.remove(&input.previous_output) {
1648                Some(utxo) => utxo,
1649                None => continue,
1650            };
1651
1652            match utxo {
1653                Utxo::Local(utxo) => {
1654                    *psbt_input =
1655                        match self.get_psbt_input(utxo, params.sighash, params.only_witness_utxo) {
1656                            Ok(psbt_input) => psbt_input,
1657                            Err(e) => match e {
1658                                Error::UnknownUtxo => psbt::Input {
1659                                    sighash_type: params.sighash,
1660                                    ..psbt::Input::default()
1661                                },
1662                                _ => return Err(e),
1663                            },
1664                        }
1665                }
1666                Utxo::Foreign {
1667                    psbt_input: foreign_psbt_input,
1668                    outpoint,
1669                } => {
1670                    let is_taproot = foreign_psbt_input
1671                        .witness_utxo
1672                        .as_ref()
1673                        .map(|txout| txout.script_pubkey.is_v1_p2tr())
1674                        .unwrap_or(false);
1675                    if !is_taproot
1676                        && !params.only_witness_utxo
1677                        && foreign_psbt_input.non_witness_utxo.is_none()
1678                    {
1679                        return Err(Error::Generic(format!(
1680                            "Missing non_witness_utxo on foreign utxo {}",
1681                            outpoint
1682                        )));
1683                    }
1684                    *psbt_input = *foreign_psbt_input;
1685                }
1686            }
1687        }
1688
1689        self.update_psbt_with_descriptor(&mut psbt)?;
1690
1691        Ok(psbt)
1692    }
1693
1694    /// get the corresponding PSBT Input for a LocalUtxo
1695    pub fn get_psbt_input(
1696        &self,
1697        utxo: LocalUtxo,
1698        sighash_type: Option<psbt::PsbtSighashType>,
1699        only_witness_utxo: bool,
1700    ) -> Result<psbt::Input, Error> {
1701        // Try to find the prev_script in our db to figure out if this is internal or external,
1702        // and the derivation index
1703        let (keychain, child) = self
1704            .database
1705            .borrow()
1706            .get_path_from_script_pubkey(&utxo.txout.script_pubkey)?
1707            .ok_or(Error::UnknownUtxo)?;
1708
1709        let mut psbt_input = psbt::Input {
1710            sighash_type,
1711            ..psbt::Input::default()
1712        };
1713
1714        let desc = self.get_descriptor_for_keychain(keychain);
1715        let derived_descriptor = desc.at_derivation_index(child);
1716
1717        psbt_input
1718            .update_with_descriptor_unchecked(&derived_descriptor)
1719            .map_err(MiniscriptPsbtError::Conversion)?;
1720
1721        let prev_output = utxo.outpoint;
1722        if let Some(prev_tx) = self.database.borrow().get_raw_tx(&prev_output.txid)? {
1723            if desc.is_witness() || desc.is_taproot() {
1724                psbt_input.witness_utxo = Some(prev_tx.output[prev_output.vout as usize].clone());
1725            }
1726            if !desc.is_taproot() && (!desc.is_witness() || !only_witness_utxo) {
1727                psbt_input.non_witness_utxo = Some(prev_tx);
1728            }
1729        }
1730        Ok(psbt_input)
1731    }
1732
1733    fn update_psbt_with_descriptor(
1734        &self,
1735        psbt: &mut psbt::PartiallySignedTransaction,
1736    ) -> Result<(), Error> {
1737        // We need to borrow `psbt` mutably within the loops, so we have to allocate a vec for all
1738        // the input utxos and outputs
1739        //
1740        // Clippy complains that the collect is not required, but that's wrong
1741        #[allow(clippy::needless_collect)]
1742        let utxos = (0..psbt.inputs.len())
1743            .filter_map(|i| psbt.get_utxo_for(i).map(|utxo| (true, i, utxo)))
1744            .chain(
1745                psbt.unsigned_tx
1746                    .output
1747                    .iter()
1748                    .enumerate()
1749                    .map(|(i, out)| (false, i, out.clone())),
1750            )
1751            .collect::<Vec<_>>();
1752
1753        // Try to figure out the keychain and derivation for every input and output
1754        for (is_input, index, out) in utxos.into_iter() {
1755            if let Some((keychain, child)) = self
1756                .database
1757                .borrow()
1758                .get_path_from_script_pubkey(&out.script_pubkey)?
1759            {
1760                debug!(
1761                    "Found descriptor for input #{} {:?}/{}",
1762                    index, keychain, child
1763                );
1764
1765                let desc = self.get_descriptor_for_keychain(keychain);
1766                let desc = desc.at_derivation_index(child);
1767
1768                if is_input {
1769                    psbt.update_input_with_descriptor(index, &desc)
1770                        .map_err(MiniscriptPsbtError::UtxoUpdate)?;
1771                } else {
1772                    psbt.update_output_with_descriptor(index, &desc)
1773                        .map_err(MiniscriptPsbtError::OutputUpdate)?;
1774                }
1775            }
1776        }
1777
1778        Ok(())
1779    }
1780
1781    /// Return an immutable reference to the internal database
1782    pub fn database(&self) -> impl std::ops::Deref<Target = D> + '_ {
1783        self.database.borrow()
1784    }
1785
1786    /// Sync the internal database with the blockchain
1787    #[maybe_async]
1788    pub fn sync<B: WalletSync + GetHeight>(
1789        &self,
1790        blockchain: &B,
1791        sync_opts: SyncOptions,
1792    ) -> Result<(), Error> {
1793        debug!("Begin sync...");
1794
1795        // TODO: for the next runs, we cannot reuse the `sync_opts.progress` object due to trait
1796        // restrictions
1797        let mut progress_iter = sync_opts.progress.into_iter();
1798        let mut new_progress = || {
1799            progress_iter
1800                .next()
1801                .unwrap_or_else(|| Box::new(NoopProgress))
1802        };
1803
1804        let run_setup = self.ensure_addresses_cached(CACHE_ADDR_BATCH_SIZE)?;
1805        debug!("run_setup: {}", run_setup);
1806
1807        // TODO: what if i generate an address first and cache some addresses?
1808        // TODO: we should sync if generating an address triggers a new batch to be stored
1809
1810        // We need to ensure descriptor is derivable to fullfil "missing cache", otherwise we will
1811        // end up with an infinite loop
1812        let has_wildcard = self.descriptor.has_wildcard()
1813            && (self.change_descriptor.is_none()
1814                || self.change_descriptor.as_ref().unwrap().has_wildcard());
1815
1816        // Restrict max rounds in case of faulty "missing cache" implementation by blockchain
1817        let max_rounds = if has_wildcard { 100 } else { 1 };
1818
1819        for _ in 0..max_rounds {
1820            let sync_res = if run_setup {
1821                maybe_await!(blockchain.wallet_setup(&self.database, new_progress()))
1822            } else {
1823                maybe_await!(blockchain.wallet_sync(&self.database, new_progress()))
1824            };
1825
1826            // If the error is the special `MissingCachedScripts` error, we return the number of
1827            // scripts we should ensure cached.
1828            // On any other error, we should return the error.
1829            // On no error, we say `ensure_cache` is 0.
1830            let ensure_cache = sync_res.map_or_else(
1831                |e| match e {
1832                    Error::MissingCachedScripts(inner) => {
1833                        // each call to `WalletSync` is expensive, maximize on scripts to search for
1834                        let extra =
1835                            std::cmp::max(inner.missing_count as u32, CACHE_ADDR_BATCH_SIZE);
1836                        let last = inner.last_count as u32;
1837                        Ok(extra + last)
1838                    }
1839                    _ => Err(e),
1840                },
1841                |_| Ok(0_u32),
1842            )?;
1843
1844            // cache and try again, break when there is nothing to cache
1845            if !self.ensure_addresses_cached(ensure_cache)? {
1846                break;
1847            }
1848        }
1849
1850        let sync_time = SyncTime {
1851            block_time: BlockTime {
1852                height: maybe_await!(blockchain.get_height())?,
1853                timestamp: time::get_timestamp(),
1854            },
1855        };
1856        debug!("Saving `sync_time` = {:?}", sync_time);
1857        self.database.borrow_mut().set_sync_time(sync_time)?;
1858
1859        Ok(())
1860    }
1861
1862    /// Return the checksum of the public descriptor associated to `keychain`
1863    ///
1864    /// Internally calls [`Self::get_descriptor_for_keychain`] to fetch the right descriptor
1865    pub fn descriptor_checksum(&self, keychain: KeychainKind) -> String {
1866        self.get_descriptor_for_keychain(keychain)
1867            .to_string()
1868            .split_once('#')
1869            .unwrap()
1870            .1
1871            .to_string()
1872    }
1873}
1874
1875/// Deterministically generate a unique name given the descriptors defining the wallet
1876///
1877/// Compatible with [`wallet_name_from_descriptor`]
1878pub fn wallet_name_from_descriptor<T>(
1879    descriptor: T,
1880    change_descriptor: Option<T>,
1881    network: Network,
1882    secp: &SecpCtx,
1883) -> Result<String, Error>
1884where
1885    T: IntoWalletDescriptor,
1886{
1887    //TODO check descriptors contains only public keys
1888    let descriptor = descriptor
1889        .into_wallet_descriptor(secp, network)?
1890        .0
1891        .to_string();
1892    let mut wallet_name = calc_checksum(&descriptor[..descriptor.find('#').unwrap()])?;
1893    if let Some(change_descriptor) = change_descriptor {
1894        let change_descriptor = change_descriptor
1895            .into_wallet_descriptor(secp, network)?
1896            .0
1897            .to_string();
1898        wallet_name.push_str(
1899            calc_checksum(&change_descriptor[..change_descriptor.find('#').unwrap()])?.as_str(),
1900        );
1901    }
1902
1903    Ok(wallet_name)
1904}
1905
1906/// Return a fake wallet that appears to be funded for testing.
1907pub fn get_funded_wallet(
1908    descriptor: &str,
1909) -> (Wallet<AnyDatabase>, (String, Option<String>), bitcoin::Txid) {
1910    let descriptors = testutils!(@descriptors (descriptor));
1911    let wallet = Wallet::new(
1912        &descriptors.0,
1913        None,
1914        Network::Regtest,
1915        AnyDatabase::Memory(MemoryDatabase::new()),
1916    )
1917    .unwrap();
1918
1919    let funding_address_kix = 0;
1920
1921    let tx_meta = testutils! {
1922            @tx ( (@external descriptors, funding_address_kix) => 50_000 ) (@confirmations 1)
1923    };
1924
1925    wallet
1926        .database
1927        .borrow_mut()
1928        .set_script_pubkey(
1929            &bitcoin::Address::from_str(&tx_meta.output.get(0).unwrap().to_address)
1930                .unwrap()
1931                .script_pubkey(),
1932            KeychainKind::External,
1933            funding_address_kix,
1934        )
1935        .unwrap();
1936    wallet
1937        .database
1938        .borrow_mut()
1939        .set_last_index(KeychainKind::External, funding_address_kix)
1940        .unwrap();
1941
1942    let txid = crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, Some(100));
1943
1944    (wallet, descriptors, txid)
1945}
1946
1947#[cfg(test)]
1948pub(crate) mod test {
1949    use assert_matches::assert_matches;
1950    use bitcoin::{util::psbt, Network, PackedLockTime, Sequence};
1951
1952    use crate::database::Database;
1953    use crate::types::KeychainKind;
1954
1955    use super::*;
1956    use crate::signer::{SignOptions, SignerError};
1957    use crate::wallet::AddressIndex::{LastUnused, New, Peek, Reset};
1958
1959    // The satisfaction size of a P2WPKH is 112 WU =
1960    // 1 (elements in witness) + 1 (OP_PUSH) + 33 (pk) + 1 (OP_PUSH) + 72 (signature + sighash) + 1*4 (script len)
1961    // On the witness itself, we have to push once for the pk (33WU) and once for signature + sighash (72WU), for
1962    // a total of 105 WU.
1963    // Here, we push just once for simplicity, so we have to add an extra byte for the missing
1964    // OP_PUSH.
1965    const P2WPKH_FAKE_WITNESS_SIZE: usize = 106;
1966
1967    #[test]
1968    fn test_descriptor_checksum() {
1969        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
1970        let checksum = wallet.descriptor_checksum(KeychainKind::External);
1971        assert_eq!(checksum.len(), 8);
1972        assert_eq!(
1973            calc_checksum(&wallet.descriptor.to_string()).unwrap(),
1974            checksum
1975        );
1976    }
1977
1978    #[test]
1979    fn test_db_checksum() {
1980        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
1981        let desc = wallet.descriptor.to_string();
1982
1983        let checksum = calc_checksum_bytes_internal(&desc, true).unwrap();
1984        let checksum_inception = calc_checksum_bytes_internal(&desc, false).unwrap();
1985        let checksum_invalid = [b'q'; 8];
1986
1987        let mut db = MemoryDatabase::new();
1988        db.check_descriptor_checksum(KeychainKind::External, checksum)
1989            .expect("failed to save actual checksum");
1990        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
1991            .expect("db that uses actual checksum should be supported");
1992
1993        let mut db = MemoryDatabase::new();
1994        db.check_descriptor_checksum(KeychainKind::External, checksum_inception)
1995            .expect("failed to save checksum inception");
1996        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
1997            .expect("db that uses checksum inception should be supported");
1998
1999        let mut db = MemoryDatabase::new();
2000        db.check_descriptor_checksum(KeychainKind::External, checksum_invalid)
2001            .expect("failed to save invalid checksum");
2002        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
2003            .expect_err("db that uses invalid checksum should fail");
2004    }
2005
2006    #[test]
2007    fn test_get_funded_wallet_balance() {
2008        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2009        assert_eq!(wallet.get_balance().unwrap().confirmed, 50000);
2010    }
2011
2012    #[test]
2013    fn test_cache_addresses_fixed() {
2014        let db = MemoryDatabase::new();
2015        let wallet = Wallet::new(
2016            "wpkh(L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6)",
2017            None,
2018            Network::Testnet,
2019            db,
2020        )
2021        .unwrap();
2022
2023        assert_eq!(
2024            wallet.get_address(New).unwrap().to_string(),
2025            "tb1qj08ys4ct2hzzc2hcz6h2hgrvlmsjynaw43s835"
2026        );
2027        assert_eq!(
2028            wallet.get_address(New).unwrap().to_string(),
2029            "tb1qj08ys4ct2hzzc2hcz6h2hgrvlmsjynaw43s835"
2030        );
2031
2032        assert!(wallet
2033            .database
2034            .borrow_mut()
2035            .get_script_pubkey_from_path(KeychainKind::External, 0)
2036            .unwrap()
2037            .is_some());
2038        assert!(wallet
2039            .database
2040            .borrow_mut()
2041            .get_script_pubkey_from_path(KeychainKind::Internal, 0)
2042            .unwrap()
2043            .is_none());
2044    }
2045
2046    #[test]
2047    fn test_cache_addresses() {
2048        let db = MemoryDatabase::new();
2049        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)", None, Network::Testnet, db).unwrap();
2050
2051        assert_eq!(
2052            wallet.get_address(New).unwrap().to_string(),
2053            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
2054        );
2055        assert_eq!(
2056            wallet.get_address(New).unwrap().to_string(),
2057            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
2058        );
2059
2060        assert!(wallet
2061            .database
2062            .borrow_mut()
2063            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE - 1)
2064            .unwrap()
2065            .is_some());
2066        assert!(wallet
2067            .database
2068            .borrow_mut()
2069            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE)
2070            .unwrap()
2071            .is_none());
2072    }
2073
2074    #[test]
2075    fn test_cache_addresses_refill() {
2076        let db = MemoryDatabase::new();
2077        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)", None, Network::Testnet, db).unwrap();
2078
2079        assert_eq!(
2080            wallet.get_address(New).unwrap().to_string(),
2081            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
2082        );
2083        assert!(wallet
2084            .database
2085            .borrow_mut()
2086            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE - 1)
2087            .unwrap()
2088            .is_some());
2089
2090        for _ in 0..CACHE_ADDR_BATCH_SIZE {
2091            wallet.get_address(New).unwrap();
2092        }
2093
2094        assert!(wallet
2095            .database
2096            .borrow_mut()
2097            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE * 2 - 1)
2098            .unwrap()
2099            .is_some());
2100    }
2101
2102    pub(crate) fn get_test_wpkh() -> &'static str {
2103        "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)"
2104    }
2105
2106    pub(crate) fn get_test_single_sig_csv() -> &'static str {
2107        // and(pk(Alice),older(6))
2108        "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),older(6)))"
2109    }
2110
2111    pub(crate) fn get_test_a_or_b_plus_csv() -> &'static str {
2112        // or(pk(Alice),and(pk(Bob),older(144)))
2113        "wsh(or_d(pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu),and_v(v:pk(cMnkdebixpXMPfkcNEjjGin7s94hiehAH4mLbYkZoh9KSiNNmqC8),older(144))))"
2114    }
2115
2116    pub(crate) fn get_test_single_sig_cltv() -> &'static str {
2117        // and(pk(Alice),after(100000))
2118        "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100000)))"
2119    }
2120
2121    pub(crate) fn get_test_tr_single_sig() -> &'static str {
2122        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG)"
2123    }
2124
2125    pub(crate) fn get_test_tr_with_taptree() -> &'static str {
2126        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{pk(cPZzKuNmpuUjD1e8jUU4PVzy2b5LngbSip8mBsxf4e7rSFZVb4Uh),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
2127    }
2128
2129    pub(crate) fn get_test_tr_with_taptree_both_priv() -> &'static str {
2130        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{pk(cPZzKuNmpuUjD1e8jUU4PVzy2b5LngbSip8mBsxf4e7rSFZVb4Uh),pk(cNaQCDwmmh4dS9LzCgVtyy1e1xjCJ21GUDHe9K98nzb689JvinGV)})"
2131    }
2132
2133    pub(crate) fn get_test_tr_repeated_key() -> &'static str {
2134        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100)),and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(200))})"
2135    }
2136
2137    pub(crate) fn get_test_tr_single_sig_xprv() -> &'static str {
2138        "tr(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*)"
2139    }
2140
2141    pub(crate) fn get_test_tr_with_taptree_xprv() -> &'static str {
2142        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG,{pk(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
2143    }
2144
2145    pub(crate) fn get_test_tr_dup_keys() -> &'static str {
2146        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG,{pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
2147    }
2148
2149    macro_rules! assert_fee_rate {
2150        ($psbt:expr, $fees:expr, $fee_rate:expr $( ,@dust_change $( $dust_change:expr )* )* $( ,@add_signature $( $add_signature:expr )* )* ) => ({
2151            let psbt = $psbt.clone();
2152            #[allow(unused_mut)]
2153            let mut tx = $psbt.clone().extract_tx();
2154            $(
2155                $( $add_signature )*
2156                for txin in &mut tx.input {
2157                    txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
2158                }
2159            )*
2160
2161            #[allow(unused_mut)]
2162            #[allow(unused_assignments)]
2163            let mut dust_change = false;
2164            $(
2165                $( $dust_change )*
2166                dust_change = true;
2167            )*
2168
2169            let fee_amount = psbt
2170                .inputs
2171                .iter()
2172                .fold(0, |acc, i| acc + i.witness_utxo.as_ref().unwrap().value)
2173                - psbt
2174                    .unsigned_tx
2175                    .output
2176                    .iter()
2177                    .fold(0, |acc, o| acc + o.value);
2178
2179            assert_eq!(fee_amount, $fees);
2180
2181            let tx_fee_rate = FeeRate::from_wu($fees, tx.weight());
2182            let fee_rate = $fee_rate;
2183
2184            if !dust_change {
2185                assert!(tx_fee_rate >= fee_rate && (tx_fee_rate - fee_rate).as_sat_per_vb().abs() < 0.5, "Expected fee rate of {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
2186            } else {
2187                assert!(tx_fee_rate >= fee_rate, "Expected fee rate of at least {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
2188            }
2189        });
2190    }
2191
2192    macro_rules! from_str {
2193        ($e:expr, $t:ty) => {{
2194            use std::str::FromStr;
2195            <$t>::from_str($e).unwrap()
2196        }};
2197
2198        ($e:expr) => {
2199            from_str!($e, _)
2200        };
2201    }
2202
2203    #[test]
2204    #[should_panic(expected = "NoRecipients")]
2205    fn test_create_tx_empty_recipients() {
2206        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2207        wallet.build_tx().finish().unwrap();
2208    }
2209
2210    #[test]
2211    #[should_panic(expected = "NoUtxosSelected")]
2212    fn test_create_tx_manually_selected_empty_utxos() {
2213        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2214        let addr = wallet.get_address(New).unwrap();
2215        let mut builder = wallet.build_tx();
2216        builder
2217            .add_recipient(addr.script_pubkey(), 25_000)
2218            .manually_selected_only();
2219        builder.finish().unwrap();
2220    }
2221
2222    #[test]
2223    #[should_panic(expected = "Invalid version `0`")]
2224    fn test_create_tx_version_0() {
2225        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2226        let addr = wallet.get_address(New).unwrap();
2227        let mut builder = wallet.build_tx();
2228        builder
2229            .add_recipient(addr.script_pubkey(), 25_000)
2230            .version(0);
2231        builder.finish().unwrap();
2232    }
2233
2234    #[test]
2235    #[should_panic(
2236        expected = "TxBuilder requested version `1`, but at least `2` is needed to use OP_CSV"
2237    )]
2238    fn test_create_tx_version_1_csv() {
2239        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
2240        let addr = wallet.get_address(New).unwrap();
2241        let mut builder = wallet.build_tx();
2242        builder
2243            .add_recipient(addr.script_pubkey(), 25_000)
2244            .version(1);
2245        builder.finish().unwrap();
2246    }
2247
2248    #[test]
2249    fn test_create_tx_custom_version() {
2250        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2251        let addr = wallet.get_address(New).unwrap();
2252        let mut builder = wallet.build_tx();
2253        builder
2254            .add_recipient(addr.script_pubkey(), 25_000)
2255            .version(42);
2256        let (psbt, _) = builder.finish().unwrap();
2257
2258        assert_eq!(psbt.unsigned_tx.version, 42);
2259    }
2260
2261    #[test]
2262    fn test_create_tx_default_locktime() {
2263        let descriptors = testutils!(@descriptors (get_test_wpkh()));
2264        let wallet = Wallet::new(
2265            &descriptors.0,
2266            None,
2267            Network::Regtest,
2268            AnyDatabase::Memory(MemoryDatabase::new()),
2269        )
2270        .unwrap();
2271
2272        let tx_meta = testutils! {
2273                @tx ( (@external descriptors, 0) => 50_000 )
2274        };
2275
2276        // Add the transaction to our db, but do not sync the db.
2277        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
2278
2279        let addr = wallet.get_address(New).unwrap();
2280        let mut builder = wallet.build_tx();
2281        builder.add_recipient(addr.script_pubkey(), 25_000);
2282        let (psbt, _) = builder.finish().unwrap();
2283
2284        // Since we never synced the wallet we don't have a last_sync_height
2285        // we could use to try to prevent fee sniping. We default to 0.
2286        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(0));
2287    }
2288
2289    #[test]
2290    fn test_create_tx_fee_sniping_locktime_provided_height() {
2291        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2292        let addr = wallet.get_address(New).unwrap();
2293        let mut builder = wallet.build_tx();
2294        builder.add_recipient(addr.script_pubkey(), 25_000);
2295        let sync_time = SyncTime {
2296            block_time: BlockTime {
2297                height: 24,
2298                timestamp: 0,
2299            },
2300        };
2301        wallet
2302            .database
2303            .borrow_mut()
2304            .set_sync_time(sync_time)
2305            .unwrap();
2306        let current_height = 25;
2307        builder.current_height(current_height);
2308        let (psbt, _) = builder.finish().unwrap();
2309
2310        // current_height will override the last sync height
2311        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(current_height));
2312    }
2313
2314    #[test]
2315    fn test_create_tx_fee_sniping_locktime_last_sync() {
2316        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2317        let addr = wallet.get_address(New).unwrap();
2318        let mut builder = wallet.build_tx();
2319        builder.add_recipient(addr.script_pubkey(), 25_000);
2320        let sync_time = SyncTime {
2321            block_time: BlockTime {
2322                height: 25,
2323                timestamp: 0,
2324            },
2325        };
2326        wallet
2327            .database
2328            .borrow_mut()
2329            .set_sync_time(sync_time.clone())
2330            .unwrap();
2331        let (psbt, _) = builder.finish().unwrap();
2332
2333        // If there's no current_height we're left with using the last sync height
2334        assert_eq!(
2335            psbt.unsigned_tx.lock_time,
2336            PackedLockTime(sync_time.block_time.height)
2337        );
2338    }
2339
2340    #[test]
2341    fn test_create_tx_default_locktime_cltv() {
2342        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
2343        let addr = wallet.get_address(New).unwrap();
2344        let mut builder = wallet.build_tx();
2345        builder.add_recipient(addr.script_pubkey(), 25_000);
2346        let (psbt, _) = builder.finish().unwrap();
2347
2348        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(100_000));
2349    }
2350
2351    #[test]
2352    fn test_create_tx_custom_locktime() {
2353        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2354        let addr = wallet.get_address(New).unwrap();
2355        let mut builder = wallet.build_tx();
2356        builder
2357            .add_recipient(addr.script_pubkey(), 25_000)
2358            .current_height(630_001)
2359            .nlocktime(LockTime::from_height(630_000).unwrap());
2360        let (psbt, _) = builder.finish().unwrap();
2361
2362        // When we explicitly specify a nlocktime
2363        // we don't try any fee sniping prevention trick
2364        // (we ignore the current_height)
2365        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
2366    }
2367
2368    #[test]
2369    fn test_create_tx_custom_locktime_compatible_with_cltv() {
2370        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
2371        let addr = wallet.get_address(New).unwrap();
2372        let mut builder = wallet.build_tx();
2373        builder
2374            .add_recipient(addr.script_pubkey(), 25_000)
2375            .nlocktime(LockTime::from_height(630_000).unwrap());
2376        let (psbt, _) = builder.finish().unwrap();
2377
2378        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
2379    }
2380
2381    #[test]
2382    #[should_panic(
2383        expected = "TxBuilder requested timelock of `Blocks(Height(50000))`, but at least `Blocks(Height(100000))` is required to spend from this script"
2384    )]
2385    fn test_create_tx_custom_locktime_incompatible_with_cltv() {
2386        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
2387        let addr = wallet.get_address(New).unwrap();
2388        let mut builder = wallet.build_tx();
2389        builder
2390            .add_recipient(addr.script_pubkey(), 25_000)
2391            .nlocktime(LockTime::from_height(50000).unwrap());
2392        builder.finish().unwrap();
2393    }
2394
2395    #[test]
2396    fn test_create_tx_no_rbf_csv() {
2397        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
2398        let addr = wallet.get_address(New).unwrap();
2399        let mut builder = wallet.build_tx();
2400        builder.add_recipient(addr.script_pubkey(), 25_000);
2401        let (psbt, _) = builder.finish().unwrap();
2402
2403        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(6));
2404    }
2405
2406    #[test]
2407    fn test_create_tx_with_default_rbf_csv() {
2408        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
2409        let addr = wallet.get_address(New).unwrap();
2410        let mut builder = wallet.build_tx();
2411        builder
2412            .add_recipient(addr.script_pubkey(), 25_000)
2413            .enable_rbf();
2414        let (psbt, _) = builder.finish().unwrap();
2415        // When CSV is enabled it takes precedence over the rbf value (unless forced by the user).
2416        // It will be set to the OP_CSV value, in this case 6
2417        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(6));
2418    }
2419
2420    #[test]
2421    #[should_panic(
2422        expected = "Cannot enable RBF with nSequence `Sequence(3)` given a required OP_CSV of `Sequence(6)`"
2423    )]
2424    fn test_create_tx_with_custom_rbf_csv() {
2425        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
2426        let addr = wallet.get_address(New).unwrap();
2427        let mut builder = wallet.build_tx();
2428        builder
2429            .add_recipient(addr.script_pubkey(), 25_000)
2430            .enable_rbf_with_sequence(Sequence(3));
2431        builder.finish().unwrap();
2432    }
2433
2434    #[test]
2435    fn test_create_tx_no_rbf_cltv() {
2436        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
2437        let addr = wallet.get_address(New).unwrap();
2438        let mut builder = wallet.build_tx();
2439        builder.add_recipient(addr.script_pubkey(), 25_000);
2440        let (psbt, _) = builder.finish().unwrap();
2441
2442        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFE));
2443    }
2444
2445    #[test]
2446    #[should_panic(expected = "Cannot enable RBF with a nSequence >= 0xFFFFFFFE")]
2447    fn test_create_tx_invalid_rbf_sequence() {
2448        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2449        let addr = wallet.get_address(New).unwrap();
2450        let mut builder = wallet.build_tx();
2451        builder
2452            .add_recipient(addr.script_pubkey(), 25_000)
2453            .enable_rbf_with_sequence(Sequence(0xFFFFFFFE));
2454        builder.finish().unwrap();
2455    }
2456
2457    #[test]
2458    fn test_create_tx_custom_rbf_sequence() {
2459        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2460        let addr = wallet.get_address(New).unwrap();
2461        let mut builder = wallet.build_tx();
2462        builder
2463            .add_recipient(addr.script_pubkey(), 25_000)
2464            .enable_rbf_with_sequence(Sequence(0xDEADBEEF));
2465        let (psbt, _) = builder.finish().unwrap();
2466
2467        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xDEADBEEF));
2468    }
2469
2470    #[test]
2471    fn test_create_tx_default_sequence() {
2472        let descriptors = testutils!(@descriptors (get_test_wpkh()));
2473        let wallet = Wallet::new(
2474            &descriptors.0,
2475            None,
2476            Network::Regtest,
2477            AnyDatabase::Memory(MemoryDatabase::new()),
2478        )
2479        .unwrap();
2480
2481        let tx_meta = testutils! {
2482                @tx ( (@external descriptors, 0) => 50_000 )
2483        };
2484
2485        // Add the transaction to our db, but do not sync the db. Unsynced db
2486        // should trigger the default sequence value for a new transaction as 0xFFFFFFFF
2487        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
2488
2489        let addr = wallet.get_address(New).unwrap();
2490        let mut builder = wallet.build_tx();
2491        builder.add_recipient(addr.script_pubkey(), 25_000);
2492        let (psbt, _) = builder.finish().unwrap();
2493
2494        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFF));
2495    }
2496
2497    #[test]
2498    #[should_panic(
2499        expected = "The `change_policy` can be set only if the wallet has a change_descriptor"
2500    )]
2501    fn test_create_tx_change_policy_no_internal() {
2502        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2503        let addr = wallet.get_address(New).unwrap();
2504        let mut builder = wallet.build_tx();
2505        builder
2506            .add_recipient(addr.script_pubkey(), 25_000)
2507            .do_not_spend_change();
2508        builder.finish().unwrap();
2509    }
2510
2511    #[test]
2512    fn test_create_tx_drain_wallet_and_drain_to() {
2513        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2514        let addr = wallet.get_address(New).unwrap();
2515        let mut builder = wallet.build_tx();
2516        builder.drain_to(addr.script_pubkey()).drain_wallet();
2517        let (psbt, details) = builder.finish().unwrap();
2518
2519        assert_eq!(psbt.unsigned_tx.output.len(), 1);
2520        assert_eq!(
2521            psbt.unsigned_tx.output[0].value,
2522            50_000 - details.fee.unwrap_or(0)
2523        );
2524    }
2525
2526    #[test]
2527    fn test_create_tx_drain_wallet_and_drain_to_and_with_recipient() {
2528        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2529        let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
2530        let drain_addr = wallet.get_address(New).unwrap();
2531        let mut builder = wallet.build_tx();
2532        builder
2533            .add_recipient(addr.script_pubkey(), 20_000)
2534            .drain_to(drain_addr.script_pubkey())
2535            .drain_wallet();
2536        let (psbt, details) = builder.finish().unwrap();
2537        let outputs = psbt.unsigned_tx.output;
2538
2539        assert_eq!(outputs.len(), 2);
2540        let main_output = outputs
2541            .iter()
2542            .find(|x| x.script_pubkey == addr.script_pubkey())
2543            .unwrap();
2544        let drain_output = outputs
2545            .iter()
2546            .find(|x| x.script_pubkey == drain_addr.script_pubkey())
2547            .unwrap();
2548        assert_eq!(main_output.value, 20_000,);
2549        assert_eq!(drain_output.value, 30_000 - details.fee.unwrap_or(0));
2550    }
2551
2552    #[test]
2553    fn test_create_tx_drain_to_and_utxos() {
2554        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2555        let addr = wallet.get_address(New).unwrap();
2556        let utxos: Vec<_> = wallet
2557            .get_available_utxos()
2558            .unwrap()
2559            .into_iter()
2560            .map(|(u, _)| u.outpoint)
2561            .collect();
2562        let mut builder = wallet.build_tx();
2563        builder
2564            .drain_to(addr.script_pubkey())
2565            .add_utxos(&utxos)
2566            .unwrap();
2567        let (psbt, details) = builder.finish().unwrap();
2568
2569        assert_eq!(psbt.unsigned_tx.output.len(), 1);
2570        assert_eq!(
2571            psbt.unsigned_tx.output[0].value,
2572            50_000 - details.fee.unwrap_or(0)
2573        );
2574    }
2575
2576    #[test]
2577    #[should_panic(expected = "NoRecipients")]
2578    fn test_create_tx_drain_to_no_drain_wallet_no_utxos() {
2579        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2580        let drain_addr = wallet.get_address(New).unwrap();
2581        let mut builder = wallet.build_tx();
2582        builder.drain_to(drain_addr.script_pubkey());
2583        builder.finish().unwrap();
2584    }
2585
2586    #[test]
2587    fn test_create_tx_default_fee_rate() {
2588        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2589        let addr = wallet.get_address(New).unwrap();
2590        let mut builder = wallet.build_tx();
2591        builder.add_recipient(addr.script_pubkey(), 25_000);
2592        let (psbt, details) = builder.finish().unwrap();
2593
2594        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::default(), @add_signature);
2595    }
2596
2597    #[test]
2598    fn test_create_tx_custom_fee_rate() {
2599        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2600        let addr = wallet.get_address(New).unwrap();
2601        let mut builder = wallet.build_tx();
2602        builder
2603            .add_recipient(addr.script_pubkey(), 25_000)
2604            .fee_rate(FeeRate::from_sat_per_vb(5.0));
2605        let (psbt, details) = builder.finish().unwrap();
2606
2607        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(5.0), @add_signature);
2608    }
2609
2610    #[test]
2611    fn test_create_tx_absolute_fee() {
2612        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2613        let addr = wallet.get_address(New).unwrap();
2614        let mut builder = wallet.build_tx();
2615        builder
2616            .drain_to(addr.script_pubkey())
2617            .drain_wallet()
2618            .fee_absolute(100);
2619        let (psbt, details) = builder.finish().unwrap();
2620
2621        assert_eq!(details.fee.unwrap_or(0), 100);
2622        assert_eq!(psbt.unsigned_tx.output.len(), 1);
2623        assert_eq!(
2624            psbt.unsigned_tx.output[0].value,
2625            50_000 - details.fee.unwrap_or(0)
2626        );
2627    }
2628
2629    #[test]
2630    fn test_create_tx_absolute_zero_fee() {
2631        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2632        let addr = wallet.get_address(New).unwrap();
2633        let mut builder = wallet.build_tx();
2634        builder
2635            .drain_to(addr.script_pubkey())
2636            .drain_wallet()
2637            .fee_absolute(0);
2638        let (psbt, details) = builder.finish().unwrap();
2639
2640        assert_eq!(details.fee.unwrap_or(0), 0);
2641        assert_eq!(psbt.unsigned_tx.output.len(), 1);
2642        assert_eq!(
2643            psbt.unsigned_tx.output[0].value,
2644            50_000 - details.fee.unwrap_or(0)
2645        );
2646    }
2647
2648    #[test]
2649    #[should_panic(expected = "InsufficientFunds")]
2650    fn test_create_tx_absolute_high_fee() {
2651        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2652        let addr = wallet.get_address(New).unwrap();
2653        let mut builder = wallet.build_tx();
2654        builder
2655            .drain_to(addr.script_pubkey())
2656            .drain_wallet()
2657            .fee_absolute(60_000);
2658        let (_psbt, _details) = builder.finish().unwrap();
2659    }
2660
2661    #[test]
2662    fn test_create_tx_add_change() {
2663        use super::tx_builder::TxOrdering;
2664
2665        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2666        let addr = wallet.get_address(New).unwrap();
2667        let mut builder = wallet.build_tx();
2668        builder
2669            .add_recipient(addr.script_pubkey(), 25_000)
2670            .ordering(TxOrdering::Untouched);
2671        let (psbt, details) = builder.finish().unwrap();
2672
2673        assert_eq!(psbt.unsigned_tx.output.len(), 2);
2674        assert_eq!(psbt.unsigned_tx.output[0].value, 25_000);
2675        assert_eq!(
2676            psbt.unsigned_tx.output[1].value,
2677            25_000 - details.fee.unwrap_or(0)
2678        );
2679    }
2680
2681    #[test]
2682    fn test_create_tx_skip_change_dust() {
2683        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2684        let addr = wallet.get_address(New).unwrap();
2685        let mut builder = wallet.build_tx();
2686        builder.add_recipient(addr.script_pubkey(), 49_800);
2687        let (psbt, details) = builder.finish().unwrap();
2688
2689        assert_eq!(psbt.unsigned_tx.output.len(), 1);
2690        assert_eq!(psbt.unsigned_tx.output[0].value, 49_800);
2691        assert_eq!(details.fee.unwrap_or(0), 200);
2692    }
2693
2694    #[test]
2695    #[should_panic(expected = "InsufficientFunds")]
2696    fn test_create_tx_drain_to_dust_amount() {
2697        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2698        let addr = wallet.get_address(New).unwrap();
2699        // very high fee rate, so that the only output would be below dust
2700        let mut builder = wallet.build_tx();
2701        builder
2702            .drain_to(addr.script_pubkey())
2703            .drain_wallet()
2704            .fee_rate(FeeRate::from_sat_per_vb(453.0));
2705        builder.finish().unwrap();
2706    }
2707
2708    #[test]
2709    fn test_create_tx_ordering_respected() {
2710        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2711        let addr = wallet.get_address(New).unwrap();
2712        let mut builder = wallet.build_tx();
2713        builder
2714            .add_recipient(addr.script_pubkey(), 30_000)
2715            .add_recipient(addr.script_pubkey(), 10_000)
2716            .ordering(super::tx_builder::TxOrdering::Bip69Lexicographic);
2717        let (psbt, details) = builder.finish().unwrap();
2718
2719        assert_eq!(psbt.unsigned_tx.output.len(), 3);
2720        assert_eq!(
2721            psbt.unsigned_tx.output[0].value,
2722            10_000 - details.fee.unwrap_or(0)
2723        );
2724        assert_eq!(psbt.unsigned_tx.output[1].value, 10_000);
2725        assert_eq!(psbt.unsigned_tx.output[2].value, 30_000);
2726    }
2727
2728    #[test]
2729    fn test_create_tx_default_sighash() {
2730        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2731        let addr = wallet.get_address(New).unwrap();
2732        let mut builder = wallet.build_tx();
2733        builder.add_recipient(addr.script_pubkey(), 30_000);
2734        let (psbt, _) = builder.finish().unwrap();
2735
2736        assert_eq!(psbt.inputs[0].sighash_type, None);
2737    }
2738
2739    #[test]
2740    fn test_create_tx_custom_sighash() {
2741        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
2742        let addr = wallet.get_address(New).unwrap();
2743        let mut builder = wallet.build_tx();
2744        builder
2745            .add_recipient(addr.script_pubkey(), 30_000)
2746            .sighash(bitcoin::EcdsaSighashType::Single.into());
2747        let (psbt, _) = builder.finish().unwrap();
2748
2749        assert_eq!(
2750            psbt.inputs[0].sighash_type,
2751            Some(bitcoin::EcdsaSighashType::Single.into())
2752        );
2753    }
2754
2755    #[test]
2756    fn test_create_tx_input_hd_keypaths() {
2757        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
2758        use std::str::FromStr;
2759
2760        let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
2761        let addr = wallet.get_address(New).unwrap();
2762        let mut builder = wallet.build_tx();
2763        builder.drain_to(addr.script_pubkey()).drain_wallet();
2764        let (psbt, _) = builder.finish().unwrap();
2765
2766        assert_eq!(psbt.inputs[0].bip32_derivation.len(), 1);
2767        assert_eq!(
2768            psbt.inputs[0].bip32_derivation.values().next().unwrap(),
2769            &(
2770                Fingerprint::from_str("d34db33f").unwrap(),
2771                DerivationPath::from_str("m/44'/0'/0'/0/0").unwrap()
2772            )
2773        );
2774    }
2775
2776    #[test]
2777    fn test_create_tx_output_hd_keypaths() {
2778        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
2779        use std::str::FromStr;
2780
2781        let (wallet, descriptors, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
2782        // cache some addresses
2783        wallet.get_address(New).unwrap();
2784
2785        let addr = testutils!(@external descriptors, 5);
2786        let mut builder = wallet.build_tx();
2787        builder.drain_to(addr.script_pubkey()).drain_wallet();
2788        let (psbt, _) = builder.finish().unwrap();
2789
2790        assert_eq!(psbt.outputs[0].bip32_derivation.len(), 1);
2791        assert_eq!(
2792            psbt.outputs[0].bip32_derivation.values().next().unwrap(),
2793            &(
2794                Fingerprint::from_str("d34db33f").unwrap(),
2795                DerivationPath::from_str("m/44'/0'/0'/0/5").unwrap()
2796            )
2797        );
2798    }
2799
2800    #[test]
2801    fn test_create_tx_set_redeem_script_p2sh() {
2802        use bitcoin::hashes::hex::FromHex;
2803
2804        let (wallet, _, _) =
2805            get_funded_wallet("sh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
2806        let addr = wallet.get_address(New).unwrap();
2807        let mut builder = wallet.build_tx();
2808        builder.drain_to(addr.script_pubkey()).drain_wallet();
2809        let (psbt, _) = builder.finish().unwrap();
2810
2811        assert_eq!(
2812            psbt.inputs[0].redeem_script,
2813            Some(Script::from(
2814                Vec::<u8>::from_hex(
2815                    "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
2816                )
2817                .unwrap()
2818            ))
2819        );
2820        assert_eq!(psbt.inputs[0].witness_script, None);
2821    }
2822
2823    #[test]
2824    fn test_create_tx_set_witness_script_p2wsh() {
2825        use bitcoin::hashes::hex::FromHex;
2826
2827        let (wallet, _, _) =
2828            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
2829        let addr = wallet.get_address(New).unwrap();
2830        let mut builder = wallet.build_tx();
2831        builder.drain_to(addr.script_pubkey()).drain_wallet();
2832        let (psbt, _) = builder.finish().unwrap();
2833
2834        assert_eq!(psbt.inputs[0].redeem_script, None);
2835        assert_eq!(
2836            psbt.inputs[0].witness_script,
2837            Some(Script::from(
2838                Vec::<u8>::from_hex(
2839                    "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
2840                )
2841                .unwrap()
2842            ))
2843        );
2844    }
2845
2846    #[test]
2847    fn test_create_tx_set_redeem_witness_script_p2wsh_p2sh() {
2848        use bitcoin::hashes::hex::FromHex;
2849
2850        let (wallet, _, _) =
2851            get_funded_wallet("sh(wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)))");
2852        let addr = wallet.get_address(New).unwrap();
2853        let mut builder = wallet.build_tx();
2854        builder.drain_to(addr.script_pubkey()).drain_wallet();
2855        let (psbt, _) = builder.finish().unwrap();
2856
2857        let script = Script::from(
2858            Vec::<u8>::from_hex(
2859                "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac",
2860            )
2861            .unwrap(),
2862        );
2863
2864        assert_eq!(psbt.inputs[0].redeem_script, Some(script.to_v0_p2wsh()));
2865        assert_eq!(psbt.inputs[0].witness_script, Some(script));
2866    }
2867
2868    #[test]
2869    fn test_create_tx_non_witness_utxo() {
2870        let (wallet, _, _) =
2871            get_funded_wallet("sh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
2872        let addr = wallet.get_address(New).unwrap();
2873        let mut builder = wallet.build_tx();
2874        builder.drain_to(addr.script_pubkey()).drain_wallet();
2875        let (psbt, _) = builder.finish().unwrap();
2876
2877        assert!(psbt.inputs[0].non_witness_utxo.is_some());
2878        assert!(psbt.inputs[0].witness_utxo.is_none());
2879    }
2880
2881    #[test]
2882    fn test_create_tx_only_witness_utxo() {
2883        let (wallet, _, _) =
2884            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
2885        let addr = wallet.get_address(New).unwrap();
2886        let mut builder = wallet.build_tx();
2887        builder
2888            .drain_to(addr.script_pubkey())
2889            .only_witness_utxo()
2890            .drain_wallet();
2891        let (psbt, _) = builder.finish().unwrap();
2892
2893        assert!(psbt.inputs[0].non_witness_utxo.is_none());
2894        assert!(psbt.inputs[0].witness_utxo.is_some());
2895    }
2896
2897    #[test]
2898    fn test_create_tx_shwpkh_has_witness_utxo() {
2899        let (wallet, _, _) =
2900            get_funded_wallet("sh(wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
2901        let addr = wallet.get_address(New).unwrap();
2902        let mut builder = wallet.build_tx();
2903        builder.drain_to(addr.script_pubkey()).drain_wallet();
2904        let (psbt, _) = builder.finish().unwrap();
2905
2906        assert!(psbt.inputs[0].witness_utxo.is_some());
2907    }
2908
2909    #[test]
2910    fn test_create_tx_both_non_witness_utxo_and_witness_utxo_default() {
2911        let (wallet, _, _) =
2912            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
2913        let addr = wallet.get_address(New).unwrap();
2914        let mut builder = wallet.build_tx();
2915        builder.drain_to(addr.script_pubkey()).drain_wallet();
2916        let (psbt, _) = builder.finish().unwrap();
2917
2918        assert!(psbt.inputs[0].non_witness_utxo.is_some());
2919        assert!(psbt.inputs[0].witness_utxo.is_some());
2920    }
2921
2922    #[test]
2923    fn test_create_tx_add_utxo() {
2924        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
2925        let small_output_txid = crate::populate_test_db!(
2926            wallet.database.borrow_mut(),
2927            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
2928            Some(100),
2929        );
2930
2931        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
2932        let mut builder = wallet.build_tx();
2933        builder
2934            .add_recipient(addr.script_pubkey(), 30_000)
2935            .add_utxo(OutPoint {
2936                txid: small_output_txid,
2937                vout: 0,
2938            })
2939            .unwrap();
2940        let (psbt, details) = builder.finish().unwrap();
2941
2942        assert_eq!(
2943            psbt.unsigned_tx.input.len(),
2944            2,
2945            "should add an additional input since 25_000 < 30_000"
2946        );
2947        assert_eq!(details.sent, 75_000, "total should be sum of both inputs");
2948    }
2949
2950    #[test]
2951    #[should_panic(expected = "InsufficientFunds")]
2952    fn test_create_tx_manually_selected_insufficient() {
2953        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
2954        let small_output_txid = crate::populate_test_db!(
2955            wallet.database.borrow_mut(),
2956            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
2957            Some(100),
2958        );
2959
2960        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
2961        let mut builder = wallet.build_tx();
2962        builder
2963            .add_recipient(addr.script_pubkey(), 30_000)
2964            .add_utxo(OutPoint {
2965                txid: small_output_txid,
2966                vout: 0,
2967            })
2968            .unwrap()
2969            .manually_selected_only();
2970        builder.finish().unwrap();
2971    }
2972
2973    #[test]
2974    #[should_panic(expected = "SpendingPolicyRequired(External)")]
2975    fn test_create_tx_policy_path_required() {
2976        let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
2977
2978        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
2979        let mut builder = wallet.build_tx();
2980        builder.add_recipient(addr.script_pubkey(), 30_000);
2981        builder.finish().unwrap();
2982    }
2983
2984    #[test]
2985    fn test_create_tx_policy_path_no_csv() {
2986        let descriptors = testutils!(@descriptors (get_test_wpkh()));
2987        let wallet = Wallet::new(
2988            &descriptors.0,
2989            None,
2990            Network::Regtest,
2991            AnyDatabase::Memory(MemoryDatabase::new()),
2992        )
2993        .unwrap();
2994
2995        let tx_meta = testutils! {
2996                @tx ( (@external descriptors, 0) => 50_000 )
2997        };
2998
2999        // Add the transaction to our db, but do not sync the db. Unsynced db
3000        // should trigger the default sequence value for a new transaction as 0xFFFFFFFF
3001        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
3002
3003        let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
3004        let root_id = external_policy.id;
3005        // child #0 is just the key "A"
3006        let path = vec![(root_id, vec![0])].into_iter().collect();
3007
3008        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3009        let mut builder = wallet.build_tx();
3010        builder
3011            .add_recipient(addr.script_pubkey(), 30_000)
3012            .policy_path(path, KeychainKind::External);
3013        let (psbt, _) = builder.finish().unwrap();
3014
3015        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFF));
3016    }
3017
3018    #[test]
3019    fn test_create_tx_policy_path_use_csv() {
3020        let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
3021
3022        let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
3023        let root_id = external_policy.id;
3024        // child #1 is or(pk(B),older(144))
3025        let path = vec![(root_id, vec![1])].into_iter().collect();
3026
3027        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3028        let mut builder = wallet.build_tx();
3029        builder
3030            .add_recipient(addr.script_pubkey(), 30_000)
3031            .policy_path(path, KeychainKind::External);
3032        let (psbt, _) = builder.finish().unwrap();
3033
3034        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(144));
3035    }
3036
3037    #[test]
3038    fn test_create_tx_policy_path_ignored_subtree_with_csv() {
3039        let (wallet, _, _) = get_funded_wallet("wsh(or_d(pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu),or_i(and_v(v:pkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),older(30)),and_v(v:pkh(cMnkdebixpXMPfkcNEjjGin7s94hiehAH4mLbYkZoh9KSiNNmqC8),older(90)))))");
3040
3041        let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
3042        let root_id = external_policy.id;
3043        // child #0 is pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)
3044        let path = vec![(root_id, vec![0])].into_iter().collect();
3045
3046        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3047        let mut builder = wallet.build_tx();
3048        builder
3049            .add_recipient(addr.script_pubkey(), 30_000)
3050            .policy_path(path, KeychainKind::External);
3051        let (psbt, _) = builder.finish().unwrap();
3052
3053        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFE));
3054    }
3055
3056    #[test]
3057    fn test_create_tx_global_xpubs_with_origin() {
3058        use bitcoin::hashes::hex::FromHex;
3059        use bitcoin::util::bip32;
3060
3061        let (wallet, _, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
3062        let addr = wallet.get_address(New).unwrap();
3063        let mut builder = wallet.build_tx();
3064        builder
3065            .add_recipient(addr.script_pubkey(), 25_000)
3066            .add_global_xpubs();
3067        let (psbt, _) = builder.finish().unwrap();
3068
3069        let key = bip32::ExtendedPubKey::from_str("tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3").unwrap();
3070        let fingerprint = bip32::Fingerprint::from_hex("73756c7f").unwrap();
3071        let path = bip32::DerivationPath::from_str("m/48'/0'/0'/2'").unwrap();
3072
3073        assert_eq!(psbt.xpub.len(), 1);
3074        assert_eq!(psbt.xpub.get(&key), Some(&(fingerprint, path)));
3075    }
3076
3077    #[test]
3078    fn test_add_foreign_utxo() {
3079        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
3080        let (wallet2, _, _) =
3081            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
3082
3083        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3084        let utxo = wallet2.list_unspent().unwrap().remove(0);
3085        let foreign_utxo_satisfaction = wallet2
3086            .get_descriptor_for_keychain(KeychainKind::External)
3087            .max_satisfaction_weight()
3088            .unwrap();
3089
3090        let psbt_input = psbt::Input {
3091            witness_utxo: Some(utxo.txout.clone()),
3092            ..Default::default()
3093        };
3094
3095        let mut builder = wallet1.build_tx();
3096        builder
3097            .add_recipient(addr.script_pubkey(), 60_000)
3098            .only_witness_utxo()
3099            .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
3100            .unwrap();
3101        let (mut psbt, details) = builder.finish().unwrap();
3102
3103        assert_eq!(
3104            details.sent - details.received,
3105            10_000 + details.fee.unwrap_or(0),
3106            "we should have only net spent ~10_000"
3107        );
3108
3109        assert!(
3110            psbt.unsigned_tx
3111                .input
3112                .iter()
3113                .any(|input| input.previous_output == utxo.outpoint),
3114            "foreign_utxo should be in there"
3115        );
3116
3117        let finished = wallet1
3118            .sign(
3119                &mut psbt,
3120                SignOptions {
3121                    trust_witness_utxo: true,
3122                    ..Default::default()
3123                },
3124            )
3125            .unwrap();
3126
3127        assert!(
3128            !finished,
3129            "only one of the inputs should have been signed so far"
3130        );
3131
3132        let finished = wallet2
3133            .sign(
3134                &mut psbt,
3135                SignOptions {
3136                    trust_witness_utxo: true,
3137                    ..Default::default()
3138                },
3139            )
3140            .unwrap();
3141        assert!(finished, "all the inputs should have been signed now");
3142    }
3143
3144    #[test]
3145    #[should_panic(expected = "Generic(\"Foreign utxo missing witness_utxo or non_witness_utxo\")")]
3146    fn test_add_foreign_utxo_invalid_psbt_input() {
3147        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3148        let mut builder = wallet.build_tx();
3149        let outpoint = wallet.list_unspent().unwrap()[0].outpoint;
3150        let foreign_utxo_satisfaction = wallet
3151            .get_descriptor_for_keychain(KeychainKind::External)
3152            .max_satisfaction_weight()
3153            .unwrap();
3154        builder
3155            .add_foreign_utxo(outpoint, psbt::Input::default(), foreign_utxo_satisfaction)
3156            .unwrap();
3157    }
3158
3159    #[test]
3160    fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
3161        let (wallet1, _, txid1) = get_funded_wallet(get_test_wpkh());
3162        let (wallet2, _, txid2) =
3163            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
3164
3165        let utxo2 = wallet2.list_unspent().unwrap().remove(0);
3166        let tx1 = wallet1
3167            .database
3168            .borrow()
3169            .get_tx(&txid1, true)
3170            .unwrap()
3171            .unwrap()
3172            .transaction
3173            .unwrap();
3174        let tx2 = wallet2
3175            .database
3176            .borrow()
3177            .get_tx(&txid2, true)
3178            .unwrap()
3179            .unwrap()
3180            .transaction
3181            .unwrap();
3182
3183        let satisfaction_weight = wallet2
3184            .get_descriptor_for_keychain(KeychainKind::External)
3185            .max_satisfaction_weight()
3186            .unwrap();
3187
3188        let mut builder = wallet1.build_tx();
3189        assert!(
3190            builder
3191                .add_foreign_utxo(
3192                    utxo2.outpoint,
3193                    psbt::Input {
3194                        non_witness_utxo: Some(tx1),
3195                        ..Default::default()
3196                    },
3197                    satisfaction_weight
3198                )
3199                .is_err(),
3200            "should fail when outpoint doesn't match psbt_input"
3201        );
3202        assert!(
3203            builder
3204                .add_foreign_utxo(
3205                    utxo2.outpoint,
3206                    psbt::Input {
3207                        non_witness_utxo: Some(tx2),
3208                        ..Default::default()
3209                    },
3210                    satisfaction_weight
3211                )
3212                .is_ok(),
3213            "shoulld be ok when outpoint does match psbt_input"
3214        );
3215    }
3216
3217    #[test]
3218    fn test_add_foreign_utxo_only_witness_utxo() {
3219        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
3220        let (wallet2, _, txid2) =
3221            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
3222        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3223        let utxo2 = wallet2.list_unspent().unwrap().remove(0);
3224
3225        let satisfaction_weight = wallet2
3226            .get_descriptor_for_keychain(KeychainKind::External)
3227            .max_satisfaction_weight()
3228            .unwrap();
3229
3230        let mut builder = wallet1.build_tx();
3231        builder.add_recipient(addr.script_pubkey(), 60_000);
3232
3233        {
3234            let mut builder = builder.clone();
3235            let psbt_input = psbt::Input {
3236                witness_utxo: Some(utxo2.txout.clone()),
3237                ..Default::default()
3238            };
3239            builder
3240                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
3241                .unwrap();
3242            assert!(
3243                builder.finish().is_err(),
3244                "psbt_input with witness_utxo should fail with only witness_utxo"
3245            );
3246        }
3247
3248        {
3249            let mut builder = builder.clone();
3250            let psbt_input = psbt::Input {
3251                witness_utxo: Some(utxo2.txout.clone()),
3252                ..Default::default()
3253            };
3254            builder
3255                .only_witness_utxo()
3256                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
3257                .unwrap();
3258            assert!(
3259                builder.finish().is_ok(),
3260                "psbt_input with just witness_utxo should succeed when `only_witness_utxo` is enabled"
3261            );
3262        }
3263
3264        {
3265            let mut builder = builder.clone();
3266            let tx2 = wallet2
3267                .database
3268                .borrow()
3269                .get_tx(&txid2, true)
3270                .unwrap()
3271                .unwrap()
3272                .transaction
3273                .unwrap();
3274            let psbt_input = psbt::Input {
3275                non_witness_utxo: Some(tx2),
3276                ..Default::default()
3277            };
3278            builder
3279                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
3280                .unwrap();
3281            assert!(
3282                builder.finish().is_ok(),
3283                "psbt_input with non_witness_utxo should succeed by default"
3284            );
3285        }
3286    }
3287
3288    #[test]
3289    fn test_get_psbt_input() {
3290        // this should grab a known good utxo and set the input
3291        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3292        for utxo in wallet.list_unspent().unwrap() {
3293            let psbt_input = wallet.get_psbt_input(utxo, None, false).unwrap();
3294            assert!(psbt_input.witness_utxo.is_some() || psbt_input.non_witness_utxo.is_some());
3295        }
3296    }
3297
3298    #[test]
3299    #[should_panic(
3300        expected = "MissingKeyOrigin(\"tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3\")"
3301    )]
3302    fn test_create_tx_global_xpubs_origin_missing() {
3303        let (wallet, _, _) = get_funded_wallet("wpkh(tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
3304        let addr = wallet.get_address(New).unwrap();
3305        let mut builder = wallet.build_tx();
3306        builder
3307            .add_recipient(addr.script_pubkey(), 25_000)
3308            .add_global_xpubs();
3309        builder.finish().unwrap();
3310    }
3311
3312    #[test]
3313    fn test_create_tx_global_xpubs_master_without_origin() {
3314        use bitcoin::hashes::hex::FromHex;
3315        use bitcoin::util::bip32;
3316
3317        let (wallet, _, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
3318        let addr = wallet.get_address(New).unwrap();
3319        let mut builder = wallet.build_tx();
3320        builder
3321            .add_recipient(addr.script_pubkey(), 25_000)
3322            .add_global_xpubs();
3323        let (psbt, _) = builder.finish().unwrap();
3324
3325        let key = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL").unwrap();
3326        let fingerprint = bip32::Fingerprint::from_hex("997a323b").unwrap();
3327
3328        assert_eq!(psbt.xpub.len(), 1);
3329        assert_eq!(
3330            psbt.xpub.get(&key),
3331            Some(&(fingerprint, bip32::DerivationPath::default()))
3332        );
3333    }
3334
3335    #[test]
3336    #[should_panic(expected = "IrreplaceableTransaction")]
3337    fn test_bump_fee_irreplaceable_tx() {
3338        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3339        let addr = wallet.get_address(New).unwrap();
3340        let mut builder = wallet.build_tx();
3341        builder.add_recipient(addr.script_pubkey(), 25_000);
3342        let (psbt, mut details) = builder.finish().unwrap();
3343
3344        let tx = psbt.extract_tx();
3345        let txid = tx.txid();
3346        // skip saving the utxos, we know they can't be used anyways
3347        details.transaction = Some(tx);
3348        wallet.database.borrow_mut().set_tx(&details).unwrap();
3349
3350        wallet.build_fee_bump(txid).unwrap().finish().unwrap();
3351    }
3352
3353    #[test]
3354    #[should_panic(expected = "TransactionConfirmed")]
3355    fn test_bump_fee_confirmed_tx() {
3356        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3357        let addr = wallet.get_address(New).unwrap();
3358        let mut builder = wallet.build_tx();
3359        builder.add_recipient(addr.script_pubkey(), 25_000);
3360        let (psbt, mut details) = builder.finish().unwrap();
3361
3362        let tx = psbt.extract_tx();
3363        let txid = tx.txid();
3364        // skip saving the utxos, we know they can't be used anyways
3365        details.transaction = Some(tx);
3366        details.confirmation_time = Some(BlockTime {
3367            timestamp: 12345678,
3368            height: 42,
3369        });
3370        wallet.database.borrow_mut().set_tx(&details).unwrap();
3371
3372        wallet.build_fee_bump(txid).unwrap().finish().unwrap();
3373    }
3374
3375    #[test]
3376    #[should_panic(expected = "FeeRateTooLow")]
3377    fn test_bump_fee_low_fee_rate() {
3378        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3379        let addr = wallet.get_address(New).unwrap();
3380        let mut builder = wallet.build_tx();
3381        builder
3382            .add_recipient(addr.script_pubkey(), 25_000)
3383            .enable_rbf();
3384        let (psbt, mut details) = builder.finish().unwrap();
3385
3386        let tx = psbt.extract_tx();
3387        let txid = tx.txid();
3388        // skip saving the utxos, we know they can't be used anyways
3389        details.transaction = Some(tx);
3390        wallet.database.borrow_mut().set_tx(&details).unwrap();
3391
3392        let mut builder = wallet.build_fee_bump(txid).unwrap();
3393        builder.fee_rate(FeeRate::from_sat_per_vb(1.0));
3394        builder.finish().unwrap();
3395    }
3396
3397    #[test]
3398    #[should_panic(expected = "FeeTooLow")]
3399    fn test_bump_fee_low_abs() {
3400        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3401        let addr = wallet.get_address(New).unwrap();
3402        let mut builder = wallet.build_tx();
3403        builder
3404            .add_recipient(addr.script_pubkey(), 25_000)
3405            .enable_rbf();
3406        let (psbt, mut details) = builder.finish().unwrap();
3407
3408        let tx = psbt.extract_tx();
3409        let txid = tx.txid();
3410        // skip saving the utxos, we know they can't be used anyways
3411        details.transaction = Some(tx);
3412        wallet.database.borrow_mut().set_tx(&details).unwrap();
3413
3414        let mut builder = wallet.build_fee_bump(txid).unwrap();
3415        builder.fee_absolute(10);
3416        builder.finish().unwrap();
3417    }
3418
3419    #[test]
3420    #[should_panic(expected = "FeeTooLow")]
3421    fn test_bump_fee_zero_abs() {
3422        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3423        let addr = wallet.get_address(New).unwrap();
3424        let mut builder = wallet.build_tx();
3425        builder
3426            .add_recipient(addr.script_pubkey(), 25_000)
3427            .enable_rbf();
3428        let (psbt, mut details) = builder.finish().unwrap();
3429
3430        let tx = psbt.extract_tx();
3431        let txid = tx.txid();
3432        // skip saving the utxos, we know they can't be used anyways
3433        details.transaction = Some(tx);
3434        wallet.database.borrow_mut().set_tx(&details).unwrap();
3435
3436        let mut builder = wallet.build_fee_bump(txid).unwrap();
3437        builder.fee_absolute(0);
3438        builder.finish().unwrap();
3439    }
3440
3441    #[test]
3442    fn test_bump_fee_reduce_change() {
3443        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3444        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3445        let mut builder = wallet.build_tx();
3446        builder
3447            .add_recipient(addr.script_pubkey(), 25_000)
3448            .enable_rbf();
3449        let (psbt, mut original_details) = builder.finish().unwrap();
3450        let mut tx = psbt.extract_tx();
3451        let txid = tx.txid();
3452        // skip saving the new utxos, we know they can't be used anyways
3453        for txin in &mut tx.input {
3454            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3455            wallet
3456                .database
3457                .borrow_mut()
3458                .del_utxo(&txin.previous_output)
3459                .unwrap();
3460        }
3461        original_details.transaction = Some(tx);
3462        wallet
3463            .database
3464            .borrow_mut()
3465            .set_tx(&original_details)
3466            .unwrap();
3467
3468        let mut builder = wallet.build_fee_bump(txid).unwrap();
3469        builder.fee_rate(FeeRate::from_sat_per_vb(2.5)).enable_rbf();
3470        let (psbt, details) = builder.finish().unwrap();
3471
3472        assert_eq!(details.sent, original_details.sent);
3473        assert_eq!(
3474            details.received + details.fee.unwrap_or(0),
3475            original_details.received + original_details.fee.unwrap_or(0)
3476        );
3477        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
3478
3479        let tx = &psbt.unsigned_tx;
3480        assert_eq!(tx.output.len(), 2);
3481        assert_eq!(
3482            tx.output
3483                .iter()
3484                .find(|txout| txout.script_pubkey == addr.script_pubkey())
3485                .unwrap()
3486                .value,
3487            25_000
3488        );
3489        assert_eq!(
3490            tx.output
3491                .iter()
3492                .find(|txout| txout.script_pubkey != addr.script_pubkey())
3493                .unwrap()
3494                .value,
3495            details.received
3496        );
3497
3498        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(2.5), @add_signature);
3499    }
3500
3501    #[test]
3502    fn test_bump_fee_absolute_reduce_change() {
3503        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3504        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3505        let mut builder = wallet.build_tx();
3506        builder
3507            .add_recipient(addr.script_pubkey(), 25_000)
3508            .enable_rbf();
3509        let (psbt, mut original_details) = builder.finish().unwrap();
3510        let mut tx = psbt.extract_tx();
3511        let txid = tx.txid();
3512        // skip saving the new utxos, we know they can't be used anyways
3513        for txin in &mut tx.input {
3514            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3515            wallet
3516                .database
3517                .borrow_mut()
3518                .del_utxo(&txin.previous_output)
3519                .unwrap();
3520        }
3521        original_details.transaction = Some(tx);
3522        wallet
3523            .database
3524            .borrow_mut()
3525            .set_tx(&original_details)
3526            .unwrap();
3527
3528        let mut builder = wallet.build_fee_bump(txid).unwrap();
3529        builder.fee_absolute(200);
3530        builder.enable_rbf();
3531        let (psbt, details) = builder.finish().unwrap();
3532
3533        assert_eq!(details.sent, original_details.sent);
3534        assert_eq!(
3535            details.received + details.fee.unwrap_or(0),
3536            original_details.received + original_details.fee.unwrap_or(0)
3537        );
3538        assert!(
3539            details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0),
3540            "{} > {}",
3541            details.fee.unwrap_or(0),
3542            original_details.fee.unwrap_or(0)
3543        );
3544
3545        let tx = &psbt.unsigned_tx;
3546        assert_eq!(tx.output.len(), 2);
3547        assert_eq!(
3548            tx.output
3549                .iter()
3550                .find(|txout| txout.script_pubkey == addr.script_pubkey())
3551                .unwrap()
3552                .value,
3553            25_000
3554        );
3555        assert_eq!(
3556            tx.output
3557                .iter()
3558                .find(|txout| txout.script_pubkey != addr.script_pubkey())
3559                .unwrap()
3560                .value,
3561            details.received
3562        );
3563
3564        assert_eq!(details.fee.unwrap_or(0), 200);
3565    }
3566
3567    #[test]
3568    fn test_bump_fee_reduce_single_recipient() {
3569        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3570        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3571        let mut builder = wallet.build_tx();
3572        builder
3573            .drain_to(addr.script_pubkey())
3574            .drain_wallet()
3575            .enable_rbf();
3576        let (psbt, mut original_details) = builder.finish().unwrap();
3577        let mut tx = psbt.extract_tx();
3578        let txid = tx.txid();
3579        for txin in &mut tx.input {
3580            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3581            wallet
3582                .database
3583                .borrow_mut()
3584                .del_utxo(&txin.previous_output)
3585                .unwrap();
3586        }
3587        original_details.transaction = Some(tx);
3588        wallet
3589            .database
3590            .borrow_mut()
3591            .set_tx(&original_details)
3592            .unwrap();
3593
3594        let mut builder = wallet.build_fee_bump(txid).unwrap();
3595        builder
3596            .fee_rate(FeeRate::from_sat_per_vb(2.5))
3597            .allow_shrinking(addr.script_pubkey())
3598            .unwrap();
3599        let (psbt, details) = builder.finish().unwrap();
3600
3601        assert_eq!(details.sent, original_details.sent);
3602        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
3603
3604        let tx = &psbt.unsigned_tx;
3605        assert_eq!(tx.output.len(), 1);
3606        assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
3607
3608        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(2.5), @add_signature);
3609    }
3610
3611    #[test]
3612    fn test_bump_fee_absolute_reduce_single_recipient() {
3613        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
3614        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3615        let mut builder = wallet.build_tx();
3616        builder
3617            .drain_to(addr.script_pubkey())
3618            .drain_wallet()
3619            .enable_rbf();
3620        let (psbt, mut original_details) = builder.finish().unwrap();
3621        let mut tx = psbt.extract_tx();
3622        let txid = tx.txid();
3623        for txin in &mut tx.input {
3624            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3625            wallet
3626                .database
3627                .borrow_mut()
3628                .del_utxo(&txin.previous_output)
3629                .unwrap();
3630        }
3631        original_details.transaction = Some(tx);
3632        wallet
3633            .database
3634            .borrow_mut()
3635            .set_tx(&original_details)
3636            .unwrap();
3637
3638        let mut builder = wallet.build_fee_bump(txid).unwrap();
3639        builder
3640            .allow_shrinking(addr.script_pubkey())
3641            .unwrap()
3642            .fee_absolute(300);
3643        let (psbt, details) = builder.finish().unwrap();
3644
3645        assert_eq!(details.sent, original_details.sent);
3646        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
3647
3648        let tx = &psbt.unsigned_tx;
3649        assert_eq!(tx.output.len(), 1);
3650        assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
3651
3652        assert_eq!(details.fee.unwrap_or(0), 300);
3653    }
3654
3655    #[test]
3656    fn test_bump_fee_drain_wallet() {
3657        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
3658        // receive an extra tx so that our wallet has two utxos.
3659        let incoming_txid = crate::populate_test_db!(
3660            wallet.database.borrow_mut(),
3661            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
3662            Some(100),
3663        );
3664        let outpoint = OutPoint {
3665            txid: incoming_txid,
3666            vout: 0,
3667        };
3668        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3669        let mut builder = wallet.build_tx();
3670        builder
3671            .drain_to(addr.script_pubkey())
3672            .add_utxo(outpoint)
3673            .unwrap()
3674            .manually_selected_only()
3675            .enable_rbf();
3676        let (psbt, mut original_details) = builder.finish().unwrap();
3677        let mut tx = psbt.extract_tx();
3678        let txid = tx.txid();
3679        for txin in &mut tx.input {
3680            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3681            wallet
3682                .database
3683                .borrow_mut()
3684                .del_utxo(&txin.previous_output)
3685                .unwrap();
3686        }
3687        original_details.transaction = Some(tx);
3688        wallet
3689            .database
3690            .borrow_mut()
3691            .set_tx(&original_details)
3692            .unwrap();
3693        assert_eq!(original_details.sent, 25_000);
3694
3695        // for the new feerate, it should be enough to reduce the output, but since we specify
3696        // `drain_wallet` we expect to spend everything
3697        let mut builder = wallet.build_fee_bump(txid).unwrap();
3698        builder
3699            .drain_wallet()
3700            .allow_shrinking(addr.script_pubkey())
3701            .unwrap()
3702            .fee_rate(FeeRate::from_sat_per_vb(5.0));
3703        let (_, details) = builder.finish().unwrap();
3704        assert_eq!(details.sent, 75_000);
3705    }
3706
3707    #[test]
3708    #[should_panic(expected = "InsufficientFunds")]
3709    fn test_bump_fee_remove_output_manually_selected_only() {
3710        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
3711        // receive an extra tx so that our wallet has two utxos. then we manually pick only one of
3712        // them, and make sure that `bump_fee` doesn't try to add more. This fails because we've
3713        // told the wallet it's not allowed to add more inputs AND it can't reduce the value of the
3714        // existing output. In other words, bump_fee + manually_selected_only is always an error
3715        // unless you've also set "allow_shrinking" OR there is a change output.
3716        let incoming_txid = crate::populate_test_db!(
3717            wallet.database.borrow_mut(),
3718            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
3719            Some(100),
3720        );
3721        let outpoint = OutPoint {
3722            txid: incoming_txid,
3723            vout: 0,
3724        };
3725        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3726        let mut builder = wallet.build_tx();
3727        builder
3728            .drain_to(addr.script_pubkey())
3729            .add_utxo(outpoint)
3730            .unwrap()
3731            .manually_selected_only()
3732            .enable_rbf();
3733        let (psbt, mut original_details) = builder.finish().unwrap();
3734        let mut tx = psbt.extract_tx();
3735        let txid = tx.txid();
3736        for txin in &mut tx.input {
3737            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3738            wallet
3739                .database
3740                .borrow_mut()
3741                .del_utxo(&txin.previous_output)
3742                .unwrap();
3743        }
3744        original_details.transaction = Some(tx);
3745        wallet
3746            .database
3747            .borrow_mut()
3748            .set_tx(&original_details)
3749            .unwrap();
3750        assert_eq!(original_details.sent, 25_000);
3751
3752        let mut builder = wallet.build_fee_bump(txid).unwrap();
3753        builder
3754            .manually_selected_only()
3755            .fee_rate(FeeRate::from_sat_per_vb(255.0));
3756        builder.finish().unwrap();
3757    }
3758
3759    #[test]
3760    fn test_bump_fee_add_input() {
3761        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
3762        crate::populate_test_db!(
3763            wallet.database.borrow_mut(),
3764            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
3765            Some(100),
3766        );
3767
3768        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3769        let mut builder = wallet.build_tx();
3770        builder
3771            .add_recipient(addr.script_pubkey(), 45_000)
3772            .enable_rbf();
3773        let (psbt, mut original_details) = builder.finish().unwrap();
3774        let mut tx = psbt.extract_tx();
3775        let txid = tx.txid();
3776        // skip saving the new utxos, we know they can't be used anyways
3777        for txin in &mut tx.input {
3778            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3779            wallet
3780                .database
3781                .borrow_mut()
3782                .del_utxo(&txin.previous_output)
3783                .unwrap();
3784        }
3785        original_details.transaction = Some(tx);
3786        wallet
3787            .database
3788            .borrow_mut()
3789            .set_tx(&original_details)
3790            .unwrap();
3791
3792        let mut builder = wallet.build_fee_bump(txid).unwrap();
3793        builder.fee_rate(FeeRate::from_sat_per_vb(50.0));
3794        let (psbt, details) = builder.finish().unwrap();
3795
3796        assert_eq!(details.sent, original_details.sent + 25_000);
3797        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
3798
3799        let tx = &psbt.unsigned_tx;
3800        assert_eq!(tx.input.len(), 2);
3801        assert_eq!(tx.output.len(), 2);
3802        assert_eq!(
3803            tx.output
3804                .iter()
3805                .find(|txout| txout.script_pubkey == addr.script_pubkey())
3806                .unwrap()
3807                .value,
3808            45_000
3809        );
3810        assert_eq!(
3811            tx.output
3812                .iter()
3813                .find(|txout| txout.script_pubkey != addr.script_pubkey())
3814                .unwrap()
3815                .value,
3816            details.received
3817        );
3818
3819        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(50.0), @add_signature);
3820    }
3821
3822    #[test]
3823    fn test_bump_fee_absolute_add_input() {
3824        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
3825        crate::populate_test_db!(
3826            wallet.database.borrow_mut(),
3827            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
3828            Some(100),
3829        );
3830
3831        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3832        let mut builder = wallet.build_tx();
3833        builder
3834            .add_recipient(addr.script_pubkey(), 45_000)
3835            .enable_rbf();
3836        let (psbt, mut original_details) = builder.finish().unwrap();
3837        let mut tx = psbt.extract_tx();
3838        let txid = tx.txid();
3839        // skip saving the new utxos, we know they can't be used anyways
3840        for txin in &mut tx.input {
3841            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3842            wallet
3843                .database
3844                .borrow_mut()
3845                .del_utxo(&txin.previous_output)
3846                .unwrap();
3847        }
3848        original_details.transaction = Some(tx);
3849        wallet
3850            .database
3851            .borrow_mut()
3852            .set_tx(&original_details)
3853            .unwrap();
3854
3855        let mut builder = wallet.build_fee_bump(txid).unwrap();
3856        builder.fee_absolute(6_000);
3857        let (psbt, details) = builder.finish().unwrap();
3858
3859        assert_eq!(details.sent, original_details.sent + 25_000);
3860        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
3861
3862        let tx = &psbt.unsigned_tx;
3863        assert_eq!(tx.input.len(), 2);
3864        assert_eq!(tx.output.len(), 2);
3865        assert_eq!(
3866            tx.output
3867                .iter()
3868                .find(|txout| txout.script_pubkey == addr.script_pubkey())
3869                .unwrap()
3870                .value,
3871            45_000
3872        );
3873        assert_eq!(
3874            tx.output
3875                .iter()
3876                .find(|txout| txout.script_pubkey != addr.script_pubkey())
3877                .unwrap()
3878                .value,
3879            details.received
3880        );
3881
3882        assert_eq!(details.fee.unwrap_or(0), 6_000);
3883    }
3884
3885    #[test]
3886    fn test_bump_fee_no_change_add_input_and_change() {
3887        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
3888        let incoming_txid = crate::populate_test_db!(
3889            wallet.database.borrow_mut(),
3890            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
3891            Some(100),
3892        );
3893
3894        // initially make a tx without change by using `drain_to`
3895        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3896        let mut builder = wallet.build_tx();
3897        builder
3898            .drain_to(addr.script_pubkey())
3899            .add_utxo(OutPoint {
3900                txid: incoming_txid,
3901                vout: 0,
3902            })
3903            .unwrap()
3904            .manually_selected_only()
3905            .enable_rbf();
3906        let (psbt, mut original_details) = builder.finish().unwrap();
3907
3908        let mut tx = psbt.extract_tx();
3909        let txid = tx.txid();
3910        // skip saving the new utxos, we know they can't be used anyways
3911        for txin in &mut tx.input {
3912            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3913            wallet
3914                .database
3915                .borrow_mut()
3916                .del_utxo(&txin.previous_output)
3917                .unwrap();
3918        }
3919        original_details.transaction = Some(tx);
3920        wallet
3921            .database
3922            .borrow_mut()
3923            .set_tx(&original_details)
3924            .unwrap();
3925
3926        // now bump the fees without using `allow_shrinking`. the wallet should add an
3927        // extra input and a change output, and leave the original output untouched
3928        let mut builder = wallet.build_fee_bump(txid).unwrap();
3929        builder.fee_rate(FeeRate::from_sat_per_vb(50.0));
3930        let (psbt, details) = builder.finish().unwrap();
3931
3932        let original_send_all_amount = original_details.sent - original_details.fee.unwrap_or(0);
3933        assert_eq!(details.sent, original_details.sent + 50_000);
3934        assert_eq!(
3935            details.received,
3936            75_000 - original_send_all_amount - details.fee.unwrap_or(0)
3937        );
3938
3939        let tx = &psbt.unsigned_tx;
3940        assert_eq!(tx.input.len(), 2);
3941        assert_eq!(tx.output.len(), 2);
3942        assert_eq!(
3943            tx.output
3944                .iter()
3945                .find(|txout| txout.script_pubkey == addr.script_pubkey())
3946                .unwrap()
3947                .value,
3948            original_send_all_amount
3949        );
3950        assert_eq!(
3951            tx.output
3952                .iter()
3953                .find(|txout| txout.script_pubkey != addr.script_pubkey())
3954                .unwrap()
3955                .value,
3956            75_000 - original_send_all_amount - details.fee.unwrap_or(0)
3957        );
3958
3959        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(50.0), @add_signature);
3960    }
3961
3962    #[test]
3963    fn test_bump_fee_add_input_change_dust() {
3964        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
3965        crate::populate_test_db!(
3966            wallet.database.borrow_mut(),
3967            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
3968            Some(100),
3969        );
3970
3971        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
3972        let mut builder = wallet.build_tx();
3973        builder
3974            .add_recipient(addr.script_pubkey(), 45_000)
3975            .enable_rbf();
3976        let (psbt, mut original_details) = builder.finish().unwrap();
3977        let mut tx = psbt.extract_tx();
3978        assert_eq!(tx.input.len(), 1);
3979        assert_eq!(tx.output.len(), 2);
3980        let txid = tx.txid();
3981        // skip saving the new utxos, we know they can't be used anyways
3982        for txin in &mut tx.input {
3983            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
3984            wallet
3985                .database
3986                .borrow_mut()
3987                .del_utxo(&txin.previous_output)
3988                .unwrap();
3989        }
3990        let original_tx_weight = tx.weight();
3991        original_details.transaction = Some(tx);
3992        wallet
3993            .database
3994            .borrow_mut()
3995            .set_tx(&original_details)
3996            .unwrap();
3997
3998        let mut builder = wallet.build_fee_bump(txid).unwrap();
3999        // We set a fee high enough that during rbf we are forced to add
4000        // a new input and also that we have to remove the change
4001        // that we had previously
4002
4003        // We calculate the new weight as:
4004        //   original weight
4005        // + extra input weight: 160 WU = (32 (prevout) + 4 (vout) + 4 (nsequence)) * 4
4006        // + input satisfaction weight: 112 WU = 106 (witness) + 2 (witness len) + (1 (script len)) * 4
4007        // - change output weight: 124 WU = (8 (value) + 1 (script len) + 22 (script)) * 4
4008        let new_tx_weight = original_tx_weight + 160 + 112 - 124;
4009        // two inputs (50k, 25k) and one output (45k) - epsilon
4010        // We use epsilon here to avoid asking for a slightly too high feerate
4011        let fee_abs = 50_000 + 25_000 - 45_000 - 10;
4012        builder.fee_rate(FeeRate::from_wu(fee_abs, new_tx_weight));
4013        let (psbt, details) = builder.finish().unwrap();
4014
4015        assert_eq!(
4016            original_details.received,
4017            5_000 - original_details.fee.unwrap_or(0)
4018        );
4019
4020        assert_eq!(details.sent, original_details.sent + 25_000);
4021        assert_eq!(details.fee.unwrap_or(0), 30_000);
4022        assert_eq!(details.received, 0);
4023
4024        let tx = &psbt.unsigned_tx;
4025        assert_eq!(tx.input.len(), 2);
4026        assert_eq!(tx.output.len(), 1);
4027        assert_eq!(
4028            tx.output
4029                .iter()
4030                .find(|txout| txout.script_pubkey == addr.script_pubkey())
4031                .unwrap()
4032                .value,
4033            45_000
4034        );
4035
4036        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(140.0), @dust_change, @add_signature);
4037    }
4038
4039    #[test]
4040    fn test_bump_fee_force_add_input() {
4041        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
4042        let incoming_txid = crate::populate_test_db!(
4043            wallet.database.borrow_mut(),
4044            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
4045            Some(100),
4046        );
4047
4048        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
4049        let mut builder = wallet.build_tx();
4050        builder
4051            .add_recipient(addr.script_pubkey(), 45_000)
4052            .enable_rbf();
4053        let (psbt, mut original_details) = builder.finish().unwrap();
4054        let mut tx = psbt.extract_tx();
4055        let txid = tx.txid();
4056        // skip saving the new utxos, we know they can't be used anyways
4057        for txin in &mut tx.input {
4058            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
4059            wallet
4060                .database
4061                .borrow_mut()
4062                .del_utxo(&txin.previous_output)
4063                .unwrap();
4064        }
4065        original_details.transaction = Some(tx);
4066        wallet
4067            .database
4068            .borrow_mut()
4069            .set_tx(&original_details)
4070            .unwrap();
4071
4072        // the new fee_rate is low enough that just reducing the change would be fine, but we force
4073        // the addition of an extra input with `add_utxo()`
4074        let mut builder = wallet.build_fee_bump(txid).unwrap();
4075        builder
4076            .add_utxo(OutPoint {
4077                txid: incoming_txid,
4078                vout: 0,
4079            })
4080            .unwrap()
4081            .fee_rate(FeeRate::from_sat_per_vb(5.0));
4082        let (psbt, details) = builder.finish().unwrap();
4083
4084        assert_eq!(details.sent, original_details.sent + 25_000);
4085        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
4086
4087        let tx = &psbt.unsigned_tx;
4088        assert_eq!(tx.input.len(), 2);
4089        assert_eq!(tx.output.len(), 2);
4090        assert_eq!(
4091            tx.output
4092                .iter()
4093                .find(|txout| txout.script_pubkey == addr.script_pubkey())
4094                .unwrap()
4095                .value,
4096            45_000
4097        );
4098        assert_eq!(
4099            tx.output
4100                .iter()
4101                .find(|txout| txout.script_pubkey != addr.script_pubkey())
4102                .unwrap()
4103                .value,
4104            details.received
4105        );
4106
4107        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(5.0), @add_signature);
4108    }
4109
4110    #[test]
4111    fn test_bump_fee_absolute_force_add_input() {
4112        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
4113        let incoming_txid = crate::populate_test_db!(
4114            wallet.database.borrow_mut(),
4115            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
4116            Some(100),
4117        );
4118
4119        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
4120        let mut builder = wallet.build_tx();
4121        builder
4122            .add_recipient(addr.script_pubkey(), 45_000)
4123            .enable_rbf();
4124        let (psbt, mut original_details) = builder.finish().unwrap();
4125        let mut tx = psbt.extract_tx();
4126        let txid = tx.txid();
4127        // skip saving the new utxos, we know they can't be used anyways
4128        for txin in &mut tx.input {
4129            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
4130            wallet
4131                .database
4132                .borrow_mut()
4133                .del_utxo(&txin.previous_output)
4134                .unwrap();
4135        }
4136        original_details.transaction = Some(tx);
4137        wallet
4138            .database
4139            .borrow_mut()
4140            .set_tx(&original_details)
4141            .unwrap();
4142
4143        // the new fee_rate is low enough that just reducing the change would be fine, but we force
4144        // the addition of an extra input with `add_utxo()`
4145        let mut builder = wallet.build_fee_bump(txid).unwrap();
4146        builder
4147            .add_utxo(OutPoint {
4148                txid: incoming_txid,
4149                vout: 0,
4150            })
4151            .unwrap()
4152            .fee_absolute(250);
4153        let (psbt, details) = builder.finish().unwrap();
4154
4155        assert_eq!(details.sent, original_details.sent + 25_000);
4156        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
4157
4158        let tx = &psbt.unsigned_tx;
4159        assert_eq!(tx.input.len(), 2);
4160        assert_eq!(tx.output.len(), 2);
4161        assert_eq!(
4162            tx.output
4163                .iter()
4164                .find(|txout| txout.script_pubkey == addr.script_pubkey())
4165                .unwrap()
4166                .value,
4167            45_000
4168        );
4169        assert_eq!(
4170            tx.output
4171                .iter()
4172                .find(|txout| txout.script_pubkey != addr.script_pubkey())
4173                .unwrap()
4174                .value,
4175            details.received
4176        );
4177
4178        assert_eq!(details.fee.unwrap_or(0), 250);
4179    }
4180
4181    #[test]
4182    #[should_panic(expected = "InsufficientFunds")]
4183    fn test_bump_fee_unconfirmed_inputs_only() {
4184        // We try to bump the fee, but:
4185        // - We can't reduce the change, as we have no change
4186        // - All our UTXOs are unconfirmed
4187        // So, we fail with "InsufficientFunds", as per RBF rule 2:
4188        // The replacement transaction may only include an unconfirmed input
4189        // if that input was included in one of the original transactions.
4190        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
4191        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
4192        let mut builder = wallet.build_tx();
4193        builder
4194            .drain_wallet()
4195            .drain_to(addr.script_pubkey())
4196            .enable_rbf();
4197        let (psbt, mut original_details) = builder.finish().unwrap();
4198        // Now we receive one transaction with 0 confirmations. We won't be able to use that for
4199        // fee bumping, as it's still unconfirmed!
4200        crate::populate_test_db!(
4201            wallet.database.borrow_mut(),
4202            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 0)),
4203            Some(100),
4204        );
4205        let mut tx = psbt.extract_tx();
4206        let txid = tx.txid();
4207        for txin in &mut tx.input {
4208            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
4209            wallet
4210                .database
4211                .borrow_mut()
4212                .del_utxo(&txin.previous_output)
4213                .unwrap();
4214        }
4215        original_details.transaction = Some(tx);
4216        wallet
4217            .database
4218            .borrow_mut()
4219            .set_tx(&original_details)
4220            .unwrap();
4221
4222        let mut builder = wallet.build_fee_bump(txid).unwrap();
4223        builder.fee_rate(FeeRate::from_sat_per_vb(25.0));
4224        builder.finish().unwrap();
4225    }
4226
4227    #[test]
4228    fn test_bump_fee_unconfirmed_input() {
4229        // We create a tx draining the wallet and spending one confirmed
4230        // and one unconfirmed UTXO. We check that we can fee bump normally
4231        // (BIP125 rule 2 only apply to newly added unconfirmed input, you can
4232        // always fee bump with an unconfirmed input if it was included in the
4233        // original transaction)
4234        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
4235        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
4236        // We receive a tx with 0 confirmations, which will be used as an input
4237        // in the drain tx.
4238        crate::populate_test_db!(
4239            wallet.database.borrow_mut(),
4240            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 0)),
4241            Some(100),
4242        );
4243        let mut builder = wallet.build_tx();
4244        builder
4245            .drain_wallet()
4246            .drain_to(addr.script_pubkey())
4247            .enable_rbf();
4248        let (psbt, mut original_details) = builder.finish().unwrap();
4249        let mut tx = psbt.extract_tx();
4250        let txid = tx.txid();
4251        for txin in &mut tx.input {
4252            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
4253            wallet
4254                .database
4255                .borrow_mut()
4256                .del_utxo(&txin.previous_output)
4257                .unwrap();
4258        }
4259        original_details.transaction = Some(tx);
4260        wallet
4261            .database
4262            .borrow_mut()
4263            .set_tx(&original_details)
4264            .unwrap();
4265
4266        let mut builder = wallet.build_fee_bump(txid).unwrap();
4267        builder
4268            .fee_rate(FeeRate::from_sat_per_vb(15.0))
4269            .allow_shrinking(addr.script_pubkey())
4270            .unwrap();
4271        builder.finish().unwrap();
4272    }
4273
4274    #[test]
4275    fn test_fee_amount_negative_drain_val() {
4276        // While building the transaction, bdk would calculate the drain_value
4277        // as
4278        // current_delta - fee_amount - drain_fee
4279        // using saturating_sub, meaning that if the result would end up negative,
4280        // it'll remain to zero instead.
4281        // This caused a bug in master where we would calculate the wrong fee
4282        // for a transaction.
4283        // See https://github.com/bitcoindevkit/bdk/issues/660
4284        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
4285        let send_to = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt").unwrap();
4286        let fee_rate = FeeRate::from_sat_per_vb(2.01);
4287        let incoming_txid = crate::populate_test_db!(
4288            wallet.database.borrow_mut(),
4289            testutils! (@tx ( (@external descriptors, 0) => 8859 ) (@confirmations 1)),
4290            Some(100),
4291        );
4292
4293        let mut builder = wallet.build_tx();
4294        builder
4295            .add_recipient(send_to.script_pubkey(), 8630)
4296            .add_utxo(OutPoint::new(incoming_txid, 0))
4297            .unwrap()
4298            .enable_rbf()
4299            .fee_rate(fee_rate);
4300        let (psbt, details) = builder.finish().unwrap();
4301
4302        assert!(psbt.inputs.len() == 1);
4303        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate, @add_signature);
4304    }
4305
4306    #[test]
4307    fn test_sign_single_xprv() {
4308        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
4309        let addr = wallet.get_address(New).unwrap();
4310        let mut builder = wallet.build_tx();
4311        builder.drain_to(addr.script_pubkey()).drain_wallet();
4312        let (mut psbt, _) = builder.finish().unwrap();
4313
4314        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
4315        assert!(finalized);
4316
4317        let extracted = psbt.extract_tx();
4318        assert_eq!(extracted.input[0].witness.len(), 2);
4319    }
4320
4321    #[test]
4322    fn test_sign_single_xprv_with_master_fingerprint_and_path() {
4323        let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/84h/1h/0h]tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
4324        let addr = wallet.get_address(New).unwrap();
4325        let mut builder = wallet.build_tx();
4326        builder.drain_to(addr.script_pubkey()).drain_wallet();
4327        let (mut psbt, _) = builder.finish().unwrap();
4328
4329        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
4330        assert!(finalized);
4331
4332        let extracted = psbt.extract_tx();
4333        assert_eq!(extracted.input[0].witness.len(), 2);
4334    }
4335
4336    #[test]
4337    fn test_sign_single_xprv_bip44_path() {
4338        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/44'/0'/0'/0/*)");
4339        let addr = wallet.get_address(New).unwrap();
4340        let mut builder = wallet.build_tx();
4341        builder.drain_to(addr.script_pubkey()).drain_wallet();
4342        let (mut psbt, _) = builder.finish().unwrap();
4343
4344        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
4345        assert!(finalized);
4346
4347        let extracted = psbt.extract_tx();
4348        assert_eq!(extracted.input[0].witness.len(), 2);
4349    }
4350
4351    #[test]
4352    fn test_sign_single_xprv_sh_wpkh() {
4353        let (wallet, _, _) = get_funded_wallet("sh(wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*))");
4354        let addr = wallet.get_address(New).unwrap();
4355        let mut builder = wallet.build_tx();
4356        builder.drain_to(addr.script_pubkey()).drain_wallet();
4357        let (mut psbt, _) = builder.finish().unwrap();
4358
4359        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
4360        assert!(finalized);
4361
4362        let extracted = psbt.extract_tx();
4363        assert_eq!(extracted.input[0].witness.len(), 2);
4364    }
4365
4366    #[test]
4367    fn test_sign_single_wif() {
4368        let (wallet, _, _) =
4369            get_funded_wallet("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)");
4370        let addr = wallet.get_address(New).unwrap();
4371        let mut builder = wallet.build_tx();
4372        builder.drain_to(addr.script_pubkey()).drain_wallet();
4373        let (mut psbt, _) = builder.finish().unwrap();
4374
4375        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
4376        assert!(finalized);
4377
4378        let extracted = psbt.extract_tx();
4379        assert_eq!(extracted.input[0].witness.len(), 2);
4380    }
4381
4382    #[test]
4383    fn test_sign_single_xprv_no_hd_keypaths() {
4384        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
4385        let addr = wallet.get_address(New).unwrap();
4386        let mut builder = wallet.build_tx();
4387        builder.drain_to(addr.script_pubkey()).drain_wallet();
4388        let (mut psbt, _) = builder.finish().unwrap();
4389
4390        psbt.inputs[0].bip32_derivation.clear();
4391        assert_eq!(psbt.inputs[0].bip32_derivation.len(), 0);
4392
4393        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
4394        assert!(finalized);
4395
4396        let extracted = psbt.extract_tx();
4397        assert_eq!(extracted.input[0].witness.len(), 2);
4398    }
4399
4400    #[test]
4401    fn test_include_output_redeem_witness_script() {
4402        let (wallet, _, _) = get_funded_wallet("sh(wsh(multi(1,cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW,cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)))");
4403        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
4404        let mut builder = wallet.build_tx();
4405        builder
4406            .add_recipient(addr.script_pubkey(), 45_000)
4407            .include_output_redeem_witness_script();
4408        let (psbt, _) = builder.finish().unwrap();
4409
4410        // p2sh-p2wsh transaction should contain both witness and redeem scripts
4411        assert!(psbt
4412            .outputs
4413            .iter()
4414            .any(|output| output.redeem_script.is_some() && output.witness_script.is_some()));
4415    }
4416
4417    #[test]
4418    fn test_signing_only_one_of_multiple_inputs() {
4419        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
4420        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
4421        let mut builder = wallet.build_tx();
4422        builder
4423            .add_recipient(addr.script_pubkey(), 45_000)
4424            .include_output_redeem_witness_script();
4425        let (mut psbt, _) = builder.finish().unwrap();
4426
4427        // add another input to the psbt that is at least passable.
4428        let dud_input = bitcoin::util::psbt::Input {
4429            witness_utxo: Some(TxOut {
4430                value: 100_000,
4431                script_pubkey: miniscript::Descriptor::<bitcoin::PublicKey>::from_str(
4432                    "wpkh(025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357)",
4433                )
4434                .unwrap()
4435                .script_pubkey(),
4436            }),
4437            ..Default::default()
4438        };
4439
4440        psbt.inputs.push(dud_input);
4441        psbt.unsigned_tx.input.push(bitcoin::TxIn::default());
4442        let is_final = wallet
4443            .sign(
4444                &mut psbt,
4445                SignOptions {
4446                    trust_witness_utxo: true,
4447                    ..Default::default()
4448                },
4449            )
4450            .unwrap();
4451        assert!(
4452            !is_final,
4453            "shouldn't be final since we can't sign one of the inputs"
4454        );
4455        assert!(
4456            psbt.inputs[0].final_script_witness.is_some(),
4457            "should finalized input it signed"
4458        )
4459    }
4460
4461    #[test]
4462    fn test_remove_partial_sigs_after_finalize_sign_option() {
4463        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
4464
4465        for remove_partial_sigs in &[true, false] {
4466            let addr = wallet.get_address(New).unwrap();
4467            let mut builder = wallet.build_tx();
4468            builder.drain_to(addr.script_pubkey()).drain_wallet();
4469            let mut psbt = builder.finish().unwrap().0;
4470
4471            assert!(wallet
4472                .sign(
4473                    &mut psbt,
4474                    SignOptions {
4475                        remove_partial_sigs: *remove_partial_sigs,
4476                        ..Default::default()
4477                    },
4478                )
4479                .unwrap());
4480
4481            psbt.inputs.iter().for_each(|input| {
4482                if *remove_partial_sigs {
4483                    assert!(input.partial_sigs.is_empty())
4484                } else {
4485                    assert!(!input.partial_sigs.is_empty())
4486                }
4487            });
4488        }
4489    }
4490
4491    #[test]
4492    fn test_try_finalize_sign_option() {
4493        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
4494
4495        for try_finalize in &[true, false] {
4496            let addr = wallet.get_address(New).unwrap();
4497            let mut builder = wallet.build_tx();
4498            builder.drain_to(addr.script_pubkey()).drain_wallet();
4499            let mut psbt = builder.finish().unwrap().0;
4500
4501            let finalized = wallet
4502                .sign(
4503                    &mut psbt,
4504                    SignOptions {
4505                        try_finalize: *try_finalize,
4506                        ..Default::default()
4507                    },
4508                )
4509                .unwrap();
4510
4511            psbt.inputs.iter().for_each(|input| {
4512                if *try_finalize {
4513                    assert!(finalized);
4514                    assert!(input.final_script_sig.is_some());
4515                    assert!(input.final_script_witness.is_some());
4516                } else {
4517                    assert!(!finalized);
4518                    assert!(input.final_script_sig.is_none());
4519                    assert!(input.final_script_witness.is_none());
4520                }
4521            });
4522        }
4523    }
4524
4525    #[test]
4526    fn test_sign_nonstandard_sighash() {
4527        let sighash = EcdsaSighashType::NonePlusAnyoneCanPay;
4528
4529        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
4530        let addr = wallet.get_address(New).unwrap();
4531        let mut builder = wallet.build_tx();
4532        builder
4533            .drain_to(addr.script_pubkey())
4534            .sighash(sighash.into())
4535            .drain_wallet();
4536        let (mut psbt, _) = builder.finish().unwrap();
4537
4538        let result = wallet.sign(&mut psbt, Default::default());
4539        assert!(
4540            result.is_err(),
4541            "Signing should have failed because the TX uses non-standard sighashes"
4542        );
4543        assert_matches!(
4544            result,
4545            Err(Error::Signer(SignerError::NonStandardSighash)),
4546            "Signing failed with the wrong error type"
4547        );
4548
4549        // try again after opting-in
4550        let result = wallet.sign(
4551            &mut psbt,
4552            SignOptions {
4553                allow_all_sighashes: true,
4554                ..Default::default()
4555            },
4556        );
4557        assert!(result.is_ok(), "Signing should have worked");
4558        assert!(
4559            result.unwrap(),
4560            "Should finalize the input since we can produce signatures"
4561        );
4562
4563        let extracted = psbt.extract_tx();
4564        assert_eq!(
4565            *extracted.input[0].witness.to_vec()[0].last().unwrap(),
4566            sighash.to_u32() as u8,
4567            "The signature should have been made with the right sighash"
4568        );
4569    }
4570
4571    #[test]
4572    fn test_unused_address() {
4573        let db = MemoryDatabase::new();
4574        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
4575                                         None, Network::Testnet, db).unwrap();
4576
4577        assert_eq!(
4578            wallet.get_address(LastUnused).unwrap().to_string(),
4579            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
4580        );
4581        assert_eq!(
4582            wallet.get_address(LastUnused).unwrap().to_string(),
4583            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
4584        );
4585    }
4586
4587    #[test]
4588    fn test_next_unused_address() {
4589        let descriptor = "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)";
4590        let descriptors = testutils!(@descriptors (descriptor));
4591        let wallet = Wallet::new(
4592            &descriptors.0,
4593            None,
4594            Network::Testnet,
4595            MemoryDatabase::new(),
4596        )
4597        .unwrap();
4598
4599        assert_eq!(
4600            wallet.get_address(LastUnused).unwrap().to_string(),
4601            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
4602        );
4603
4604        // use the above address
4605        crate::populate_test_db!(
4606            wallet.database.borrow_mut(),
4607            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
4608            Some(100),
4609        );
4610
4611        assert_eq!(
4612            wallet.get_address(LastUnused).unwrap().to_string(),
4613            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4614        );
4615    }
4616
4617    #[test]
4618    fn test_peek_address_at_index() {
4619        let db = MemoryDatabase::new();
4620        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
4621                                         None, Network::Testnet, db).unwrap();
4622
4623        assert_eq!(
4624            wallet.get_address(Peek(1)).unwrap().to_string(),
4625            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4626        );
4627
4628        assert_eq!(
4629            wallet.get_address(Peek(0)).unwrap().to_string(),
4630            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
4631        );
4632
4633        assert_eq!(
4634            wallet.get_address(Peek(2)).unwrap().to_string(),
4635            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
4636        );
4637
4638        // current new address is not affected
4639        assert_eq!(
4640            wallet.get_address(New).unwrap().to_string(),
4641            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
4642        );
4643
4644        assert_eq!(
4645            wallet.get_address(New).unwrap().to_string(),
4646            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4647        );
4648    }
4649
4650    #[test]
4651    fn test_peek_address_at_index_not_derivable() {
4652        let db = MemoryDatabase::new();
4653        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/1)",
4654                                         None, Network::Testnet, db).unwrap();
4655
4656        assert_eq!(
4657            wallet.get_address(Peek(1)).unwrap().to_string(),
4658            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4659        );
4660
4661        assert_eq!(
4662            wallet.get_address(Peek(0)).unwrap().to_string(),
4663            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4664        );
4665
4666        assert_eq!(
4667            wallet.get_address(Peek(2)).unwrap().to_string(),
4668            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4669        );
4670    }
4671
4672    #[test]
4673    fn test_reset_address_index() {
4674        let db = MemoryDatabase::new();
4675        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
4676                                         None, Network::Testnet, db).unwrap();
4677
4678        // new index 0
4679        assert_eq!(
4680            wallet.get_address(New).unwrap().to_string(),
4681            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
4682        );
4683
4684        // new index 1
4685        assert_eq!(
4686            wallet.get_address(New).unwrap().to_string(),
4687            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4688        );
4689
4690        // new index 2
4691        assert_eq!(
4692            wallet.get_address(New).unwrap().to_string(),
4693            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
4694        );
4695
4696        //  reset index 1 again
4697        assert_eq!(
4698            wallet.get_address(Reset(1)).unwrap().to_string(),
4699            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
4700        );
4701
4702        // new index 2 again
4703        assert_eq!(
4704            wallet.get_address(New).unwrap().to_string(),
4705            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
4706        );
4707    }
4708
4709    #[test]
4710    fn test_returns_index_and_address() {
4711        let db = MemoryDatabase::new();
4712        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
4713                                         None, Network::Testnet, db).unwrap();
4714
4715        // new index 0
4716        assert_eq!(
4717            wallet.get_address(New).unwrap(),
4718            AddressInfo {
4719                index: 0,
4720                address: Address::from_str("tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a").unwrap(),
4721                keychain: KeychainKind::External,
4722            }
4723        );
4724
4725        // new index 1
4726        assert_eq!(
4727            wallet.get_address(New).unwrap(),
4728            AddressInfo {
4729                index: 1,
4730                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
4731                keychain: KeychainKind::External,
4732            }
4733        );
4734
4735        // peek index 25
4736        assert_eq!(
4737            wallet.get_address(Peek(25)).unwrap(),
4738            AddressInfo {
4739                index: 25,
4740                address: Address::from_str("tb1qsp7qu0knx3sl6536dzs0703u2w2ag6ppl9d0c2").unwrap(),
4741                keychain: KeychainKind::External,
4742            }
4743        );
4744
4745        // new index 2
4746        assert_eq!(
4747            wallet.get_address(New).unwrap(),
4748            AddressInfo {
4749                index: 2,
4750                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
4751                keychain: KeychainKind::External,
4752            }
4753        );
4754
4755        //  reset index 1 again
4756        assert_eq!(
4757            wallet.get_address(Reset(1)).unwrap(),
4758            AddressInfo {
4759                index: 1,
4760                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
4761                keychain: KeychainKind::External,
4762            }
4763        );
4764
4765        // new index 2 again
4766        assert_eq!(
4767            wallet.get_address(New).unwrap(),
4768            AddressInfo {
4769                index: 2,
4770                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
4771                keychain: KeychainKind::External,
4772            }
4773        );
4774    }
4775
4776    #[test]
4777    fn test_sending_to_bip350_bech32m_address() {
4778        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
4779        let addr =
4780            Address::from_str("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c")
4781                .unwrap();
4782        let mut builder = wallet.build_tx();
4783        builder.add_recipient(addr.script_pubkey(), 45_000);
4784        builder.finish().unwrap();
4785    }
4786
4787    #[test]
4788    fn test_get_address() {
4789        use crate::descriptor::template::Bip84;
4790        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
4791        let wallet = Wallet::new(
4792            Bip84(key, KeychainKind::External),
4793            Some(Bip84(key, KeychainKind::Internal)),
4794            Network::Regtest,
4795            MemoryDatabase::default(),
4796        )
4797        .unwrap();
4798
4799        assert_eq!(
4800            wallet.get_address(AddressIndex::New).unwrap(),
4801            AddressInfo {
4802                index: 0,
4803                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
4804                keychain: KeychainKind::External,
4805            }
4806        );
4807
4808        assert_eq!(
4809            wallet.get_internal_address(AddressIndex::New).unwrap(),
4810            AddressInfo {
4811                index: 0,
4812                address: Address::from_str("bcrt1q0ue3s5y935tw7v3gmnh36c5zzsaw4n9c9smq79").unwrap(),
4813                keychain: KeychainKind::Internal,
4814            }
4815        );
4816
4817        let wallet = Wallet::new(
4818            Bip84(key, KeychainKind::External),
4819            None,
4820            Network::Regtest,
4821            MemoryDatabase::default(),
4822        )
4823        .unwrap();
4824
4825        assert_eq!(
4826            wallet.get_internal_address(AddressIndex::New).unwrap(),
4827            AddressInfo {
4828                index: 0,
4829                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
4830                keychain: KeychainKind::Internal,
4831            },
4832            "when there's no internal descriptor it should just use external"
4833        );
4834    }
4835
4836    #[test]
4837    fn test_get_address_no_reuse_single_descriptor() {
4838        use crate::descriptor::template::Bip84;
4839        use std::collections::HashSet;
4840
4841        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
4842        let wallet = Wallet::new(
4843            Bip84(key, KeychainKind::External),
4844            None,
4845            Network::Regtest,
4846            MemoryDatabase::default(),
4847        )
4848        .unwrap();
4849
4850        let mut used_set = HashSet::new();
4851
4852        (0..3).for_each(|_| {
4853            let external_addr = wallet.get_address(AddressIndex::New).unwrap().address;
4854            assert!(used_set.insert(external_addr));
4855
4856            let internal_addr = wallet
4857                .get_internal_address(AddressIndex::New)
4858                .unwrap()
4859                .address;
4860            assert!(used_set.insert(internal_addr));
4861        });
4862    }
4863
4864    #[test]
4865    fn test_taproot_psbt_populate_tap_key_origins() {
4866        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
4867        let addr = wallet.get_address(AddressIndex::New).unwrap();
4868
4869        let mut builder = wallet.build_tx();
4870        builder.add_recipient(addr.script_pubkey(), 25_000);
4871        let (psbt, _) = builder.finish().unwrap();
4872
4873        assert_eq!(
4874            psbt.inputs[0]
4875                .tap_key_origins
4876                .clone()
4877                .into_iter()
4878                .collect::<Vec<_>>(),
4879            vec![(
4880                from_str!("b96d3a3dc76a4fc74e976511b23aecb78e0754c23c0ed7a6513e18cbbc7178e9"),
4881                (vec![], (from_str!("f6a5cb8b"), from_str!("m/0")))
4882            )],
4883            "Wrong input tap_key_origins"
4884        );
4885        assert_eq!(
4886            psbt.outputs[0]
4887                .tap_key_origins
4888                .clone()
4889                .into_iter()
4890                .collect::<Vec<_>>(),
4891            vec![(
4892                from_str!("e9b03068cf4a2621d4f81e68f6c4216e6bd260fe6edf6acc55c8d8ae5aeff0a8"),
4893                (vec![], (from_str!("f6a5cb8b"), from_str!("m/1")))
4894            )],
4895            "Wrong output tap_key_origins"
4896        );
4897    }
4898
4899    #[test]
4900    fn test_taproot_psbt_populate_tap_key_origins_repeated_key() {
4901        let (wallet, _, _) = get_funded_wallet(get_test_tr_repeated_key());
4902        let addr = wallet.get_address(AddressIndex::New).unwrap();
4903
4904        let path = vec![("e5mmg3xh".to_string(), vec![0])]
4905            .into_iter()
4906            .collect();
4907
4908        let mut builder = wallet.build_tx();
4909        builder
4910            .add_recipient(addr.script_pubkey(), 25_000)
4911            .policy_path(path, KeychainKind::External);
4912        let (psbt, _) = builder.finish().unwrap();
4913
4914        let mut input_key_origins = psbt.inputs[0]
4915            .tap_key_origins
4916            .clone()
4917            .into_iter()
4918            .collect::<Vec<_>>();
4919        input_key_origins.sort();
4920
4921        assert_eq!(
4922            input_key_origins,
4923            vec![
4924                (
4925                    from_str!("b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"),
4926                    (
4927                        vec![],
4928                        (FromStr::from_str("871fd295").unwrap(), vec![].into())
4929                    )
4930                ),
4931                (
4932                    from_str!("2b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3"),
4933                    (
4934                        vec![
4935                            from_str!(
4936                                "858ad7a7d7f270e2c490c4d6ba00c499e46b18fdd59ea3c2c47d20347110271e"
4937                            ),
4938                            from_str!(
4939                                "f6e927ad4492c051fe325894a4f5f14538333b55a35f099876be42009ec8f903"
4940                            ),
4941                        ],
4942                        (FromStr::from_str("ece52657").unwrap(), vec![].into())
4943                    )
4944                )
4945            ],
4946            "Wrong input tap_key_origins"
4947        );
4948
4949        let mut output_key_origins = psbt.outputs[0]
4950            .tap_key_origins
4951            .clone()
4952            .into_iter()
4953            .collect::<Vec<_>>();
4954        output_key_origins.sort();
4955
4956        assert_eq!(
4957            input_key_origins, output_key_origins,
4958            "Wrong output tap_key_origins"
4959        );
4960    }
4961
4962    #[test]
4963    fn test_taproot_psbt_input_tap_tree() {
4964        use crate::bitcoin::psbt::serialize::Deserialize;
4965        use crate::bitcoin::psbt::TapTree;
4966        use bitcoin::hashes::hex::FromHex;
4967        use bitcoin::util::taproot;
4968
4969        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree());
4970        let addr = wallet.get_address(AddressIndex::Peek(0)).unwrap();
4971
4972        let mut builder = wallet.build_tx();
4973        builder.drain_to(addr.script_pubkey()).drain_wallet();
4974        let (psbt, _) = builder.finish().unwrap();
4975
4976        assert_eq!(
4977            psbt.inputs[0].tap_merkle_root,
4978            Some(
4979                FromHex::from_hex(
4980                    "61f81509635053e52d9d1217545916167394490da2287aca4693606e43851986"
4981                )
4982                .unwrap()
4983            ),
4984        );
4985        assert_eq!(
4986            psbt.inputs[0].tap_scripts.clone().into_iter().collect::<Vec<_>>(),
4987            vec![
4988                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b7ef769a745e625ed4b9a4982a4dc08274c59187e73e6f07171108f455081cb2").unwrap()).unwrap(), (from_str!("208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac"), taproot::LeafVersion::TapScript)),
4989                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b9a515f7be31a70186e3c5937ee4a70cc4b4e1efe876c1d38e408222ffc64834").unwrap()).unwrap(), (from_str!("2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac"), taproot::LeafVersion::TapScript)),
4990            ],
4991        );
4992        assert_eq!(
4993            psbt.inputs[0].tap_internal_key,
4994            Some(from_str!(
4995                "b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"
4996            ))
4997        );
4998
4999        // Since we are creating an output to the same address as the input, assert that the
5000        // internal_key is the same
5001        assert_eq!(
5002            psbt.inputs[0].tap_internal_key,
5003            psbt.outputs[0].tap_internal_key
5004        );
5005
5006        assert_eq!(
5007            psbt.outputs[0].tap_tree,
5008            Some(TapTree::deserialize(&Vec::<u8>::from_hex("01c022208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac01c0222051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac",).unwrap()).unwrap())
5009        );
5010    }
5011
5012    #[test]
5013    fn test_taproot_sign_missing_witness_utxo() {
5014        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
5015        let addr = wallet.get_address(New).unwrap();
5016        let mut builder = wallet.build_tx();
5017        builder.drain_to(addr.script_pubkey()).drain_wallet();
5018        let (mut psbt, _) = builder.finish().unwrap();
5019        let witness_utxo = psbt.inputs[0].witness_utxo.take();
5020
5021        let result = wallet.sign(
5022            &mut psbt,
5023            SignOptions {
5024                allow_all_sighashes: true,
5025                ..Default::default()
5026            },
5027        );
5028        assert_matches!(
5029            result,
5030            Err(Error::Signer(SignerError::MissingWitnessUtxo)),
5031            "Signing should have failed with the correct error because the witness_utxo is missing"
5032        );
5033
5034        // restore the witness_utxo
5035        psbt.inputs[0].witness_utxo = witness_utxo;
5036
5037        let result = wallet.sign(
5038            &mut psbt,
5039            SignOptions {
5040                allow_all_sighashes: true,
5041                ..Default::default()
5042            },
5043        );
5044
5045        assert_matches!(
5046            result,
5047            Ok(true),
5048            "Should finalize the input since we can produce signatures"
5049        );
5050    }
5051
5052    #[test]
5053    fn test_taproot_sign_using_non_witness_utxo() {
5054        let (wallet, _, prev_txid) = get_funded_wallet(get_test_tr_single_sig());
5055        let addr = wallet.get_address(New).unwrap();
5056        let mut builder = wallet.build_tx();
5057        builder.drain_to(addr.script_pubkey()).drain_wallet();
5058        let (mut psbt, _) = builder.finish().unwrap();
5059
5060        psbt.inputs[0].witness_utxo = None;
5061        psbt.inputs[0].non_witness_utxo = wallet.database().get_raw_tx(&prev_txid).unwrap();
5062        assert!(
5063            psbt.inputs[0].non_witness_utxo.is_some(),
5064            "Previous tx should be present in the database"
5065        );
5066
5067        let result = wallet.sign(&mut psbt, Default::default());
5068        assert!(result.is_ok(), "Signing should have worked");
5069        assert!(
5070            result.unwrap(),
5071            "Should finalize the input since we can produce signatures"
5072        );
5073    }
5074
5075    #[test]
5076    fn test_taproot_foreign_utxo() {
5077        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
5078        let (wallet2, _, _) = get_funded_wallet(get_test_tr_single_sig());
5079
5080        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
5081        let utxo = wallet2.list_unspent().unwrap().remove(0);
5082        let psbt_input = wallet2.get_psbt_input(utxo.clone(), None, false).unwrap();
5083        let foreign_utxo_satisfaction = wallet2
5084            .get_descriptor_for_keychain(KeychainKind::External)
5085            .max_satisfaction_weight()
5086            .unwrap();
5087
5088        assert!(
5089            psbt_input.non_witness_utxo.is_none(),
5090            "`non_witness_utxo` should never be populated for taproot"
5091        );
5092
5093        let mut builder = wallet1.build_tx();
5094        builder
5095            .add_recipient(addr.script_pubkey(), 60_000)
5096            .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
5097            .unwrap();
5098        let (psbt, details) = builder.finish().unwrap();
5099
5100        assert_eq!(
5101            details.sent - details.received,
5102            10_000 + details.fee.unwrap_or(0),
5103            "we should have only net spent ~10_000"
5104        );
5105
5106        assert!(
5107            psbt.unsigned_tx
5108                .input
5109                .iter()
5110                .any(|input| input.previous_output == utxo.outpoint),
5111            "foreign_utxo should be in there"
5112        );
5113    }
5114
5115    fn test_spend_from_wallet(wallet: Wallet<AnyDatabase>) {
5116        let addr = wallet.get_address(AddressIndex::New).unwrap();
5117
5118        let mut builder = wallet.build_tx();
5119        builder.add_recipient(addr.script_pubkey(), 25_000);
5120        let (mut psbt, _) = builder.finish().unwrap();
5121
5122        assert!(
5123            wallet.sign(&mut psbt, Default::default()).unwrap(),
5124            "Unable to finalize tx"
5125        );
5126    }
5127
5128    #[test]
5129    fn test_taproot_key_spend() {
5130        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
5131        test_spend_from_wallet(wallet);
5132
5133        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
5134        test_spend_from_wallet(wallet);
5135    }
5136
5137    #[test]
5138    fn test_taproot_no_key_spend() {
5139        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
5140        let addr = wallet.get_address(AddressIndex::New).unwrap();
5141
5142        let mut builder = wallet.build_tx();
5143        builder.add_recipient(addr.script_pubkey(), 25_000);
5144        let (mut psbt, _) = builder.finish().unwrap();
5145
5146        assert!(
5147            wallet
5148                .sign(
5149                    &mut psbt,
5150                    SignOptions {
5151                        sign_with_tap_internal_key: false,
5152                        ..Default::default()
5153                    },
5154                )
5155                .unwrap(),
5156            "Unable to finalize tx"
5157        );
5158
5159        assert!(psbt.inputs.iter().all(|i| i.tap_key_sig.is_none()));
5160    }
5161
5162    #[test]
5163    fn test_taproot_script_spend() {
5164        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree());
5165        test_spend_from_wallet(wallet);
5166
5167        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_xprv());
5168        test_spend_from_wallet(wallet);
5169    }
5170
5171    #[test]
5172    fn test_taproot_script_spend_sign_all_leaves() {
5173        use crate::signer::TapLeavesOptions;
5174        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
5175        let addr = wallet.get_address(AddressIndex::New).unwrap();
5176
5177        let mut builder = wallet.build_tx();
5178        builder.add_recipient(addr.script_pubkey(), 25_000);
5179        let (mut psbt, _) = builder.finish().unwrap();
5180
5181        assert!(
5182            wallet
5183                .sign(
5184                    &mut psbt,
5185                    SignOptions {
5186                        tap_leaves_options: TapLeavesOptions::All,
5187                        ..Default::default()
5188                    },
5189                )
5190                .unwrap(),
5191            "Unable to finalize tx"
5192        );
5193
5194        assert!(psbt
5195            .inputs
5196            .iter()
5197            .all(|i| i.tap_script_sigs.len() == i.tap_scripts.len()));
5198    }
5199
5200    #[test]
5201    fn test_taproot_script_spend_sign_include_some_leaves() {
5202        use crate::signer::TapLeavesOptions;
5203        use bitcoin::util::taproot::TapLeafHash;
5204
5205        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
5206        let addr = wallet.get_address(AddressIndex::New).unwrap();
5207
5208        let mut builder = wallet.build_tx();
5209        builder.add_recipient(addr.script_pubkey(), 25_000);
5210        let (mut psbt, _) = builder.finish().unwrap();
5211        let mut script_leaves: Vec<_> = psbt.inputs[0]
5212            .tap_scripts
5213            .clone()
5214            .values()
5215            .map(|(script, version)| TapLeafHash::from_script(script, *version))
5216            .collect();
5217        let included_script_leaves = vec![script_leaves.pop().unwrap()];
5218        let excluded_script_leaves = script_leaves;
5219
5220        assert!(
5221            wallet
5222                .sign(
5223                    &mut psbt,
5224                    SignOptions {
5225                        tap_leaves_options: TapLeavesOptions::Include(
5226                            included_script_leaves.clone()
5227                        ),
5228                        ..Default::default()
5229                    },
5230                )
5231                .unwrap(),
5232            "Unable to finalize tx"
5233        );
5234
5235        assert!(psbt.inputs[0]
5236            .tap_script_sigs
5237            .iter()
5238            .all(|s| included_script_leaves.contains(&s.0 .1)
5239                && !excluded_script_leaves.contains(&s.0 .1)));
5240    }
5241
5242    #[test]
5243    fn test_taproot_script_spend_sign_exclude_some_leaves() {
5244        use crate::signer::TapLeavesOptions;
5245        use bitcoin::util::taproot::TapLeafHash;
5246
5247        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
5248        let addr = wallet.get_address(AddressIndex::New).unwrap();
5249
5250        let mut builder = wallet.build_tx();
5251        builder.add_recipient(addr.script_pubkey(), 25_000);
5252        let (mut psbt, _) = builder.finish().unwrap();
5253        let mut script_leaves: Vec<_> = psbt.inputs[0]
5254            .tap_scripts
5255            .clone()
5256            .values()
5257            .map(|(script, version)| TapLeafHash::from_script(script, *version))
5258            .collect();
5259        let included_script_leaves = vec![script_leaves.pop().unwrap()];
5260        let excluded_script_leaves = script_leaves;
5261
5262        assert!(
5263            wallet
5264                .sign(
5265                    &mut psbt,
5266                    SignOptions {
5267                        tap_leaves_options: TapLeavesOptions::Exclude(
5268                            excluded_script_leaves.clone()
5269                        ),
5270                        ..Default::default()
5271                    },
5272                )
5273                .unwrap(),
5274            "Unable to finalize tx"
5275        );
5276
5277        assert!(psbt.inputs[0]
5278            .tap_script_sigs
5279            .iter()
5280            .all(|s| included_script_leaves.contains(&s.0 .1)
5281                && !excluded_script_leaves.contains(&s.0 .1)));
5282    }
5283
5284    #[test]
5285    fn test_taproot_script_spend_sign_no_leaves() {
5286        use crate::signer::TapLeavesOptions;
5287        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
5288        let addr = wallet.get_address(AddressIndex::New).unwrap();
5289
5290        let mut builder = wallet.build_tx();
5291        builder.add_recipient(addr.script_pubkey(), 25_000);
5292        let (mut psbt, _) = builder.finish().unwrap();
5293
5294        wallet
5295            .sign(
5296                &mut psbt,
5297                SignOptions {
5298                    tap_leaves_options: TapLeavesOptions::None,
5299                    ..Default::default()
5300                },
5301            )
5302            .unwrap();
5303
5304        assert!(psbt.inputs.iter().all(|i| i.tap_script_sigs.is_empty()));
5305    }
5306
5307    #[test]
5308    fn test_taproot_sign_derive_index_from_psbt() {
5309        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
5310
5311        let addr = wallet.get_address(AddressIndex::New).unwrap();
5312
5313        let mut builder = wallet.build_tx();
5314        builder.add_recipient(addr.script_pubkey(), 25_000);
5315        let (mut psbt, _) = builder.finish().unwrap();
5316
5317        // re-create the wallet with an empty db
5318        let wallet_empty = Wallet::new(
5319            get_test_tr_single_sig_xprv(),
5320            None,
5321            Network::Regtest,
5322            AnyDatabase::Memory(MemoryDatabase::new()),
5323        )
5324        .unwrap();
5325
5326        // signing with an empty db means that we will only look at the psbt to infer the
5327        // derivation index
5328        assert!(
5329            wallet_empty.sign(&mut psbt, Default::default()).unwrap(),
5330            "Unable to finalize tx"
5331        );
5332    }
5333
5334    #[test]
5335    fn test_taproot_sign_explicit_sighash_all() {
5336        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
5337        let addr = wallet.get_address(New).unwrap();
5338        let mut builder = wallet.build_tx();
5339        builder
5340            .drain_to(addr.script_pubkey())
5341            .sighash(SchnorrSighashType::All.into())
5342            .drain_wallet();
5343        let (mut psbt, _) = builder.finish().unwrap();
5344
5345        let result = wallet.sign(&mut psbt, Default::default());
5346        assert!(
5347            result.is_ok(),
5348            "Signing should work because SIGHASH_ALL is safe"
5349        )
5350    }
5351
5352    #[test]
5353    fn test_taproot_sign_non_default_sighash() {
5354        let sighash = SchnorrSighashType::NonePlusAnyoneCanPay;
5355
5356        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
5357        let addr = wallet.get_address(New).unwrap();
5358        let mut builder = wallet.build_tx();
5359        builder
5360            .drain_to(addr.script_pubkey())
5361            .sighash(sighash.into())
5362            .drain_wallet();
5363        let (mut psbt, _) = builder.finish().unwrap();
5364
5365        let witness_utxo = psbt.inputs[0].witness_utxo.take();
5366
5367        let result = wallet.sign(&mut psbt, Default::default());
5368        assert!(
5369            result.is_err(),
5370            "Signing should have failed because the TX uses non-standard sighashes"
5371        );
5372        assert_matches!(
5373            result,
5374            Err(Error::Signer(SignerError::NonStandardSighash)),
5375            "Signing failed with the wrong error type"
5376        );
5377
5378        // try again after opting-in
5379        let result = wallet.sign(
5380            &mut psbt,
5381            SignOptions {
5382                allow_all_sighashes: true,
5383                ..Default::default()
5384            },
5385        );
5386        assert!(
5387            result.is_err(),
5388            "Signing should have failed because the witness_utxo is missing"
5389        );
5390        assert_matches!(
5391            result,
5392            Err(Error::Signer(SignerError::MissingWitnessUtxo)),
5393            "Signing failed with the wrong error type"
5394        );
5395
5396        // restore the witness_utxo
5397        psbt.inputs[0].witness_utxo = witness_utxo;
5398
5399        let result = wallet.sign(
5400            &mut psbt,
5401            SignOptions {
5402                allow_all_sighashes: true,
5403                ..Default::default()
5404            },
5405        );
5406
5407        assert!(result.is_ok(), "Signing should have worked");
5408        assert!(
5409            result.unwrap(),
5410            "Should finalize the input since we can produce signatures"
5411        );
5412
5413        let extracted = psbt.extract_tx();
5414        assert_eq!(
5415            *extracted.input[0].witness.to_vec()[0].last().unwrap(),
5416            sighash as u8,
5417            "The signature should have been made with the right sighash"
5418        );
5419    }
5420
5421    #[test]
5422    fn test_spend_coinbase() {
5423        let descriptors = testutils!(@descriptors (get_test_wpkh()));
5424        let wallet = Wallet::new(
5425            &descriptors.0,
5426            None,
5427            Network::Regtest,
5428            AnyDatabase::Memory(MemoryDatabase::new()),
5429        )
5430        .unwrap();
5431
5432        let confirmation_time = 5;
5433
5434        crate::populate_test_db!(
5435            wallet.database.borrow_mut(),
5436            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
5437            Some(confirmation_time),
5438            (@coinbase true)
5439        );
5440        let sync_time = SyncTime {
5441            block_time: BlockTime {
5442                height: confirmation_time,
5443                timestamp: 0,
5444            },
5445        };
5446        wallet
5447            .database
5448            .borrow_mut()
5449            .set_sync_time(sync_time)
5450            .unwrap();
5451
5452        let not_yet_mature_time = confirmation_time + COINBASE_MATURITY - 1;
5453        let maturity_time = confirmation_time + COINBASE_MATURITY;
5454
5455        let balance = wallet.get_balance().unwrap();
5456        assert_eq!(
5457            balance,
5458            Balance {
5459                immature: 25_000,
5460                trusted_pending: 0,
5461                untrusted_pending: 0,
5462                confirmed: 0
5463            }
5464        );
5465
5466        // We try to create a transaction, only to notice that all
5467        // our funds are unspendable
5468        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
5469        let mut builder = wallet.build_tx();
5470        builder
5471            .add_recipient(addr.script_pubkey(), balance.immature / 2)
5472            .current_height(confirmation_time);
5473        assert_matches!(
5474            builder.finish(),
5475            Err(Error::InsufficientFunds {
5476                needed: _,
5477                available: 0
5478            })
5479        );
5480
5481        // Still unspendable...
5482        let mut builder = wallet.build_tx();
5483        builder
5484            .add_recipient(addr.script_pubkey(), balance.immature / 2)
5485            .current_height(not_yet_mature_time);
5486        assert_matches!(
5487            builder.finish(),
5488            Err(Error::InsufficientFunds {
5489                needed: _,
5490                available: 0
5491            })
5492        );
5493
5494        // ...Now the coinbase is mature :)
5495        let sync_time = SyncTime {
5496            block_time: BlockTime {
5497                height: maturity_time,
5498                timestamp: 0,
5499            },
5500        };
5501        wallet
5502            .database
5503            .borrow_mut()
5504            .set_sync_time(sync_time)
5505            .unwrap();
5506
5507        let balance = wallet.get_balance().unwrap();
5508        assert_eq!(
5509            balance,
5510            Balance {
5511                immature: 0,
5512                trusted_pending: 0,
5513                untrusted_pending: 0,
5514                confirmed: 25_000
5515            }
5516        );
5517        let mut builder = wallet.build_tx();
5518        builder
5519            .add_recipient(addr.script_pubkey(), balance.confirmed / 2)
5520            .current_height(maturity_time);
5521        builder.finish().unwrap();
5522    }
5523
5524    #[test]
5525    fn test_allow_dust_limit() {
5526        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
5527
5528        let addr = wallet.get_address(New).unwrap();
5529
5530        let mut builder = wallet.build_tx();
5531
5532        builder.add_recipient(addr.script_pubkey(), 0);
5533
5534        assert_matches!(builder.finish(), Err(Error::OutputBelowDustLimit(0)));
5535
5536        let mut builder = wallet.build_tx();
5537
5538        builder
5539            .allow_dust(true)
5540            .add_recipient(addr.script_pubkey(), 0);
5541
5542        assert!(builder.finish().is_ok());
5543    }
5544
5545    #[test]
5546    fn test_fee_rate_sign_no_grinding_high_r() {
5547        // Our goal is to obtain a transaction with a signature with high-R (71 bytes
5548        // instead of 70). We then check that our fee rate and fee calculation is
5549        // alright.
5550        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
5551        let addr = wallet.get_address(New).unwrap();
5552        let fee_rate = FeeRate::from_sat_per_vb(1.0);
5553        let mut builder = wallet.build_tx();
5554        let mut data = vec![0];
5555        builder
5556            .drain_to(addr.script_pubkey())
5557            .drain_wallet()
5558            .fee_rate(fee_rate)
5559            .add_data(&data);
5560        let (mut psbt, details) = builder.finish().unwrap();
5561        let (op_return_vout, _) = psbt
5562            .unsigned_tx
5563            .output
5564            .iter()
5565            .enumerate()
5566            .find(|(_n, i)| i.script_pubkey.is_op_return())
5567            .unwrap();
5568
5569        let mut sig_len: usize = 0;
5570        // We try to sign many different times until we find a longer signature (71 bytes)
5571        while sig_len < 71 {
5572            // Changing the OP_RETURN data will make the signature change (but not the fee, until
5573            // data[0] is small enough)
5574            data[0] += 1;
5575            psbt.unsigned_tx.output[op_return_vout].script_pubkey = Script::new_op_return(&data);
5576            // Clearing the previous signature
5577            psbt.inputs[0].partial_sigs.clear();
5578            // Signing
5579            wallet
5580                .sign(
5581                    &mut psbt,
5582                    SignOptions {
5583                        remove_partial_sigs: false,
5584                        try_finalize: false,
5585                        allow_grinding: false,
5586                        ..Default::default()
5587                    },
5588                )
5589                .unwrap();
5590            // We only have one key in the partial_sigs map, this is a trick to retrieve it
5591            let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
5592            sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
5593        }
5594        // Actually finalizing the transaction...
5595        wallet
5596            .sign(
5597                &mut psbt,
5598                SignOptions {
5599                    remove_partial_sigs: false,
5600                    allow_grinding: false,
5601                    ..Default::default()
5602                },
5603            )
5604            .unwrap();
5605        // ...and checking that everything is fine
5606        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate);
5607    }
5608
5609    #[test]
5610    fn test_fee_rate_sign_grinding_low_r() {
5611        // Our goal is to obtain a transaction with a signature with low-R (70 bytes)
5612        // by setting the `allow_grinding` signing option as true.
5613        // We then check that our fee rate and fee calculation is alright and that our
5614        // signature is 70 bytes.
5615        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
5616        let addr = wallet.get_address(New).unwrap();
5617        let fee_rate = FeeRate::from_sat_per_vb(1.0);
5618        let mut builder = wallet.build_tx();
5619        builder
5620            .drain_to(addr.script_pubkey())
5621            .drain_wallet()
5622            .fee_rate(fee_rate);
5623        let (mut psbt, details) = builder.finish().unwrap();
5624
5625        wallet
5626            .sign(
5627                &mut psbt,
5628                SignOptions {
5629                    remove_partial_sigs: false,
5630                    allow_grinding: true,
5631                    ..Default::default()
5632                },
5633            )
5634            .unwrap();
5635
5636        let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
5637        let sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
5638        assert_eq!(sig_len, 70);
5639        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate);
5640    }
5641
5642    #[cfg(feature = "test-hardware-signer")]
5643    #[test]
5644    fn test_create_signer() {
5645        use crate::wallet::hardwaresigner::HWISigner;
5646        use hwi::types::HWIChain;
5647        use hwi::HWIClient;
5648
5649        let mut devices = HWIClient::enumerate().unwrap();
5650        if devices.is_empty() {
5651            panic!("No devices found!");
5652        }
5653        let device = devices.remove(0).unwrap();
5654        let client = HWIClient::get_client(&device, true, HWIChain::Regtest).unwrap();
5655        let descriptors = client.get_descriptors::<String>(None).unwrap();
5656        let custom_signer = HWISigner::from_device(&device, HWIChain::Regtest).unwrap();
5657
5658        let (mut wallet, _, _) = get_funded_wallet(&descriptors.internal[0]);
5659        wallet.add_signer(
5660            KeychainKind::External,
5661            SignerOrdering(200),
5662            Arc::new(custom_signer),
5663        );
5664
5665        let addr = wallet.get_address(LastUnused).unwrap();
5666        let mut builder = wallet.build_tx();
5667        builder.drain_to(addr.script_pubkey()).drain_wallet();
5668        let (mut psbt, _) = builder.finish().unwrap();
5669
5670        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
5671        assert!(finalized);
5672    }
5673
5674    #[test]
5675    fn test_taproot_load_descriptor_duplicated_keys() {
5676        // Added after issue https://github.com/bitcoindevkit/bdk/issues/760
5677        //
5678        // Having the same key in multiple taproot leaves is safe and should be accepted by BDK
5679
5680        let (wallet, _, _) = get_funded_wallet(get_test_tr_dup_keys());
5681        let addr = wallet.get_address(New).unwrap();
5682
5683        assert_eq!(
5684            addr.to_string(),
5685            "bcrt1pvysh4nmh85ysrkpwtrr8q8gdadhgdejpy6f9v424a8v9htjxjhyqw9c5s5"
5686        );
5687    }
5688}