1+ //! Common signing utilities for bdk_wallet examples
2+ //!
3+ //! This module provides the `SignerWrapper` struct and related utilities
4+ //! that enable signing functionality for the wallet examples. These utilities
5+ //! wrap the KeyMap type to implement the GetKey trait, allowing examples
6+ //! to sign transactions and PSBTs.
7+ //!
8+ //! Note: This module is only required temporarily until miniscript 12.x is released,
9+ //! which will include signing capabilities for KeyMap natively.
10+
11+ use miniscript:: descriptor:: { DescriptorSecretKey , KeyMap } ;
12+ use std:: collections:: BTreeMap ;
13+
14+ use bitcoin:: {
15+ key:: Secp256k1 ,
16+ psbt:: { GetKey , GetKeyError , KeyRequest } ,
17+ } ;
18+
19+ #[ derive( Debug , Clone ) ]
20+ /// A wrapper over the [`KeyMap`] type that has the `GetKey` trait implementation for signing.
21+ pub struct SignerWrapper {
22+ key_map : KeyMap ,
23+ }
24+
25+ impl SignerWrapper {
26+ /// Creates a new [`SignerWrapper`] for the given [`KeyMap`].
27+ pub fn new ( key_map : KeyMap ) -> Self {
28+ Self { key_map }
29+ }
30+ }
31+
32+ impl GetKey for SignerWrapper {
33+ type Error = GetKeyError ;
34+
35+ fn get_key < C : bitcoin:: secp256k1:: Signing > (
36+ & self ,
37+ key_request : KeyRequest ,
38+ secp : & bitcoin:: key:: Secp256k1 < C > ,
39+ ) -> Result < Option < bitcoin:: PrivateKey > , Self :: Error > {
40+ for key_map in self . key_map . iter ( ) {
41+ let ( _, desc_sk) = key_map;
42+ let wrapper = DescriptorSecretKeyWrapper :: new ( desc_sk. clone ( ) ) ;
43+ match wrapper. get_key ( key_request. clone ( ) , secp) {
44+ Ok ( Some ( private_key) ) => return Ok ( Some ( private_key) ) ,
45+ Ok ( None ) => continue ,
46+ // TODO: (@leonardo) how should we handle this ?
47+ // we can't error-out on this, because the valid signing key can be in the next
48+ // iterations.
49+ Err ( _) => continue ,
50+ }
51+ }
52+ Ok ( None )
53+ }
54+ }
55+
56+ /// Wrapper for DescriptorSecretKey to implement GetKey trait
57+ pub struct DescriptorSecretKeyWrapper ( DescriptorSecretKey ) ;
58+
59+ impl DescriptorSecretKeyWrapper {
60+ /// Creates a new DescriptorSecretKeyWrapper
61+ pub fn new ( desc_sk : DescriptorSecretKey ) -> Self {
62+ Self ( desc_sk)
63+ }
64+ }
65+
66+ impl GetKey for DescriptorSecretKeyWrapper {
67+ type Error = GetKeyError ;
68+
69+ fn get_key < C : bitcoin:: secp256k1:: Signing > (
70+ & self ,
71+ key_request : KeyRequest ,
72+ secp : & Secp256k1 < C > ,
73+ ) -> Result < Option < bitcoin:: PrivateKey > , Self :: Error > {
74+ match ( & self . 0 , key_request) {
75+ ( DescriptorSecretKey :: Single ( single_priv) , key_request) => {
76+ let private_key = single_priv. key ;
77+ let public_key = private_key. public_key ( secp) ;
78+ let pubkey_map = BTreeMap :: from ( [ ( public_key, private_key) ] ) ;
79+ return pubkey_map. get_key ( key_request, secp) ;
80+ }
81+ ( DescriptorSecretKey :: XPrv ( descriptor_xkey) , KeyRequest :: Pubkey ( public_key) ) => {
82+ let private_key = descriptor_xkey. xkey . private_key ;
83+ let pk = private_key. public_key ( secp) ;
84+ if public_key. inner . eq ( & pk) {
85+ return Ok ( Some (
86+ descriptor_xkey
87+ . xkey
88+ . derive_priv ( secp, & descriptor_xkey. derivation_path )
89+ . map_err ( GetKeyError :: Bip32 ) ?
90+ . to_priv ( ) ,
91+ ) ) ;
92+ }
93+ }
94+ (
95+ DescriptorSecretKey :: XPrv ( descriptor_xkey) ,
96+ ref key_request @ KeyRequest :: Bip32 ( ref key_source) ,
97+ ) => {
98+ if let Some ( key) = descriptor_xkey. xkey . get_key ( key_request. clone ( ) , secp) ? {
99+ return Ok ( Some ( key) ) ;
100+ }
101+
102+ if let Some ( _derivation_path) = descriptor_xkey. matches ( key_source, secp) {
103+ let ( _fp, derivation_path) = key_source;
104+
105+ if let Some ( ( _fp, origin_derivation_path) ) = & descriptor_xkey. origin {
106+ let derivation_path = & derivation_path[ origin_derivation_path. len ( ) ..] ;
107+ return Ok ( Some (
108+ descriptor_xkey
109+ . xkey
110+ . derive_priv ( secp, & derivation_path)
111+ . map_err ( GetKeyError :: Bip32 ) ?
112+ . to_priv ( ) ,
113+ ) ) ;
114+ } else {
115+ return Ok ( Some (
116+ descriptor_xkey
117+ . xkey
118+ . derive_priv ( secp, derivation_path)
119+ . map_err ( GetKeyError :: Bip32 ) ?
120+ . to_priv ( ) ,
121+ ) ) ;
122+ } ;
123+ }
124+ }
125+ ( DescriptorSecretKey :: XPrv ( _) , KeyRequest :: XOnlyPubkey ( _) ) => {
126+ return Err ( GetKeyError :: NotSupported )
127+ }
128+ ( DescriptorSecretKey :: MultiXPrv ( _) , _) => unimplemented ! ( ) ,
129+ _ => unreachable ! ( ) ,
130+ }
131+ Ok ( None )
132+ }
133+ }
0 commit comments