bdk_wallet/wallet/
signer.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//! Generalized signers
13//!
14//! This module provides the ability to add customized signers to a [`Wallet`](super::Wallet)
15//! through the [`Wallet::add_signer`](super::Wallet::add_signer) function.
16//!
17//! ```
18//! # use alloc::sync::Arc;
19//! # use core::str::FromStr;
20//! # use bitcoin::secp256k1::{Secp256k1, All};
21//! # use bitcoin::*;
22//! # use bdk_wallet::signer::*;
23//! # use bdk_wallet::*;
24//! # #[derive(Debug)]
25//! # struct CustomHSM;
26//! # impl CustomHSM {
27//! #     fn hsm_sign_input(&self, _psbt: &mut Psbt, _input: usize) -> Result<(), SignerError> {
28//! #         Ok(())
29//! #     }
30//! #     fn connect() -> Self {
31//! #         CustomHSM
32//! #     }
33//! #     fn get_id(&self) -> SignerId {
34//! #         SignerId::Dummy(0)
35//! #     }
36//! # }
37//! #[derive(Debug)]
38//! struct CustomSigner {
39//!     device: CustomHSM,
40//! }
41//!
42//! impl CustomSigner {
43//!     fn connect() -> Self {
44//!         CustomSigner { device: CustomHSM::connect() }
45//!     }
46//! }
47//!
48//! impl SignerCommon for CustomSigner {
49//!     fn id(&self, _secp: &Secp256k1<All>) -> SignerId {
50//!         self.device.get_id()
51//!     }
52//! }
53//!
54//! impl InputSigner for CustomSigner {
55//!     fn sign_input(
56//!         &self,
57//!         psbt: &mut Psbt,
58//!         input_index: usize,
59//!         _sign_options: &SignOptions,
60//!         _secp: &Secp256k1<All>,
61//!     ) -> Result<(), SignerError> {
62//!         self.device.hsm_sign_input(psbt, input_index)?;
63//!
64//!         Ok(())
65//!     }
66//! }
67//!
68//! let custom_signer = CustomSigner::connect();
69//!
70//! let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/0/*)";
71//! let change_descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/1/*)";
72//! let mut wallet = Wallet::create(descriptor, change_descriptor)
73//!     .network(Network::Testnet)
74//!     .create_wallet_no_persist()?;
75//! wallet.add_signer(
76//!     KeychainKind::External,
77//!     SignerOrdering(200),
78//!     Arc::new(custom_signer)
79//! );
80//!
81//! # Ok::<_, anyhow::Error>(())
82//! ```
83
84use crate::collections::BTreeMap;
85use alloc::string::String;
86use alloc::sync::Arc;
87use alloc::vec::Vec;
88use core::cmp::Ordering;
89use core::fmt;
90use core::ops::{Bound::Included, Deref};
91
92use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpriv};
93use bitcoin::hashes::hash160;
94use bitcoin::secp256k1::Message;
95use bitcoin::sighash::{EcdsaSighashType, TapSighash, TapSighashType};
96use bitcoin::{ecdsa, psbt, sighash, taproot};
97use bitcoin::{key::TapTweak, key::XOnlyPublicKey, secp256k1};
98use bitcoin::{PrivateKey, Psbt, PublicKey};
99
100use miniscript::descriptor::{
101    Descriptor, DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey,
102    InnerXKey, KeyMap, SinglePriv, SinglePubKey,
103};
104use miniscript::{SigType, ToPublicKey};
105
106use super::utils::SecpCtx;
107use crate::descriptor::{DescriptorMeta, XKeyUtils};
108use crate::psbt::PsbtUtils;
109use crate::wallet::error::MiniscriptPsbtError;
110
111/// Identifier of a signer in the `SignersContainers`. Used as a key to find the right signer among
112/// multiple of them
113#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq, Hash)]
114pub enum SignerId {
115    /// Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA public key
116    PkHash(hash160::Hash),
117    /// The fingerprint of a BIP32 extended key
118    Fingerprint(Fingerprint),
119    /// Dummy identifier
120    Dummy(u64),
121}
122
123impl From<hash160::Hash> for SignerId {
124    fn from(hash: hash160::Hash) -> SignerId {
125        SignerId::PkHash(hash)
126    }
127}
128
129impl From<Fingerprint> for SignerId {
130    fn from(fing: Fingerprint) -> SignerId {
131        SignerId::Fingerprint(fing)
132    }
133}
134
135/// Signing error
136#[derive(Debug)]
137pub enum SignerError {
138    /// The private key is missing for the required public key
139    MissingKey,
140    /// The private key in use has the right fingerprint but derives differently than expected
141    InvalidKey,
142    /// The user canceled the operation
143    UserCanceled,
144    /// Input index is out of range
145    InputIndexOutOfRange,
146    /// The `non_witness_utxo` field of the transaction is required to sign this input
147    MissingNonWitnessUtxo,
148    /// The `non_witness_utxo` specified is invalid
149    InvalidNonWitnessUtxo,
150    /// The `witness_utxo` field of the transaction is required to sign this input
151    MissingWitnessUtxo,
152    /// The `witness_script` field of the transaction is required to sign this input
153    MissingWitnessScript,
154    /// The fingerprint and derivation path are missing from the psbt input
155    MissingHdKeypath,
156    /// The psbt contains a non-`SIGHASH_ALL` sighash in one of its input and the user hasn't
157    /// explicitly allowed them
158    ///
159    /// To enable signing transactions with non-standard sighashes set
160    /// [`SignOptions::allow_all_sighashes`] to `true`.
161    NonStandardSighash,
162    /// Invalid SIGHASH for the signing context in use
163    InvalidSighash,
164    /// Error while computing the hash to sign a Taproot input.
165    SighashTaproot(sighash::TaprootError),
166    /// PSBT sign error.
167    Psbt(psbt::SignError),
168    /// Miniscript PSBT error
169    MiniscriptPsbt(MiniscriptPsbtError),
170    /// To be used only by external libraries implementing [`InputSigner`] or
171    /// [`TransactionSigner`], so that they can return their own custom errors, without having to
172    /// modify [`SignerError`] in BDK.
173    External(String),
174}
175
176impl fmt::Display for SignerError {
177    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178        match self {
179            Self::MissingKey => write!(f, "Missing private key"),
180            Self::InvalidKey => write!(f, "The private key in use has the right fingerprint but derives differently than expected"),
181            Self::UserCanceled => write!(f, "The user canceled the operation"),
182            Self::InputIndexOutOfRange => write!(f, "Input index out of range"),
183            Self::MissingNonWitnessUtxo => write!(f, "Missing non-witness UTXO"),
184            Self::InvalidNonWitnessUtxo => write!(f, "Invalid non-witness UTXO"),
185            Self::MissingWitnessUtxo => write!(f, "Missing witness UTXO"),
186            Self::MissingWitnessScript => write!(f, "Missing witness script"),
187            Self::MissingHdKeypath => write!(f, "Missing fingerprint and derivation path"),
188            Self::NonStandardSighash => write!(f, "The psbt contains a non standard sighash"),
189            Self::InvalidSighash => write!(f, "Invalid SIGHASH for the signing context in use"),
190            Self::SighashTaproot(err) => write!(f, "Error while computing the hash to sign a Taproot input: {err}"),
191            Self::Psbt(err) => write!(f, "Error computing the sighash: {err}"),
192            Self::MiniscriptPsbt(err) => write!(f, "Miniscript PSBT error: {err}"),
193            Self::External(err) => write!(f, "{err}"),
194        }
195    }
196}
197
198#[cfg(feature = "std")]
199impl std::error::Error for SignerError {}
200
201/// Signing context
202///
203/// Used by our software signers to determine the type of signatures to make
204#[derive(Debug, Clone, Copy, PartialEq, Eq)]
205pub enum SignerContext {
206    /// Legacy context
207    Legacy,
208    /// Segwit v0 context (BIP 143)
209    Segwitv0,
210    /// Taproot context (BIP 340)
211    Tap {
212        /// Whether the signer can sign for the internal key or not
213        is_internal_key: bool,
214    },
215}
216
217/// Wrapper to pair a signer with its context
218#[derive(Debug, Clone)]
219pub struct SignerWrapper<S: Sized + fmt::Debug + Clone> {
220    signer: S,
221    ctx: SignerContext,
222}
223
224impl<S: Sized + fmt::Debug + Clone> SignerWrapper<S> {
225    /// Create a wrapped signer from a signer and a context
226    pub fn new(signer: S, ctx: SignerContext) -> Self {
227        SignerWrapper { signer, ctx }
228    }
229}
230
231impl<S: Sized + fmt::Debug + Clone> Deref for SignerWrapper<S> {
232    type Target = S;
233
234    fn deref(&self) -> &Self::Target {
235        &self.signer
236    }
237}
238
239/// Common signer methods
240pub trait SignerCommon: fmt::Debug + Send + Sync {
241    /// Return the [`SignerId`] for this signer
242    ///
243    /// The [`SignerId`] can be used to lookup a signer in the [`Wallet`](crate::Wallet)'s signers
244    /// map or to compare two signers.
245    fn id(&self, secp: &SecpCtx) -> SignerId;
246
247    /// Return the secret key for the signer
248    ///
249    /// This is used internally to reconstruct the original descriptor that may contain secrets.
250    /// External signers that are meant to keep key isolated should just return `None` here (which
251    /// is the default for this method, if not overridden).
252    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
253        None
254    }
255}
256
257/// PSBT Input signer
258///
259/// This trait can be implemented to provide custom signers to the wallet. If the signer supports
260/// signing individual inputs, this trait should be implemented and BDK will provide automatically
261/// an implementation for [`TransactionSigner`].
262pub trait InputSigner: SignerCommon {
263    /// Sign a single psbt input
264    fn sign_input(
265        &self,
266        psbt: &mut Psbt,
267        input_index: usize,
268        sign_options: &SignOptions,
269        secp: &SecpCtx,
270    ) -> Result<(), SignerError>;
271}
272
273/// PSBT signer
274///
275/// This trait can be implemented when the signer can't sign inputs individually, but signs the
276/// whole transaction at once.
277pub trait TransactionSigner: SignerCommon {
278    /// Sign all the inputs of the psbt
279    fn sign_transaction(
280        &self,
281        psbt: &mut Psbt,
282        sign_options: &SignOptions,
283        secp: &SecpCtx,
284    ) -> Result<(), SignerError>;
285}
286
287impl<T: InputSigner> TransactionSigner for T {
288    fn sign_transaction(
289        &self,
290        psbt: &mut Psbt,
291        sign_options: &SignOptions,
292        secp: &SecpCtx,
293    ) -> Result<(), SignerError> {
294        for input_index in 0..psbt.inputs.len() {
295            self.sign_input(psbt, input_index, sign_options, secp)?;
296        }
297
298        Ok(())
299    }
300}
301
302impl SignerCommon for SignerWrapper<DescriptorXKey<Xpriv>> {
303    fn id(&self, secp: &SecpCtx) -> SignerId {
304        SignerId::from(self.root_fingerprint(secp))
305    }
306
307    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
308        Some(DescriptorSecretKey::XPrv(self.signer.clone()))
309    }
310}
311
312impl InputSigner for SignerWrapper<DescriptorXKey<Xpriv>> {
313    fn sign_input(
314        &self,
315        psbt: &mut Psbt,
316        input_index: usize,
317        sign_options: &SignOptions,
318        secp: &SecpCtx,
319    ) -> Result<(), SignerError> {
320        if input_index >= psbt.inputs.len() {
321            return Err(SignerError::InputIndexOutOfRange);
322        }
323
324        if psbt.inputs[input_index].final_script_sig.is_some()
325            || psbt.inputs[input_index].final_script_witness.is_some()
326        {
327            return Ok(());
328        }
329
330        let tap_key_origins = psbt.inputs[input_index]
331            .tap_key_origins
332            .iter()
333            .map(|(pk, (_, keysource))| (SinglePubKey::XOnly(*pk), keysource));
334        let (public_key, full_path) = match psbt.inputs[input_index]
335            .bip32_derivation
336            .iter()
337            .map(|(pk, keysource)| (SinglePubKey::FullKey(PublicKey::new(*pk)), keysource))
338            .chain(tap_key_origins)
339            .find_map(|(pk, keysource)| {
340                if self.matches(keysource, secp).is_some() {
341                    Some((pk, keysource.1.clone()))
342                } else {
343                    None
344                }
345            }) {
346            Some((pk, full_path)) => (pk, full_path),
347            None => return Ok(()),
348        };
349
350        let derived_key = match self.origin.clone() {
351            Some((_fingerprint, origin_path)) => {
352                let deriv_path = DerivationPath::from(
353                    &full_path.into_iter().cloned().collect::<Vec<ChildNumber>>()
354                        [origin_path.len()..],
355                );
356                self.xkey.derive_priv(secp, &deriv_path).unwrap()
357            }
358            None => self.xkey.derive_priv(secp, &full_path).unwrap(),
359        };
360
361        let computed_pk = secp256k1::PublicKey::from_secret_key(secp, &derived_key.private_key);
362        let valid_key = match public_key {
363            SinglePubKey::FullKey(pk) if pk.inner == computed_pk => true,
364            SinglePubKey::XOnly(x_only) if XOnlyPublicKey::from(computed_pk) == x_only => true,
365            _ => false,
366        };
367        if !valid_key {
368            Err(SignerError::InvalidKey)
369        } else {
370            // HD wallets imply compressed keys
371            let priv_key = PrivateKey {
372                compressed: true,
373                network: self.xkey.network,
374                inner: derived_key.private_key,
375            };
376
377            SignerWrapper::new(priv_key, self.ctx).sign_input(psbt, input_index, sign_options, secp)
378        }
379    }
380}
381
382fn multikey_to_xkeys<K: InnerXKey + Clone>(
383    multikey: DescriptorMultiXKey<K>,
384) -> Vec<DescriptorXKey<K>> {
385    multikey
386        .derivation_paths
387        .into_paths()
388        .into_iter()
389        .map(|derivation_path| DescriptorXKey {
390            origin: multikey.origin.clone(),
391            xkey: multikey.xkey.clone(),
392            derivation_path,
393            wildcard: multikey.wildcard,
394        })
395        .collect()
396}
397
398impl SignerCommon for SignerWrapper<DescriptorMultiXKey<Xpriv>> {
399    fn id(&self, secp: &SecpCtx) -> SignerId {
400        SignerId::from(self.root_fingerprint(secp))
401    }
402
403    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
404        Some(DescriptorSecretKey::MultiXPrv(self.signer.clone()))
405    }
406}
407
408impl InputSigner for SignerWrapper<DescriptorMultiXKey<Xpriv>> {
409    fn sign_input(
410        &self,
411        psbt: &mut Psbt,
412        input_index: usize,
413        sign_options: &SignOptions,
414        secp: &SecpCtx,
415    ) -> Result<(), SignerError> {
416        let xkeys = multikey_to_xkeys(self.signer.clone());
417        for xkey in xkeys {
418            SignerWrapper::new(xkey, self.ctx).sign_input(psbt, input_index, sign_options, secp)?
419        }
420        Ok(())
421    }
422}
423
424impl SignerCommon for SignerWrapper<PrivateKey> {
425    fn id(&self, secp: &SecpCtx) -> SignerId {
426        SignerId::from(self.public_key(secp).to_pubkeyhash(SigType::Ecdsa))
427    }
428
429    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
430        Some(DescriptorSecretKey::Single(SinglePriv {
431            key: self.signer,
432            origin: None,
433        }))
434    }
435}
436
437impl InputSigner for SignerWrapper<PrivateKey> {
438    fn sign_input(
439        &self,
440        psbt: &mut Psbt,
441        input_index: usize,
442        sign_options: &SignOptions,
443        secp: &SecpCtx,
444    ) -> Result<(), SignerError> {
445        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
446            return Err(SignerError::InputIndexOutOfRange);
447        }
448
449        if psbt.inputs[input_index].final_script_sig.is_some()
450            || psbt.inputs[input_index].final_script_witness.is_some()
451        {
452            return Ok(());
453        }
454
455        let pubkey = PublicKey::from_private_key(secp, self);
456
457        match self.ctx {
458            SignerContext::Tap { is_internal_key } => {
459                let x_only_pubkey = XOnlyPublicKey::from(pubkey.inner);
460
461                if let Some(psbt_internal_key) = psbt.inputs[input_index].tap_internal_key {
462                    if is_internal_key
463                        && psbt.inputs[input_index].tap_key_sig.is_none()
464                        && sign_options.sign_with_tap_internal_key
465                        && x_only_pubkey == psbt_internal_key
466                    {
467                        let (sighash, sighash_type) = compute_tap_sighash(psbt, input_index, None)?;
468                        sign_psbt_schnorr(
469                            &self.inner,
470                            x_only_pubkey,
471                            None,
472                            &mut psbt.inputs[input_index],
473                            sighash,
474                            sighash_type,
475                            secp,
476                        );
477                    }
478                }
479
480                if let Some((leaf_hashes, _)) =
481                    psbt.inputs[input_index].tap_key_origins.get(&x_only_pubkey)
482                {
483                    let leaf_hashes = leaf_hashes
484                        .iter()
485                        .filter(|lh| {
486                            // Removing the leaves we shouldn't sign for
487                            let should_sign = match &sign_options.tap_leaves_options {
488                                TapLeavesOptions::All => true,
489                                TapLeavesOptions::Include(v) => v.contains(lh),
490                                TapLeavesOptions::Exclude(v) => !v.contains(lh),
491                                TapLeavesOptions::None => false,
492                            };
493                            // Filtering out the leaves without our key
494                            should_sign
495                                && !psbt.inputs[input_index]
496                                    .tap_script_sigs
497                                    .contains_key(&(x_only_pubkey, **lh))
498                        })
499                        .cloned()
500                        .collect::<Vec<_>>();
501                    for lh in leaf_hashes {
502                        let (sighash, sighash_type) =
503                            compute_tap_sighash(psbt, input_index, Some(lh))?;
504                        sign_psbt_schnorr(
505                            &self.inner,
506                            x_only_pubkey,
507                            Some(lh),
508                            &mut psbt.inputs[input_index],
509                            sighash,
510                            sighash_type,
511                            secp,
512                        );
513                    }
514                }
515            }
516            SignerContext::Segwitv0 | SignerContext::Legacy => {
517                if psbt.inputs[input_index].partial_sigs.contains_key(&pubkey) {
518                    return Ok(());
519                }
520
521                let mut sighasher = sighash::SighashCache::new(psbt.unsigned_tx.clone());
522                let (msg, sighash_type) = psbt
523                    .sighash_ecdsa(input_index, &mut sighasher)
524                    .map_err(SignerError::Psbt)?;
525
526                sign_psbt_ecdsa(
527                    &self.inner,
528                    pubkey,
529                    &mut psbt.inputs[input_index],
530                    &msg,
531                    sighash_type,
532                    secp,
533                    sign_options.allow_grinding,
534                );
535            }
536        }
537
538        Ok(())
539    }
540}
541
542fn sign_psbt_ecdsa(
543    secret_key: &secp256k1::SecretKey,
544    pubkey: PublicKey,
545    psbt_input: &mut psbt::Input,
546    msg: &Message,
547    sighash_type: EcdsaSighashType,
548    secp: &SecpCtx,
549    allow_grinding: bool,
550) {
551    let signature = if allow_grinding {
552        secp.sign_ecdsa_low_r(msg, secret_key)
553    } else {
554        secp.sign_ecdsa(msg, secret_key)
555    };
556    secp.verify_ecdsa(msg, &signature, &pubkey.inner)
557        .expect("invalid or corrupted ecdsa signature");
558
559    let final_signature = ecdsa::Signature {
560        signature,
561        sighash_type,
562    };
563    psbt_input.partial_sigs.insert(pubkey, final_signature);
564}
565
566// Calling this with `leaf_hash` = `None` will sign for key-spend
567fn sign_psbt_schnorr(
568    secret_key: &secp256k1::SecretKey,
569    pubkey: XOnlyPublicKey,
570    leaf_hash: Option<taproot::TapLeafHash>,
571    psbt_input: &mut psbt::Input,
572    sighash: TapSighash,
573    sighash_type: TapSighashType,
574    secp: &SecpCtx,
575) {
576    let keypair = secp256k1::Keypair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
577    let keypair = match leaf_hash {
578        None => keypair
579            .tap_tweak(secp, psbt_input.tap_merkle_root)
580            .to_keypair(),
581        Some(_) => keypair, // no tweak for script spend
582    };
583
584    let msg = &Message::from(sighash);
585    let signature = secp.sign_schnorr_no_aux_rand(msg, &keypair);
586    secp.verify_schnorr(&signature, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
587        .expect("invalid or corrupted schnorr signature");
588
589    let final_signature = taproot::Signature {
590        signature,
591        sighash_type,
592    };
593
594    if let Some(lh) = leaf_hash {
595        psbt_input
596            .tap_script_sigs
597            .insert((pubkey, lh), final_signature);
598    } else {
599        psbt_input.tap_key_sig = Some(final_signature);
600    }
601}
602
603/// Defines the order in which signers are called
604///
605/// The default value is `100`. Signers with an ordering above that will be called later,
606/// and they will thus see the partial signatures added to the transaction once they get to sign
607/// themselves.
608#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq)]
609pub struct SignerOrdering(pub usize);
610
611impl Default for SignerOrdering {
612    fn default() -> Self {
613        SignerOrdering(100)
614    }
615}
616
617#[derive(Debug, Clone)]
618struct SignersContainerKey {
619    id: SignerId,
620    ordering: SignerOrdering,
621}
622
623impl From<(SignerId, SignerOrdering)> for SignersContainerKey {
624    fn from(tuple: (SignerId, SignerOrdering)) -> Self {
625        SignersContainerKey {
626            id: tuple.0,
627            ordering: tuple.1,
628        }
629    }
630}
631
632/// Container for multiple signers
633#[derive(Debug, Default, Clone)]
634pub struct SignersContainer(BTreeMap<SignersContainerKey, Arc<dyn TransactionSigner>>);
635
636impl SignersContainer {
637    /// Create a map of public keys to secret keys
638    pub fn as_key_map(&self, secp: &SecpCtx) -> KeyMap {
639        self.0
640            .values()
641            .filter_map(|signer| signer.descriptor_secret_key())
642            .filter_map(|secret| secret.to_public(secp).ok().map(|public| (public, secret)))
643            .collect()
644    }
645
646    /// Build a new signer container from a [`KeyMap`]
647    ///
648    /// Also looks at the corresponding descriptor to determine the [`SignerContext`] to attach to
649    /// the signers
650    pub fn build(
651        keymap: KeyMap,
652        descriptor: &Descriptor<DescriptorPublicKey>,
653        secp: &SecpCtx,
654    ) -> SignersContainer {
655        let mut container = SignersContainer::new();
656
657        for (pubkey, secret) in keymap {
658            let ctx = match descriptor {
659                Descriptor::Tr(tr) => SignerContext::Tap {
660                    is_internal_key: tr.internal_key() == &pubkey,
661                },
662                _ if descriptor.is_witness() => SignerContext::Segwitv0,
663                _ => SignerContext::Legacy,
664            };
665
666            match secret {
667                DescriptorSecretKey::Single(private_key) => container.add_external(
668                    SignerId::from(
669                        private_key
670                            .key
671                            .public_key(secp)
672                            .to_pubkeyhash(SigType::Ecdsa),
673                    ),
674                    SignerOrdering::default(),
675                    Arc::new(SignerWrapper::new(private_key.key, ctx)),
676                ),
677                DescriptorSecretKey::XPrv(xprv) => container.add_external(
678                    SignerId::from(xprv.root_fingerprint(secp)),
679                    SignerOrdering::default(),
680                    Arc::new(SignerWrapper::new(xprv, ctx)),
681                ),
682                DescriptorSecretKey::MultiXPrv(xprv) => container.add_external(
683                    SignerId::from(xprv.root_fingerprint(secp)),
684                    SignerOrdering::default(),
685                    Arc::new(SignerWrapper::new(xprv, ctx)),
686                ),
687            };
688        }
689
690        container
691    }
692}
693
694impl SignersContainer {
695    /// Default constructor
696    pub fn new() -> Self {
697        SignersContainer(Default::default())
698    }
699
700    /// Adds an external signer to the container for the specified id. Optionally returns the
701    /// signer that was previously in the container, if any
702    pub fn add_external(
703        &mut self,
704        id: SignerId,
705        ordering: SignerOrdering,
706        signer: Arc<dyn TransactionSigner>,
707    ) -> Option<Arc<dyn TransactionSigner>> {
708        self.0.insert((id, ordering).into(), signer)
709    }
710
711    /// Removes a signer from the container and returns it
712    pub fn remove(
713        &mut self,
714        id: SignerId,
715        ordering: SignerOrdering,
716    ) -> Option<Arc<dyn TransactionSigner>> {
717        self.0.remove(&(id, ordering).into())
718    }
719
720    /// Returns the list of identifiers of all the signers in the container
721    pub fn ids(&self) -> Vec<&SignerId> {
722        self.0
723            .keys()
724            .map(|SignersContainerKey { id, .. }| id)
725            .collect()
726    }
727
728    /// Returns the list of signers in the container, sorted by lowest to highest `ordering`
729    pub fn signers(&self) -> Vec<&Arc<dyn TransactionSigner>> {
730        self.0.values().collect()
731    }
732
733    /// Finds the signer with lowest ordering for a given id in the container.
734    pub fn find(&self, id: SignerId) -> Option<&Arc<dyn TransactionSigner>> {
735        self.0
736            .range((
737                Included(&(id.clone(), SignerOrdering(0)).into()),
738                Included(&(id.clone(), SignerOrdering(usize::MAX)).into()),
739            ))
740            .filter(|(k, _)| k.id == id)
741            .map(|(_, v)| v)
742            .next()
743    }
744}
745
746/// Options for a software signer
747///
748/// Adjust the behavior of our software signers and the way a transaction is finalized
749#[derive(Debug, Clone)]
750pub struct SignOptions {
751    /// Whether the signer should trust the `witness_utxo`, if the `non_witness_utxo` hasn't been
752    /// provided
753    ///
754    /// Defaults to `false` to mitigate the "SegWit bug" which could trick the wallet into
755    /// paying a fee larger than expected.
756    ///
757    /// Some wallets, especially if relatively old, might not provide the `non_witness_utxo` for
758    /// SegWit transactions in the PSBT they generate: in those cases setting this to `true`
759    /// should correctly produce a signature, at the expense of an increased trust in the creator
760    /// of the PSBT.
761    ///
762    /// For more details see: <https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd>
763    pub trust_witness_utxo: bool,
764
765    /// Whether the wallet should assume a specific height has been reached when trying to finalize
766    /// a transaction
767    ///
768    /// The wallet will only "use" a timelock to satisfy the spending policy of an input if the
769    /// timelock height has already been reached. This option allows overriding the "current
770    /// height" to let the wallet use timelocks in the future to spend a coin.
771    pub assume_height: Option<u32>,
772
773    /// Whether the signer should use the `sighash_type` set in the PSBT when signing, no matter
774    /// what its value is
775    ///
776    /// Defaults to `false` which will only allow signing using `SIGHASH_ALL`.
777    pub allow_all_sighashes: bool,
778
779    /// Whether to try finalizing the PSBT after the inputs are signed.
780    ///
781    /// Defaults to `true` which will try finalizing PSBT after inputs are signed.
782    pub try_finalize: bool,
783
784    /// Specifies which Taproot script-spend leaves we should sign for. This option is
785    /// ignored if we're signing a non-taproot PSBT.
786    ///
787    /// Defaults to All, i.e., the wallet will sign all the leaves it has a key for.
788    pub tap_leaves_options: TapLeavesOptions,
789
790    /// Whether we should try to sign a taproot transaction with the taproot internal key
791    /// or not. This option is ignored if we're signing a non-taproot PSBT.
792    ///
793    /// Defaults to `true`, i.e., we always try to sign with the taproot internal key.
794    pub sign_with_tap_internal_key: bool,
795
796    /// Whether we should grind ECDSA signature to ensure signing with low r
797    /// or not.
798    /// Defaults to `true`, i.e., we always grind ECDSA signature to sign with low r.
799    pub allow_grinding: bool,
800}
801
802/// Customize which taproot script-path leaves the signer should sign.
803#[derive(Default, Debug, Clone, PartialEq, Eq)]
804pub enum TapLeavesOptions {
805    /// The signer will sign all the leaves it has a key for.
806    #[default]
807    All,
808    /// The signer won't sign leaves other than the ones specified. Note that it could still ignore
809    /// some of the specified leaves, if it doesn't have the right key to sign them.
810    Include(Vec<taproot::TapLeafHash>),
811    /// The signer won't sign the specified leaves.
812    Exclude(Vec<taproot::TapLeafHash>),
813    /// The signer won't sign any leaf.
814    None,
815}
816
817impl Default for SignOptions {
818    fn default() -> Self {
819        SignOptions {
820            trust_witness_utxo: false,
821            assume_height: None,
822            allow_all_sighashes: false,
823            try_finalize: true,
824            tap_leaves_options: TapLeavesOptions::default(),
825            sign_with_tap_internal_key: true,
826            allow_grinding: true,
827        }
828    }
829}
830
831/// Computes the taproot sighash.
832fn compute_tap_sighash(
833    psbt: &Psbt,
834    input_index: usize,
835    extra: Option<taproot::TapLeafHash>,
836) -> Result<(sighash::TapSighash, TapSighashType), SignerError> {
837    if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
838        return Err(SignerError::InputIndexOutOfRange);
839    }
840
841    let psbt_input = &psbt.inputs[input_index];
842
843    let sighash_type = psbt_input
844        .sighash_type
845        .unwrap_or_else(|| TapSighashType::Default.into())
846        .taproot_hash_ty()
847        .map_err(|_| SignerError::InvalidSighash)?;
848    let witness_utxos = (0..psbt.inputs.len())
849        .map(|i| psbt.get_utxo_for(i))
850        .collect::<Vec<_>>();
851    let mut all_witness_utxos = vec![];
852
853    let mut cache = sighash::SighashCache::new(&psbt.unsigned_tx);
854    let is_anyone_can_pay = psbt::PsbtSighashType::from(sighash_type).to_u32() & 0x80 != 0;
855    let prevouts = if is_anyone_can_pay {
856        sighash::Prevouts::One(
857            input_index,
858            witness_utxos[input_index]
859                .as_ref()
860                .ok_or(SignerError::MissingWitnessUtxo)?,
861        )
862    } else if witness_utxos.iter().all(Option::is_some) {
863        all_witness_utxos.extend(witness_utxos.iter().filter_map(|x| x.as_ref()));
864        sighash::Prevouts::All(&all_witness_utxos)
865    } else {
866        return Err(SignerError::MissingWitnessUtxo);
867    };
868
869    // Assume no OP_CODESEPARATOR
870    let extra = extra.map(|leaf_hash| (leaf_hash, 0xFFFFFFFF));
871
872    Ok((
873        cache
874            .taproot_signature_hash(input_index, &prevouts, None, extra, sighash_type)
875            .map_err(SignerError::SighashTaproot)?,
876        sighash_type,
877    ))
878}
879
880impl PartialOrd for SignersContainerKey {
881    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
882        Some(self.cmp(other))
883    }
884}
885
886impl Ord for SignersContainerKey {
887    fn cmp(&self, other: &Self) -> Ordering {
888        self.ordering
889            .cmp(&other.ordering)
890            .then(self.id.cmp(&other.id))
891    }
892}
893
894impl PartialEq for SignersContainerKey {
895    fn eq(&self, other: &Self) -> bool {
896        self.id == other.id && self.ordering == other.ordering
897    }
898}
899
900impl Eq for SignersContainerKey {}
901
902#[cfg(test)]
903mod signers_container_tests {
904    use super::*;
905    use crate::descriptor;
906    use crate::descriptor::IntoWalletDescriptor;
907    use crate::keys::{DescriptorKey, IntoDescriptorKey};
908    use assert_matches::assert_matches;
909    use bitcoin::bip32;
910    use bitcoin::secp256k1::{All, Secp256k1};
911    use bitcoin::Network;
912    use core::str::FromStr;
913    use miniscript::ScriptContext;
914
915    fn is_equal(this: &Arc<dyn TransactionSigner>, that: &Arc<DummySigner>) -> bool {
916        let secp = Secp256k1::new();
917        this.id(&secp) == that.id(&secp)
918    }
919
920    // Signers added with the same ordering (like `Ordering::default`) created from `KeyMap`
921    // should be preserved and not overwritten.
922    // This happens usually when a set of signers is created from a descriptor with private keys.
923    #[test]
924    fn signers_with_same_ordering() {
925        let secp = Secp256k1::new();
926
927        let (prvkey1, _, _) = setup_keys(TPRV0_STR);
928        let (prvkey2, _, _) = setup_keys(TPRV1_STR);
929        let desc = descriptor!(sh(multi(2, prvkey1, prvkey2))).unwrap();
930        let (wallet_desc, keymap) = desc
931            .into_wallet_descriptor(&secp, Network::Testnet)
932            .unwrap();
933
934        let signers = SignersContainer::build(keymap, &wallet_desc, &secp);
935        assert_eq!(signers.ids().len(), 2);
936
937        let signers = signers.signers();
938        assert_eq!(signers.len(), 2);
939    }
940
941    #[test]
942    fn signers_sorted_by_ordering() {
943        let mut signers = SignersContainer::new();
944        let signer1 = Arc::new(DummySigner { number: 1 });
945        let signer2 = Arc::new(DummySigner { number: 2 });
946        let signer3 = Arc::new(DummySigner { number: 3 });
947
948        // Mixed order insertions verifies we are not inserting at head or tail.
949        signers.add_external(SignerId::Dummy(2), SignerOrdering(2), signer2.clone());
950        signers.add_external(SignerId::Dummy(1), SignerOrdering(1), signer1.clone());
951        signers.add_external(SignerId::Dummy(3), SignerOrdering(3), signer3.clone());
952
953        // Check that signers are sorted from lowest to highest ordering
954        let signers = signers.signers();
955
956        assert!(is_equal(signers[0], &signer1));
957        assert!(is_equal(signers[1], &signer2));
958        assert!(is_equal(signers[2], &signer3));
959    }
960
961    #[test]
962    fn find_signer_by_id() {
963        let mut signers = SignersContainer::new();
964        let signer1 = Arc::new(DummySigner { number: 1 });
965        let signer2 = Arc::new(DummySigner { number: 2 });
966        let signer3 = Arc::new(DummySigner { number: 3 });
967        let signer4 = Arc::new(DummySigner { number: 3 }); // Same ID as `signer3` but will use lower ordering.
968
969        let id1 = SignerId::Dummy(1);
970        let id2 = SignerId::Dummy(2);
971        let id3 = SignerId::Dummy(3);
972        let id_nonexistent = SignerId::Dummy(999);
973
974        signers.add_external(id1.clone(), SignerOrdering(1), signer1.clone());
975        signers.add_external(id2.clone(), SignerOrdering(2), signer2.clone());
976        signers.add_external(id3.clone(), SignerOrdering(3), signer3.clone());
977
978        assert_matches!(signers.find(id1), Some(signer) if is_equal(signer, &signer1));
979        assert_matches!(signers.find(id2), Some(signer) if is_equal(signer, &signer2));
980        assert_matches!(signers.find(id3.clone()), Some(signer) if is_equal(signer, &signer3));
981
982        // The `signer4` has the same ID as `signer3` but lower ordering.
983        // It should be found by `id3` instead of `signer3`.
984        signers.add_external(id3.clone(), SignerOrdering(2), signer4.clone());
985        assert_matches!(signers.find(id3), Some(signer) if is_equal(signer, &signer4));
986
987        // Can't find anything with ID that doesn't exist
988        assert_matches!(signers.find(id_nonexistent), None);
989    }
990
991    #[derive(Debug, Clone, Copy)]
992    struct DummySigner {
993        number: u64,
994    }
995
996    impl SignerCommon for DummySigner {
997        fn id(&self, _secp: &SecpCtx) -> SignerId {
998            SignerId::Dummy(self.number)
999        }
1000    }
1001
1002    impl TransactionSigner for DummySigner {
1003        fn sign_transaction(
1004            &self,
1005            _psbt: &mut Psbt,
1006            _sign_options: &SignOptions,
1007            _secp: &SecpCtx,
1008        ) -> Result<(), SignerError> {
1009            Ok(())
1010        }
1011    }
1012
1013    const TPRV0_STR:&str = "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf";
1014    const TPRV1_STR:&str = "tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N";
1015
1016    const PATH: &str = "m/44'/1'/0'/0";
1017
1018    fn setup_keys<Ctx: ScriptContext>(
1019        tprv: &str,
1020    ) -> (DescriptorKey<Ctx>, DescriptorKey<Ctx>, Fingerprint) {
1021        let secp: Secp256k1<All> = Secp256k1::new();
1022        let path = bip32::DerivationPath::from_str(PATH).unwrap();
1023        let tprv = bip32::Xpriv::from_str(tprv).unwrap();
1024        let tpub = bip32::Xpub::from_priv(&secp, &tprv);
1025        let fingerprint = tprv.fingerprint(&secp);
1026        let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
1027        let pubkey = (tpub, path).into_descriptor_key().unwrap();
1028
1029        (prvkey, pubkey, fingerprint)
1030    }
1031}