Skip to content

Commit 23d8cfa

Browse files
committed
feat: update signer impl for XOnlyPubkey
1 parent 4f8a213 commit 23d8cfa

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/signer.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use alloc::string::ToString;
2+
use std::collections::BTreeMap;
23

34
use bitcoin::{
45
psbt::{GetKey, GetKeyError, KeyRequest},
@@ -24,10 +25,9 @@ impl GetKey for Signer {
2425
for entry in &self.0 {
2526
match entry {
2627
(_, DescriptorSecretKey::Single(prv)) => {
27-
let pk = prv.key.public_key(secp);
28-
if key_request == KeyRequest::Pubkey(pk) {
29-
return Ok(Some(prv.key));
30-
}
28+
let map: BTreeMap<_, _> =
29+
core::iter::once((prv.key.public_key(secp), prv.key)).collect();
30+
return GetKey::get_key(&map, key_request, secp);
3131
}
3232
(_, desc_sk) => {
3333
for desc_sk in desc_sk.clone().into_single_keys() {
@@ -89,6 +89,26 @@ mod test {
8989
Ok(())
9090
}
9191

92+
#[test]
93+
fn get_key_x_only_pubkey() -> anyhow::Result<()> {
94+
let secp = Secp256k1::new();
95+
let wif = "cU6BxEezV8FnkEPBCaFtc4WNuUKmgFaAu6sJErB154GXgMUjhgWe";
96+
let prv = bitcoin::PrivateKey::from_wif(wif)?;
97+
let (x_only_pk, _parity) = prv.inner.x_only_public_key(&secp);
98+
99+
let s = format!("wpkh({wif})");
100+
let (_, keymap) = Descriptor::parse_descriptor(&secp, &s).unwrap();
101+
102+
let signer = Signer(keymap);
103+
let req = KeyRequest::XOnlyPubkey(x_only_pk);
104+
let res = signer.get_key(req, &secp);
105+
assert!(matches!(
106+
res,
107+
Ok(Some(k)) if k.inner.x_only_public_key(&secp).0 == x_only_pk
108+
));
109+
Ok(())
110+
}
111+
92112
// Test `Signer` can fulfill a bip32 KeyRequest if we know the key origin
93113
#[test]
94114
fn get_key_bip32() -> anyhow::Result<()> {

0 commit comments

Comments
 (0)