Skip to content

Commit

Permalink
Add support for BIP47 (reusable payment codes)
Browse files Browse the repository at this point in the history
  • Loading branch information
afilini committed Mar 21, 2022
1 parent 0114805 commit f966cbf
Show file tree
Hide file tree
Showing 6 changed files with 903 additions and 16 deletions.
28 changes: 19 additions & 9 deletions src/keys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ use bitcoin::secp256k1::{self, Secp256k1, Signing};
use bitcoin::util::bip32;
use bitcoin::{Network, PrivateKey, PublicKey};

use miniscript::descriptor::{Descriptor, DescriptorXKey, Wildcard};
use miniscript::descriptor::{Descriptor, Wildcard};
pub use miniscript::descriptor::{
DescriptorPublicKey, DescriptorSecretKey, DescriptorSinglePriv, DescriptorSinglePub, KeyMap,
SortedMultiVec,
DescriptorPublicKey, DescriptorSecretKey, DescriptorSinglePriv, DescriptorSinglePub,
DescriptorXKey, KeyMap, SortedMultiVec,
};
pub use miniscript::ScriptContext;
use miniscript::{Miniscript, Terminal};
Expand Down Expand Up @@ -94,6 +94,13 @@ impl<Ctx: ScriptContext> DescriptorKey<Ctx> {
}
}

pub fn as_public(&self, secp: &SecpCtx) -> Result<DescriptorPublicKey, KeyError> {
match self {
DescriptorKey::Public(pk, _, _) => Ok(pk.clone()),
DescriptorKey::Secret(secret, _, _) => Ok(secret.as_public(secp)?),
}
}

// This method is used internally by `bdk::fragment!` and `bdk::descriptor!`. It has to be
// public because it is effectively called by external crates, once the macros are expanded,
// but since it is not meant to be part of the public api we hide it from the docs.
Expand All @@ -102,18 +109,15 @@ impl<Ctx: ScriptContext> DescriptorKey<Ctx> {
self,
secp: &SecpCtx,
) -> Result<(DescriptorPublicKey, KeyMap, ValidNetworks), KeyError> {
let public = self.as_public(secp)?;

match self {
DescriptorKey::Public(public, valid_networks, _) => {
DescriptorKey::Public(_, valid_networks, _) => {
Ok((public, KeyMap::default(), valid_networks))
}
DescriptorKey::Secret(secret, valid_networks, _) => {
let mut key_map = KeyMap::with_capacity(1);

let public = secret
.as_public(secp)
.map_err(|e| miniscript::Error::Unexpected(e.to_string()))?;
key_map.insert(public.clone(), secret);

Ok((public, key_map, valid_networks))
}
}
Expand Down Expand Up @@ -891,9 +895,15 @@ pub enum KeyError {
Bip32(bitcoin::util::bip32::Error),
/// Miniscript error
Miniscript(miniscript::Error),
KeyParseError(miniscript::descriptor::DescriptorKeyParseError),
}

impl_error!(miniscript::Error, Miniscript, KeyError);
impl_error!(
miniscript::descriptor::DescriptorKeyParseError,
KeyParseError,
KeyError
);
impl_error!(bitcoin::util::bip32::Error, Bip32, KeyError);

impl std::fmt::Display for KeyError {
Expand Down
16 changes: 9 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ pub extern crate sled;
#[cfg(feature = "sqlite")]
pub extern crate rusqlite;

// We should consider putting this under a feature flag but we need the macro in doctests so we need
// to wait until https://github.com/rust-lang/rust/issues/67295 is fixed.
//
// Stuff in here is too rough to document atm
#[doc(hidden)]
#[macro_use]
pub mod testutils;

#[allow(unused_imports)]
#[macro_use]
pub(crate) mod error;
Expand All @@ -262,6 +270,7 @@ mod doctest;
pub mod keys;
pub(crate) mod psbt;
pub(crate) mod types;
pub mod utils;
pub mod wallet;

pub use descriptor::template;
Expand All @@ -279,10 +288,3 @@ pub use wallet::Wallet;
pub fn version() -> &'static str {
env!("CARGO_PKG_VERSION", "unknown")
}

// We should consider putting this under a feature flag but we need the macro in doctests so we need
// to wait until https://github.com/rust-lang/rust/issues/67295 is fixed.
//
// Stuff in here is too rough to document atm
#[doc(hidden)]
pub mod testutils;
2 changes: 2 additions & 0 deletions src/testutils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,5 @@ macro_rules! testutils {
(external, internal)
})
}

pub use testutils;
Loading

0 comments on commit f966cbf

Please sign in to comment.