Merge branch 'master' into release/0.18.0

This commit is contained in:
Steve Myers 2022-04-14 10:06:47 -07:00
commit 502882d27c
No known key found for this signature in database
GPG Key ID: 8105A46B22C2D051
4 changed files with 42 additions and 18 deletions

View File

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `Wallet::get_signers()`, `Wallet::descriptor_checksum()` and `Wallet::get_address_validators()`, exposed the `AsDerived` trait. - Added `Wallet::get_signers()`, `Wallet::descriptor_checksum()` and `Wallet::get_address_validators()`, exposed the `AsDerived` trait.
- Deprecate `database::Database::flush()`, the function is only needed for the sled database on mobile, instead for mobile use the sqlite database. - Deprecate `database::Database::flush()`, the function is only needed for the sled database on mobile, instead for mobile use the sqlite database.
- Add `keychain: KeychainKind` to `wallet::AddressInfo`. - Add `keychain: KeychainKind` to `wallet::AddressInfo`.
- Improve key generation traits
## [v0.17.0] - [v0.16.1] ## [v0.17.0] - [v0.16.1]
@ -447,4 +448,4 @@ final transaction is created by calling `finish` on the builder.
[v0.16.1]: https://github.com/bitcoindevkit/bdk/compare/v0.16.0...v0.16.1 [v0.16.1]: https://github.com/bitcoindevkit/bdk/compare/v0.16.0...v0.16.1
[v0.17.0]: https://github.com/bitcoindevkit/bdk/compare/v0.16.1...v0.17.0 [v0.17.0]: https://github.com/bitcoindevkit/bdk/compare/v0.16.1...v0.17.0
[v0.18.0]: https://github.com/bitcoindevkit/bdk/compare/v0.17.0...v0.18.0 [v0.18.0]: https://github.com/bitcoindevkit/bdk/compare/v0.17.0...v0.18.0
[unreleased]: https://github.com/bitcoindevkit/bdk/compare/v0.18.0...HEAD [unreleased]: https://github.com/bitcoindevkit/bdk/compare/v0.18.0...HEAD

View File

