Skip to content

Commit b819375

Browse files
committed
wip(test-utils): impl GetKey for DescriptorSecretKey
1 parent 0683fb3 commit b819375

File tree

1 file changed

+83
-70
lines changed

1 file changed

+83
-70
lines changed

wallet/src/test_utils.rs

Lines changed: 83 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::collections::BTreeMap;
1212
use bdk_chain::{BlockId, ConfirmationBlockTime, TxUpdate};
1313
use bitcoin::{
1414
absolute,
15+
bip32::DerivationPath,
1516
hashes::Hash,
1617
key::Secp256k1,
1718
psbt::{GetKey, GetKeyError, KeyRequest},
@@ -42,81 +43,93 @@ impl GetKey for SignerWrapper {
4243
key_request: KeyRequest,
4344
secp: &bitcoin::key::Secp256k1<C>,
4445
) -> Result<Option<bitcoin::PrivateKey>, Self::Error> {
45-
for (descriptor_pk, descriptor_sk) in self.key_map.iter() {
46-
match (descriptor_sk, key_request.clone()) {
47-
(DescriptorSecretKey::Single(single_priv), key_request) => {
48-
let private_key = single_priv.key;
49-
let public_key = private_key.public_key(secp);
50-
let keys = BTreeMap::from([(public_key, private_key)]);
51-
match keys.get_key(key_request, secp) {
52-
Ok(Some(pk)) => return Ok(Some(pk)),
53-
Ok(None) => continue,
54-
Err(e) => return Err(e),
55-
}
46+
for (_, descriptor_sk) in self.key_map.iter() {
47+
let wrapper = DescriptorSecretKeyWrapper::new(descriptor_sk.clone());
48+
match wrapper.get_key(key_request.clone(), secp) {
49+
Ok(Some(key)) => return Ok(Some(key)),
50+
Ok(None) => continue,
51+
Err(e) => return Err(e),
52+
}
53+
}
54+
Ok(None)
55+
}
56+
}
57+
/// TODO: (@leonardo) add a documentation if this stays in bdk.
58+
pub struct DescriptorSecretKeyWrapper {
59+
secret_key: DescriptorSecretKey,
60+
}
61+
62+
impl DescriptorSecretKeyWrapper {
63+
/// .
64+
pub fn new(secret_key: DescriptorSecretKey) -> Self {
65+
Self { secret_key }
66+
}
67+
}
68+
69+
impl GetKey for DescriptorSecretKeyWrapper {
70+
type Error = GetKeyError;
71+
72+
fn get_key<C: bitcoin::secp256k1::Signing>(
73+
&self,
74+
key_request: KeyRequest,
75+
secp: &Secp256k1<C>,
76+
) -> Result<Option<bitcoin::PrivateKey>, Self::Error> {
77+
match (self.secret_key.clone(), key_request) {
78+
(DescriptorSecretKey::Single(single_priv), key_request) => {
79+
let private_key = single_priv.key;
80+
let public_key = private_key.public_key(secp);
81+
let keys = BTreeMap::from([(public_key, private_key)]);
82+
return keys.get_key(key_request, secp);
83+
}
84+
(DescriptorSecretKey::XPrv(descriptor_xkey), KeyRequest::Pubkey(public_key)) => {
85+
let xpriv = descriptor_xkey.xkey;
86+
let private_key = xpriv.private_key;
87+
let pk = private_key.public_key(secp);
88+
if public_key.inner.eq(&pk) {
89+
return Ok(Some(
90+
descriptor_xkey
91+
.xkey
92+
.derive_priv(secp, &descriptor_xkey.derivation_path)?
93+
.to_priv(),
94+
));
5695
}
57-
(DescriptorSecretKey::XPrv(descriptor_xkey), KeyRequest::Pubkey(public_key)) => {
58-
match descriptor_pk {
59-
DescriptorPublicKey::XPub(descriptor_xpub) => {
60-
let xpub = descriptor_xpub.xkey;
61-
match xpub.public_key.eq(&public_key.inner) {
62-
true => {
63-
return Ok(Some(
64-
descriptor_xkey
65-
.xkey
66-
.derive_priv(secp, &descriptor_xkey.derivation_path)?
67-
.to_priv(),
68-
))
69-
}
70-
false => continue,
71-
}
72-
}
73-
_ => unreachable!(),
74-
}
96+
}
97+
(
98+
DescriptorSecretKey::XPrv(descriptor_xkey),
99+
ref key_request @ KeyRequest::Bip32(ref key_source),
100+
) => {
101+
if let Some(key) = descriptor_xkey.xkey.get_key(key_request.clone(), secp)? {
102+
return Ok(Some(key));
75103
}
76-
(
77-
DescriptorSecretKey::XPrv(descriptor_xkey),
78-
ref key_request @ KeyRequest::Bip32(ref key_source),
79-
) => {
80-
let xpriv = descriptor_xkey.xkey;
81-
match xpriv.get_key(key_request.clone(), secp) {
82-
Ok(Some(private_key)) => return Ok(Some(private_key)),
83-
Ok(None) => match descriptor_xkey.matches(key_source, secp) {
84-
Some(_derivation_path) => match &descriptor_xkey.origin {
85-
Some((_origin_fingerprint, origin_derivation_path)) => {
86-
let (_fingerprint, derivation_path) = key_source;
87-
let derivation_path =
88-
&derivation_path[origin_derivation_path.len()..];
89-
return Ok(Some(
90-
descriptor_xkey
91-
.xkey
92-
.derive_priv(secp, &derivation_path)?
93-
.to_priv(),
94-
));
95-
}
96-
None => {
97-
let (_fingerprint, derivation_path) = key_source;
98-
return Ok(Some(
99-
descriptor_xkey
100-
.xkey
101-
.derive_priv(secp, &derivation_path)?
102-
.to_priv(),
103-
));
104-
}
105-
},
106-
None => continue,
107-
},
108-
Err(e) => return Err(e),
109-
}
104+
105+
if let Some(_derivation_path) = descriptor_xkey.matches(key_source, secp) {
106+
let derivation_path: &DerivationPath = match &descriptor_xkey.origin {
107+
Some((_fp, origin_derivation_path)) => {
108+
let (_fp, derivation_path) = key_source;
109+
&derivation_path[origin_derivation_path.len()..].into()
110+
}
111+
None => {
112+
let (_fp, derivation_path) = key_source;
113+
derivation_path
114+
}
115+
};
116+
117+
return Ok(Some(
118+
descriptor_xkey
119+
.xkey
120+
.derive_priv(secp, derivation_path)?
121+
.to_priv(),
122+
));
110123
}
111-
(
112-
DescriptorSecretKey::XPrv(_descriptor_xkey),
113-
KeyRequest::XOnlyPubkey(_xonly_public_key),
114-
) => return Err(GetKeyError::NotSupported), // TODO: (@leonardo) should we handle this ?
115-
(DescriptorSecretKey::MultiXPrv(_descriptor_multi_xkey), _) => unimplemented!(),
116-
_ => unreachable!(),
117124
}
125+
(
126+
DescriptorSecretKey::XPrv(descriptor_xkey),
127+
KeyRequest::XOnlyPubkey(xonly_public_key),
128+
) => return Err(GetKeyError::NotSupported),
129+
(DescriptorSecretKey::MultiXPrv(_), _) => unimplemented!(),
130+
_ => unreachable!(),
118131
}
119-
Ok(None)
132+
return Ok(None);
120133
}
121134
}
122135

0 commit comments

Comments
 (0)