1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#![cfg_attr(not(test), deny(clippy::unwrap_used))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

//! Contains a software signer [`SwSigner`] and an [`AnySigner`] that can be a Jade or a Software signer.
//!
//! Signers should implement [`lwk_common::Signer`]

mod software;

pub use crate::software::{NewError, SignError, SwSigner};
pub use bip39;

use elements_miniscript::bitcoin::bip32::DerivationPath;
use elements_miniscript::elements::bitcoin::bip32::Xpub;
use elements_miniscript::elements::pset::PartiallySignedTransaction;
use lwk_common::Signer;

/// Possible errors when signing with [`AnySigner`]
#[derive(thiserror::Error, Debug)]
pub enum SignerError {
    #[error(transparent)]
    Software(#[from] SignError),

    #[cfg(feature = "jade")]
    #[error(transparent)]
    JadeError(#[from] lwk_jade::error::Error),

    #[error(transparent)]
    Bip32Error(#[from] elements::bitcoin::bip32::Error),
}

/// A signer that can be a software signer [`SwSigner`] or a [`lwk_jade::Jade`]
#[derive(Debug)]
pub enum AnySigner {
    Software(SwSigner),

    #[cfg(feature = "jade")]
    Jade(lwk_jade::Jade, elements_miniscript::bitcoin::XKeyIdentifier),
}

impl Signer for AnySigner {
    type Error = SignerError;

    fn sign(&self, pset: &mut PartiallySignedTransaction) -> Result<u32, Self::Error> {
        Signer::sign(&self, pset)
    }

    fn derive_xpub(&self, path: &DerivationPath) -> Result<Xpub, Self::Error> {
        Signer::derive_xpub(&self, path)
    }

    fn slip77_master_blinding_key(
        &self,
    ) -> Result<elements_miniscript::slip77::MasterBlindingKey, Self::Error> {
        Signer::slip77_master_blinding_key(&self)
    }
}

impl Signer for &AnySigner {
    type Error = SignerError;

    fn sign(&self, pset: &mut PartiallySignedTransaction) -> Result<u32, Self::Error> {
        Ok(match self {
            AnySigner::Software(signer) => signer.sign(pset)?,

            #[cfg(feature = "jade")]
            AnySigner::Jade(signer, _) => signer.sign(pset)?,
        })
    }

    fn derive_xpub(&self, path: &DerivationPath) -> Result<Xpub, Self::Error> {
        Ok(match self {
            AnySigner::Software(s) => s.derive_xpub(path)?,

            #[cfg(feature = "jade")]
            AnySigner::Jade(s, _) => s.derive_xpub(path)?,
        })
    }

    fn slip77_master_blinding_key(
        &self,
    ) -> Result<elements_miniscript::slip77::MasterBlindingKey, Self::Error> {
        Ok(match self {
            AnySigner::Software(s) => s.slip77_master_blinding_key()?,

            #[cfg(feature = "jade")]
            AnySigner::Jade(s, _) => s.slip77_master_blinding_key()?,
        })
    }
}