@ -7,7 +7,6 @@
// licenses. // licenses.
use bdk::bitcoin::secp256k1::Secp256k1; use bdk::bitcoin::secp256k1::Secp256k1;
use bdk::bitcoin::util::bip32::ExtendedPrivKey;
use bdk::bitcoin::Amount; use bdk::bitcoin::Amount;
use bdk::bitcoin::Network; use bdk::bitcoin::Network;
use bdk::bitcoincore_rpc::RpcApi; use bdk::bitcoincore_rpc::RpcApi;
@ -16,7 +15,7 @@ use bdk::blockchain::rpc::{Auth, RpcBlockchain, RpcConfig};
use bdk::blockchain::ConfigurableBlockchain; use bdk::blockchain::ConfigurableBlockchain;
use bdk::keys::bip39::{Language, Mnemonic, WordCount}; use bdk::keys::bip39::{Language, Mnemonic, WordCount};
use bdk::keys::{DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey}; use bdk::keys::{DerivableKey, GeneratableKey, GeneratedKey};
use bdk::miniscript::miniscript::Segwitv0; use bdk::miniscript::miniscript::Segwitv0;
@ -85,8 +84,8 @@ fn main() -> Result<(), Box<dyn Error>> {
// create unique wallet name. // create unique wallet name.
// This is a special utility function exposed via `bdk::wallet_name_from_descriptor()` // This is a special utility function exposed via `bdk::wallet_name_from_descriptor()`
let wallet_name = wallet_name_from_descriptor( let wallet_name = wallet_name_from_descriptor(
Bip84(xprv, KeychainKind::External), Bip84(xprv.clone(), KeychainKind::External),
Some(Bip84(xprv, KeychainKind::Internal)), Some(Bip84(xprv.clone(), KeychainKind::Internal)),
Network::Regtest, Network::Regtest,
&Secp256k1::new(), &Secp256k1::new(),
)?; )?;
@ -112,8 +111,8 @@ fn main() -> Result<(), Box<dyn Error>> {
// Combine Database + Descriptor to create the final wallet // Combine Database + Descriptor to create the final wallet
let wallet = Wallet::new( let wallet = Wallet::new(
Bip84(xprv, KeychainKind::External), Bip84(xprv.clone(), KeychainKind::External),
Some(Bip84(xprv, KeychainKind::Internal)), Some(Bip84(xprv.clone(), KeychainKind::Internal)),
Network::Regtest, Network::Regtest,
database, database,
)?; )?;
@ -216,18 +215,15 @@ fn main() -> Result<(), Box<dyn Error>> {
// Helper function demonstrating privatekey extraction using bip39 mnemonic // Helper function demonstrating privatekey extraction using bip39 mnemonic
// The mnemonic can be shown to user to safekeeping and the same wallet // The mnemonic can be shown to user to safekeeping and the same wallet
// private descriptors can be recreated from it. // private descriptors can be recreated from it.
fn generate_random_ext_privkey() -> Result<ExtendedPrivKey, Box<dyn Error>> { fn generate_random_ext_privkey() -> Result<impl DerivableKey<Segwitv0> + Clone, Box<dyn Error>> {
// a Bip39 passphrase can be set optionally // a Bip39 passphrase can be set optionally
let password = Some("random password".to_string()); let password = Some("random password".to_string());
// Generate a random mnemonic, and use that to create an Extended PrivateKey // Generate a random mnemonic, and use that to create a "DerivableKey"
let mnemonic: GeneratedKey<_, Segwitv0> = let mnemonic: GeneratedKey<_, _> = Mnemonic::generate((WordCount::Words12, Language::English))
Mnemonic::generate((WordCount::Words12, Language::English)) .map_err(|e| e.expect("Unknown Error"))?;
.map_err(|e| e.expect("Unknown Error"))?;
let mnemonic = mnemonic.into_key(); // `Ok(mnemonic)` would also work if there's no passphrase and it would
let xkey: ExtendedKey = (mnemonic, password).into_extended_key()?; // yield the same result as this construct with `password` = `None`.
let xprv = xkey Ok((mnemonic, password))
.into_xprv(Network::Regtest)
.expect("Expected Private Key");
Ok(xprv)
} }

View File

@ -94,6 +94,23 @@ impl<Ctx: ScriptContext> DerivableKey<Ctx> for MnemonicWithPassphrase {
} }
} }
#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
impl<Ctx: ScriptContext> DerivableKey<Ctx> for (GeneratedKey<Mnemonic, Ctx>, Option<String>) {
fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
let (mnemonic, passphrase) = self;
(mnemonic.into_key(), passphrase).into_extended_key()
}
fn into_descriptor_key(
self,
source: Option<bip32::KeySource>,
derivation_path: bip32::DerivationPath,
) -> Result<DescriptorKey<Ctx>, KeyError> {
let (mnemonic, passphrase) = self;
(mnemonic.into_key(), passphrase).into_descriptor_key(source, derivation_path)
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))] #[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
impl<Ctx: ScriptContext> DerivableKey<Ctx> for Mnemonic { impl<Ctx: ScriptContext> DerivableKey<Ctx> for Mnemonic {
fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> { fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {

View File

@ -548,6 +548,16 @@ impl<K, Ctx: ScriptContext> Deref for GeneratedKey<K, Ctx> {
} }
} }
impl<K: Clone, Ctx: ScriptContext> Clone for GeneratedKey<K, Ctx> {
fn clone(&self) -> GeneratedKey<K, Ctx> {
GeneratedKey {
key: self.key.clone(),
valid_networks: self.valid_networks.clone(),
phantom: self.phantom,
}
}
}
// Make generated "derivable" keys themselves "derivable". Also make sure they are assigned the // Make generated "derivable" keys themselves "derivable". Also make sure they are assigned the
// right `valid_networks`. // right `valid_networks`.
impl<Ctx, K> DerivableKey<Ctx> for GeneratedKey<K, Ctx> impl<Ctx, K> DerivableKey<Ctx> for GeneratedKey<K, Ctx>