-
Notifications
You must be signed in to change notification settings - Fork 307
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge #730: Update compiler example to a Policy example
97b6fb0 Add a policy example (rajarshimaitra) da76708 Update compiler example. (rajarshimaitra) Pull request description: ### Description Fixes #729. There is an "unmaintained" warning in a old version of clap, which triggered the issue. Ideally, we should not have clap in bdk's dependency. It was only used for the `compiler.rs` example, which was a very tiny clap app compiling miniscript policies, and it wasn't really an example for bdk. This PR rewrites the example as a `policy.rs` which demos the BDK's Policy module and policy structures. - Use a `wsh(multi(2, Privkey, Pubkey))` descriptor, which has only one part private and other part public. - use `into_wallet_descriptor()` to turn that into a `Descriptor` and `KeyMap`. - Use the `KeyMap` to create a custom signer. - Extract the descriptor `Policy` structure from the given keymap. I am not very sure on how much this example is helpful. I still find it hard to read the Policy structure visually. But if Policy is something we want the user to know about descriptors and bdk wallets, this shows how to extract it for a simple multisig condition. Note: There is no use of `bdk::wallet` in the example. BDK uses the Policy extraction internally while transaction creation. But all these are exposed publicly, so can be used independently too. ### Questions: - Should we still have a `minscript::policy::compile()` example? Which IIUC is very different from `bdk::policy:Policy`. I didn't include it in this PR, because I am not sure if it fits inside bdk example categories. - Should we expose `extract_policy` as an wallet API? All though its possible to get policy without creating a wallet, why not let the wallet also spit one out for itself, if its useful? ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing ACKs for top commit: afilini: ACK 97b6fb0 Tree-SHA512: 8e3719fdad308a347d22377050b2f29e02a884ff7d4e57a05a06d078de0709b5bf70bbcb1a696d1e1cdfe02cdb470e5af643da7c775b67fe318046bd6b80f440
- Loading branch information
Showing
3 changed files
with
101 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Bitcoin Dev Kit | ||
// Written in 2020 by Alekos Filini <alekos.filini@gmail.com> | ||
// | ||
// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers | ||
// | ||
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE | ||
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. | ||
// You may not use this file except in accordance with one or both of these | ||
// licenses. | ||
|
||
extern crate bdk; | ||
extern crate env_logger; | ||
extern crate log; | ||
use std::error::Error; | ||
|
||
use bdk::bitcoin::Network; | ||
use bdk::descriptor::{policy::BuildSatisfaction, ExtractPolicy, IntoWalletDescriptor}; | ||
use bdk::wallet::signer::SignersContainer; | ||
|
||
/// This example describes the use of the BDK's [`bdk::descriptor::policy`] module. | ||
/// | ||
/// Policy is higher abstraction representation of the wallet descriptor spending condition. | ||
/// This is useful to express complex miniscript spending conditions into more human readable form. | ||
/// The resulting `Policy` structure can be used to derive spending conditions the wallet is capable | ||
/// to spend from. | ||
/// | ||
/// This example demos a Policy output for a 2of2 multisig between between 2 parties, where the wallet holds | ||
/// one of the Extend Private key. | ||
|
||
fn main() -> Result<(), Box<dyn Error>> { | ||
env_logger::init_from_env( | ||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), | ||
); | ||
|
||
let secp = bitcoin::secp256k1::Secp256k1::new(); | ||
|
||
// The descriptor used in the example | ||
// The form is "wsh(multi(2, <privkey>, <pubkey>))" | ||
let desc = "wsh(multi(2,tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/*,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/*))"; | ||
|
||
// Use the descriptor string to derive the full descriptor and a keymap. | ||
// The wallet descriptor can be used to create a new bdk::wallet. | ||
// While the `keymap` can be used to create a `SignerContainer`. | ||
// | ||
// The `SignerContainer` can sign for `PSBT`s. | ||
// a bdk::wallet internally uses these to handle transaction signing. | ||
// But they can be used as independent tools also. | ||
let (wallet_desc, keymap) = desc.into_wallet_descriptor(&secp, Network::Testnet)?; | ||
|
||
log::info!("Example Descriptor for policy analysis : {}", wallet_desc); | ||
|
||
// Create the signer with the keymap and descriptor. | ||
let signers_container = SignersContainer::build(keymap, &wallet_desc, &secp); | ||
|
||
// Extract the Policy from the given descriptor and signer. | ||
// Note that Policy is a wallet specific structure. It depends on the the descriptor, and | ||
// what the concerned wallet with a given signer can sign for. | ||
let policy = wallet_desc | ||
.extract_policy(&signers_container, BuildSatisfaction::None, &secp)? | ||
.expect("We expect a policy"); | ||
|
||
log::info!("Derived Policy for the descriptor {:#?}", policy); | ||
|
||
Ok(()) | ||
} |