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