2021-03-03 13:22:05 -08:00
|
|
|
// Bitcoin Dev Kit
|
|
|
|
// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
|
2020-08-31 11:26:36 +02:00
|
|
|
//
|
2021-03-03 13:22:05 -08:00
|
|
|
// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
|
2020-08-31 11:26:36 +02:00
|
|
|
//
|
2021-03-03 13:22:05 -08:00
|
|
|
// 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.
|
2020-08-31 11:26:36 +02:00
|
|
|
|
2020-09-14 14:25:38 +02:00
|
|
|
extern crate bdk;
|
2020-04-29 11:52:45 +02:00
|
|
|
extern crate bitcoin;
|
|
|
|
extern crate log;
|
|
|
|
extern crate miniscript;
|
|
|
|
extern crate serde_json;
|
|
|
|
|
2021-02-02 20:06:40 -05:00
|
|
|
use std::error::Error;
|
2020-04-29 11:52:45 +02:00
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
use log::info;
|
|
|
|
|
|
|
|
use bitcoin::Network;
|
|
|
|
use miniscript::policy::Concrete;
|
|
|
|
use miniscript::Descriptor;
|
|
|
|
|
2020-09-14 14:25:38 +02:00
|
|
|
use bdk::database::memory::MemoryDatabase;
|
2021-03-08 16:17:10 -08:00
|
|
|
use bdk::wallet::AddressIndex::New;
|
2020-12-23 13:48:17 +11:00
|
|
|
use bdk::{KeychainKind, Wallet};
|
2020-04-29 11:52:45 +02:00
|
|
|
|
2022-08-21 17:43:14 +05:30
|
|
|
/// Miniscript policy is a high level abstraction of spending conditions. Defined in the
|
|
|
|
/// rust-miscript library here https://docs.rs/miniscript/7.0.0/miniscript/policy/index.html
|
|
|
|
/// rust-miniscript provides a `compile()` function that can be used to compile any miniscript policy
|
|
|
|
/// into a descriptor. This descriptor then in turn can be used in bdk a fully functioning wallet
|
|
|
|
/// can be derived from the policy.
|
|
|
|
///
|
|
|
|
/// This example demonstrates the interaction between a bdk wallet and miniscript policy.
|
|
|
|
|
2021-02-02 20:06:40 -05:00
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
2020-04-29 11:52:45 +02:00
|
|
|
env_logger::init_from_env(
|
|
|
|
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
|
|
|
);
|
|
|
|
|
2022-08-21 17:43:14 +05:30
|
|
|
// We start with a generic miniscript policy string
|
|
|
|
let policy_str = "or(10@thresh(4,pk(029ffbe722b147f3035c87cb1c60b9a5947dd49c774cc31e94773478711a929ac0),pk(025f05815e3a1a8a83bfbb03ce016c9a2ee31066b98f567f6227df1d76ec4bd143),pk(025625f41e4a065efc06d5019cbbd56fe8c07595af1231e7cbc03fafb87ebb71ec),pk(02a27c8b850a00f67da3499b60562673dcf5fdfb82b7e17652a7ac54416812aefd),pk(03e618ec5f384d6e19ca9ebdb8e2119e5bef978285076828ce054e55c4daf473e2)),1@and(older(4209713),thresh(2,pk(03deae92101c790b12653231439f27b8897264125ecb2f46f48278603102573165),pk(033841045a531e1adf9910a6ec279589a90b3b8a904ee64ffd692bd08a8996c1aa),pk(02aebf2d10b040eb936a6f02f44ee82f8b34f5c1ccb20ff3949c2b28206b7c1068))))";
|
|
|
|
info!("Compiling policy: \n{}", policy_str);
|
2020-04-29 11:52:45 +02:00
|
|
|
|
2022-08-21 17:43:14 +05:30
|
|
|
// Parse the string as a [`Concrete`] type miniscript policy.
|
2021-10-21 18:35:03 +02:00
|
|
|
let policy = Concrete::<String>::from_str(policy_str)?;
|
2020-04-29 11:52:45 +02:00
|
|
|
|
2022-08-21 17:43:14 +05:30
|
|
|
// Create a `wsh` type descriptor from the policy.
|
|
|
|
// `policy.compile()` returns the resulting miniscript from the policy.
|
|
|
|
let descriptor = Descriptor::new_wsh(policy.compile()?)?;
|
2020-04-29 11:52:45 +02:00
|
|
|
|
2022-08-21 17:43:14 +05:30
|
|
|
info!("Compiled into following Descriptor: \n{}", descriptor);
|
2020-04-29 11:52:45 +02:00
|
|
|
|
2020-08-08 09:37:25 +02:00
|
|
|
let database = MemoryDatabase::new();
|
2020-04-29 11:52:45 +02:00
|
|
|
|
2022-08-21 17:43:14 +05:30
|
|
|
// Create a new wallet from this descriptor
|
|
|
|
let wallet = Wallet::new(&format!("{}", descriptor), None, Network::Regtest, database)?;
|
|
|
|
|
|
|
|
info!(
|
|
|
|
"First derived address from the descriptor: \n{}",
|
|
|
|
wallet.get_address(New)?
|
|
|
|
);
|
|
|
|
|
|
|
|
// BDK also has it's own `Policy` structure to represent the spending condition in a more
|
|
|
|
// human readable json format.
|
|
|
|
let spending_policy = wallet.policies(KeychainKind::External)?;
|
|
|
|
info!(
|
|
|
|
"The BDK spending policy: \n{}",
|
|
|
|
serde_json::to_string_pretty(&spending_policy)?
|
|
|
|
);
|
2021-02-02 20:06:40 -05:00
|
|
|
|
|
|
|
Ok(())
|
2020-04-29 11:52:45 +02:00
|
|
|
}
|