From 97b6fb06aa6d95d1c8cf1498cc4478d0f27423e4 Mon Sep 17 00:00:00 2001 From: rajarshimaitra Date: Fri, 2 Sep 2022 15:26:21 +0530 Subject: [PATCH] Add a policy example Add a new policy example demonstrating the bdk's policy structure and how to derive it for any descriptor without creating a bdk wallet. --- Cargo.toml | 4 +++ examples/policy.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 examples/policy.rs diff --git a/Cargo.toml b/Cargo.toml index 165a7b4b..fef5e62c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,6 +113,10 @@ name = "miniscriptc" path = "examples/compiler.rs" required-features = ["compiler"] +[[example]] +name = "policy" +path = "examples/policy.rs" + [[example]] name = "rpcwallet" path = "examples/rpcwallet.rs" diff --git a/examples/policy.rs b/examples/policy.rs new file mode 100644 index 00000000..64e17825 --- /dev/null +++ b/examples/policy.rs @@ -0,0 +1,66 @@ +// Bitcoin Dev Kit +// Written in 2020 by Alekos Filini +// +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , 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> { + 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, , ))" + 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(()) +}