]> Untitled Git - bitcoindevkit.org/commitdiff
Move tutorials from Blog to Tutorial section
authorrajarshimaitra <rajarshi149@gmail.com>
Fri, 10 Jun 2022 09:28:13 +0000 (14:58 +0530)
committerrajarshimaitra <rajarshi149@gmail.com>
Mon, 22 Aug 2022 12:33:03 +0000 (18:03 +0530)
13 files changed:
docs/.vuepress/config.js
docs/_blog/Bitcoin_Core_RPC_Demo.md [deleted file]
docs/_blog/compact_filters_demo.md [deleted file]
docs/_blog/descriptor_based_paper_wallet.md [deleted file]
docs/_blog/descriptors_in_the_wild.md [deleted file]
docs/_blog/hidden-power-of-bitcoin.md [deleted file]
docs/_blog/spending_policy_demo.md [deleted file]
docs/tutorials/Bitcoin_Core_RPC_Demo.md [new file with mode: 0644]
docs/tutorials/compact_filters_demo.md [new file with mode: 0644]
docs/tutorials/descriptor_based_paper_wallet.md [new file with mode: 0644]
docs/tutorials/descriptors_in_the_wild.md [new file with mode: 0644]
docs/tutorials/hidden-power-of-bitcoin.md [new file with mode: 0644]
docs/tutorials/spending_policy_demo.md [new file with mode: 0644]

index 60fe08942309962277c4aa46c79eec4035dbe8ef..cdebf6c271051da9db5e97a346c9b464446901ec 100644 (file)
@@ -48,6 +48,12 @@ const tutorialSidebar = [
     collapsable: false,
     children: [
       '/tutorials/hello-world',
+      '/tutorials/Bitcoin_Core_RPC_Demo',
+      '/tutorials/compact_filters_demo',
+      '/tutorials/descriptors_in_the_wild',
+      '/tutorials/hidden-power-of-bitcoin',
+      '/tutorials/descriptor_based_paper_wallet',
+      '/tutorials/spending_policy_demo'
     ],
   }
 ]
diff --git a/docs/_blog/Bitcoin_Core_RPC_Demo.md b/docs/_blog/Bitcoin_Core_RPC_Demo.md
deleted file mode 100644 (file)
index cff2d6f..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
----
-title: "Using BDK to build a wallet backed by a Bitcoin Core full node"
-description: "Tutorial showing usage of Bitcoin core backend with BDK wallet"
-authors:
-    - Rajarshi Maitra
-date: "2021-08-21"
-tags: ["tutorial", "BDK", "Bitcoin Core", "RPC", "Wallet"]
-hidden: true
-draft: false
----
-
-### Introduction
-BDK wallet developer library can be used to easily deploy wallets with various kinds of blockchain backend support, like [`electrum`](https://github.com/romanz/electrs), [`esplora`](https://github.com/Blockstream/esplora), `compact-filters` ([BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki)) etc. With the latest release of BDK [`v0.10.0`](https://github.com/bitcoindevkit/bdk/releases/tag/v0.10.0), BDK now supports Bitcoin Core as a blockchain backend. BDK talks with Bitcoin Core using rust-bitcoin's [bitcoincore-rpc](https://github.com/rust-bitcoin/rust-bitcoincore-rpc) library.
-
-This allows wallet devs to quickly deploy their wallet that can talk to a bitcoin full node (home raspi nodes) out of the box. Wallet devs don't need to worry about connecting to a full node with correct RPC calls, all of that is handled by BDK under the hood. All they need is to identify the full node's RPC IP address and the correct RPC credentials.
-
-In this tutorial we will see how to write a very simplistic wallet code that can connect to a bitcoin core node and maintain its balance and make transactions.
-
-Unlike other tutorials, we will not use `bdk-cli` tools, but instead write rust code directly using `BDK` devkit. In the end we will end up with our own simple bitcoin wallet.
-
-### Prerequisite
-To run with this tutorial you would need to have a bitcoin core node running in regtest mode. Get the bitcoin core binary either from the [bitcoin core repo](https://bitcoincore.org/bin/bitcoin-core-0.21.1/) or [build from source](https://github.com/bitcoin/bitcoin/blob/v0.21.1/doc/build-unix.md).
-
-Then configure the node with a following `bitcoin.conf` file
-```txt
-regtest=1
-fallbackfee=0.0001
-server=1
-txindex=1
-rpcuser=admin
-rpcpassword=password
-```
-
-Apart from that, you would need to install rust in your system. Grab the installation one-liner from [here](https://www.rust-lang.org/tools/install). 
-
-### Setting Up
-Create a new cargo binary repository.
-```shell
-mkdir ~/tutorial
-cd tutorial
-cargo new bdk-example
-cd bdk-example
-```
-This will create a new project folder named `bdk-example` with `src/main.rs` and a `cargo.toml`. 
-```shell
-$ tree -L 3 .
-.
-├── Cargo.toml
-└── src
-    └── main.rs
-
-1 directory, 2 files
-```
-Opening `main.rs` you will see some predefined code like this
-
-``` rust
-fn main() {
-    println!("Hello, world!");
-}
-```
-Try running `cargo run` and if everything is set, you should see "Hello, world!" printed in your terminal
-```shell
-$ cargo run
-    Compiling bdk-example v0.1.0 (/home/raj/github-repo/tutorial/bdk-example)
-    Finished dev [unoptimized + debuginfo] target(s) in 0.95s
-    Running `target/debug/bdk-example`
-Hello, world!
-```
-Of course we will not use the given `println!()` statement, but we will put our main code in the `main()` function.
-
-`cargo new` will also produce a skeleton `Cargo.toml` file like this
-```toml
-[package]
-name = "bdk-example"
-version = "0.1.0"
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-```
-
-### Setting dependencies
-Once the rust binary is compiled and running, we now need to specify the dependencies we need to work on our library.
-
-Remember that BDK provides almost everything we would need to build a wallet out of the box. So we don't need any more dependencies apart from BDK. We will use another small rust crate called [`dirs_next`](https://crates.io/crates/dirs-next) to find our home directory and store wallet files in a subfolder there.
-
-Add the dependencies into `Cargo.toml` like below
-```toml
-[package]
-name = "bdk-example"
-version = "0.1.0"
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-bdk = { version = "^0.10", default-features = false, features = ["all-keys", "key-value-db", "rpc"]}
-dirs-next = "2.0"
-```
-We disabled the default BDK feature (which specifies blockchain backend as an electrum server) and we requested the following features:
- - **all-keys**: Adds BIP39 key derivation capabilities
- - **key-value-db**: Adds a persistance storage capability
- - **rpc**: Adds the RPC blockchain backend capability.
-
-Now that we have the dependcies added, we can import them in the `main.rs` file to use in our code.
-Add the following imports at the start of `main.rs`
-
-```rust
-use bdk::bitcoin::Network;
-use bdk::bitcoin::secp256k1::Secp256k1;
-use bdk::bitcoin::util::bip32::{DerivationPath, KeySource};
-use bdk::bitcoin::Amount;
-use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};
-
-use bdk::blockchain::rpc::{Auth, RpcBlockchain, RpcConfig, wallet_name_from_descriptor};
-use bdk::blockchain::{ConfigurableBlockchain, NoopProgress};
-
-use bdk::keys::bip39::{Mnemonic, Language, MnemonicType};
-use bdk::keys::{GeneratedKey, GeneratableKey, ExtendedKey, DerivableKey, DescriptorKey};
-use bdk::keys::DescriptorKey::Secret;
-
-use bdk::miniscript::miniscript::Segwitv0;
-
-use bdk::Wallet;
-use bdk::wallet::{AddressIndex, signer::SignOptions};
-
-use bdk::sled;
-
-use std::str::FromStr;
-```
-With this we are now ready to add our wallet code.
-
-### Getting Descriptors
-
-BDK is a descriptor based wallet library. That means when we specify our wallet key-chain we need to tell BDK about it in the format of a descriptor. You can read up on descriptors more [here](https://bitcoindevkit.org/descriptors/). A descriptor string looks like this
-`"wpkh([b8b575c2/84'/1'/0'/0]tprv8icWtRzy9CWgFxpGMLSdAeE4wWyz39XGc6SwykeTo13tYm14JkVVQAf7jz8WDDarCgNJrG3aEPJEqchDWeJdiaWpS3FwbLB9SzsN57V7qxB/*)"`.
-
-This describes a SegwitV0 descriptor of a key derived at path `m/84'/1'/0'/0`. If you already have a descriptor from other sources, you can use that. Otherwise, BDK has your back. BDK can be used to generate a fresh master key with mnemonic, and then derive child keys from it given a specific path. Putting the key in a descriptor is as simple as wrapping it with a `wpkh()` string.
-
-We will use a dedicated function that will create fresh receive and change descriptors from BDK for our purpose. It will also generate the mnemonic word list for later regenerating the wallet. But we will ignore that for our scope.
-
-Add a function named `get-descriptor()` below the `main()` function as shown
-```rust
-fn main() {
-    ...
-}
-
-// generate fresh descriptor strings and return them via (receive, change) tuple
-fn get_descriptors() -> (String, String) {
-    // Create a new secp context
-    let secp = Secp256k1::new();
-     
-    // You can also set a password to unlock the mnemonic
-    let password = Some("random password".to_string());
-
-    // Generate a fresh mnemonic, and from there a privatekey
-    let mnemonic: GeneratedKey<_, Segwitv0> =
-                Mnemonic::generate((MnemonicType::Words12, Language::English)).unwrap();
-    let mnemonic = mnemonic.into_key();
-    let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
-    let xprv = xkey.into_xprv(Network::Regtest).unwrap();
-
-    // Create derived privkey from the above master privkey
-    // We use the following derivation paths for receive and change keys
-    // receive: "m/84h/1h/0h/0"
-    // change: "m/84h/1h/0h/1" 
-    let mut keys = Vec::new();
-
-    for path in ["m/84h/1h/0h/0", "m/84h/1h/0h/1"] {
-        let deriv_path: DerivationPath = DerivationPath::from_str(path).unwrap();
-        let derived_xprv = &xprv.derive_priv(&secp, &deriv_path).unwrap();
-        let origin: KeySource = (xprv.fingerprint(&secp), deriv_path);
-        let derived_xprv_desc_key: DescriptorKey<Segwitv0> =
-        derived_xprv.into_descriptor_key(Some(origin), DerivationPath::default()).unwrap();
-
-        // Wrap the derived key with the wpkh() string to produce a descriptor string
-        if let Secret(key, _, _) = derived_xprv_desc_key {
-            let mut desc = "wpkh(".to_string();
-            desc.push_str(&key.to_string());
-            desc.push_str(")");
-            keys.push(desc);
-        }
-    }
-    
-    // Return the keys as a tuple
-    (keys[0].clone(), keys[1].clone())
-}
-```
-
-To check that the above added function is working as expected, call it in the main function and print the descriptors
-``` rust
-use ...
-
-fn main() {
-    let (receive_desc, change_desc) = get_descriptors();
-    println!("recv: {:#?}, \nchng: {:#?}", receive_desc, change_desc);
-}
-
-fn get_descriptors() -> (String, String) {
-    ...
-}
-```
-Running the binary should produces the following result
-```shell
-$ cargo run
-recv: "wpkh([89df6a67/84'/1'/0'/0]tprv8iSRXyLtTKJN9qt1jyPVqwhDMEaYztXunPaRQznaH1z8gj8e2g7RnF2ZoHP56VEXwMn76AiV1Je6nJmZbFistwAQCrRGmSrsoKfdqfTDNA1/*)", 
-chng: "wpkh([89df6a67/84'/1'/0'/1]tprv8iSRXyLtTKJNCECQxBJ19cgx2ueS7mC7GNq7VqTWY3RNPMBY7DfTb9HUnXpJqa14jCJNRmi4yGxfoTVS4WLBXDkvTLq4vujeAD9NfDtSxGP/*)"
-```
-Voila! Now we have nice descriptors strings handy to use for our BDK wallet construction.
-
-### Talking to Bitcoin Core Programmatically
-Like all other tutorials we will use two wallets to send coins back and forth. A Bitcoin Core wallet accessible via `bitcoin-cli` command line tools, and a BDK wallet maintained by BDK library.    
-
-But unlike other tutorials, we won't be using `bitcoin-cli` to talk to the Core wallet (we can, but let's spice things up). Instead, we will use the `bitcoin-rpc` library, to talk with our core node listening at `127.0.0.1:18443`, from inside our main function. This will allow us to write code, that will handle both the core and BDK wallet, from inside of the same function, and we won't have to switch terminals!
-
-Remember we imported `use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};`? Thats exactly for this purpose.
-
-Start the `bitcoind` node.
-
-you should see bitcoind listening at port 18443
-```shell
-$ sudo netstat -nptl | grep 18443 
-tcp        0      0 0.0.0.0:18443           0.0.0.0:*               LISTEN      135532/bitcoind 
-```
-
-Lets create a core rpc interface in our main function.
-```rust
-fn main() {
-    ...
-    
-    // Create a RPC interface
-    let rpc_auth = rpc_auth::UserPass(
-        "admin".to_string(),
-        "password".to_string()
-    ); 
-    let core_rpc = Client::new("http://127.0.0.1:18443/wallet/test".to_string(), rpc_auth).unwrap();
-    println!("{:#?}", core_rpc.get_blockchain_info().unwrap());
-}
-```
-We have provided our RPC authentication `username` and `password` (same as provided in `bitcoin.conf` file).
-We have provided the RPC address of our local bitcoin node, with the path to a wallet file, named `test`. And then asked the rpc client to give us the current blockchain info.
-If everything goes well, running `cargo run` you should see an output like below:
-```shell
-$ cargo run
-...
-GetBlockchainInfoResult {
-    chain: "regtest",
-    blocks: 0,
-    headers: 0,
-    best_block_hash: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206,
-    difficulty: 0.00000000046565423739069247,
-    median_time: 1296688602,
-    verification_progress: 1.0,
-    initial_block_download: true,
-    ...
-```
-Thats it. Now we can programmatically talk to our core node.
-
-### Get some balance in core wallet.
-We have told our rpc client that we would use a wallet named `test`. But currently, our core node doesn't have such a wallet. So let's create the wallet and fund it with some test coins.
-```rust
-fn main() {
-    ...
-
-    // Create the test wallet 
-    core_rpc.create_wallet("test", None, None, None, None).unwrap();
-    
-    // Get a new address
-    let core_address = core_rpc.get_new_address(None, None).unwrap();
-    
-    // Generate 101 blocks and use the above address as coinbase
-    core_rpc.generate_to_address(101, &core_address).unwrap();
-    
-    // fetch the new balance
-    let core_balance = core_rpc.get_balance(None, None).unwrap();
-    
-    // Show balance
-    println!("core balance: {:#?}", core_balance);
-}
-```
-This will create a wallet in bitcoin core named `test`. generate 101 blocks and use a new address from the wallet as coinbase wallet. Because required coinbase maturity in bitcoin is 100 blocks, by generating 101 blocks, we will have the balance of the first coinbase block reward available for use.
-The last `println!()` statement will show the new updated balance as 50 BTC.
-```shell
-$ cargo run
-...
-core balance: Amount(50.00000000 BTC)       
-```
-Great! We now have 50 regtest BTC to play with.
-
-### Setup the BDK wallet
-Now that we are done setting up the core wallet. The last remaining step is to setup the BDK wallet. For this we will use the previous descriptor generation function and write code as below.
-
-**Note**: You might want to comment out the previous code in `main()`, as running them again will create more coins in core, which isn't an issue, but might be confusing.
-
-```rust
-fn main() {
-    ...
-
-    // Get receive and change descriptor
-    let (receive_desc, change_desc) = get_descriptors();
-    
-    // Use deterministic wallet name derived from descriptor
-    let wallet_name = wallet_name_from_descriptor(
-        &receive_desc,
-        Some(&change_desc),
-        Network::Regtest,
-        &Secp256k1::new()
-    ).unwrap();
-
-    // Create the datadir to store wallet data
-    let mut datadir = dirs_next::home_dir().unwrap();
-    datadir.push(".bdk-example");
-    let database = sled::open(datadir).unwrap();
-    let db_tree = database.open_tree(wallet_name.clone()).unwrap();
-
-    // Set RPC username, password and url
-    let auth = Auth::UserPass {
-        username: "admin".to_string(),
-        password: "password".to_string()
-    };
-    let mut rpc_url = "http://".to_string();
-    rpc_url.push_str("127.0.0.1:18443");
-
-    // Setup the RPC configuration
-    let rpc_config = RpcConfig {
-        url: rpc_url,
-        auth,
-        network: Network::Regtest,
-        wallet_name,
-        skip_blocks: None,
-    };
-
-    // Use the above configuration to create a RPC blockchain backend
-    let blockchain = RpcBlockchain::from_config(&rpc_config).unwrap();
-
-    // Combine everything and finally create the BDK wallet structure
-    let wallet = Wallet::new(&receive_desc, Some(&change_desc), Network::Regtest, db_tree, blockchain).unwrap();
-
-    // Sync the wallet
-    wallet.sync(NoopProgress, None).unwrap();
-
-    // Fetch a fresh address to receive coins
-    let address = wallet.get_address(AddressIndex::New).unwrap().address;
-
-    println!("bdk address: {:#?}", address);
-}
-```
-That's a lot of code. They are divided into logical sections. Let's discuss each step one by one.
- - First we used our previous `get_descriptors()` function to generate two descriptor strings. One for generating receive addresses and one for change addresses.
- - Then we used a special function from BDK called `wallet_name_from_descriptor()` to derive a name of the wallet from our descriptors. This allows us to have wallet names deterministically linked with descriptors. So in future if we use a different descriptor, the wallet will automatically have a different name. This allows us to not mix wallet names with same descriptor, and given the descriptors we can always determine what was the name we used. It is recommended to derive wallet names like this while using a core backend. Note that this wallet will be created inside the core node. So just like we accessed the `test` wallet, we could also access this wallet.
- - Then we created a data directory at path `/home/username/.bdk-example`. We use `dirs_next` to find our home path, and then appended that with `.bdk-example`. All the BDK wallet files will be created and maintained in that directory. In the Database we instructed BDK to create a new `Tree` with `wallet_name`, so given a descriptor, BDK will always know which DB Tree to refer (`Tree` is a `sled` specific term).
- - Then like we did previously, we created the rpc username/password authentication, and specified the rpc url. Note that we cannot use the same `rpc_auth` we used before for `core_rpc` as BDK auth and bitcoin-rpc auth are slightly separate structures.
- - We combined all this information and created an `RpcConfig` structure.
- - We used the rpc configuration to create a `RpcBlockchain` structure.
- - Finally we used the Descriptors, Database, and Blockchain to create our final BDK `wallet` structure.
-
-Now that we have a our wallet cooked, in the end, we instructed it to sync with the bitcoin core backend, and fetch us a new address.
-
-If all goes well, you should see an address printed in the terminal.
-
-```shell
-cargo run
-    Finished dev [unoptimized + debuginfo] target(s) in 2.99s
-    Running `target/debug/bdk-example`
-bdk address: bcrt1q9vkmujggvzs0rd4z6069v3v0jucje7ua7ap308
-```
-
-### Sending Sats Around
-
-Now that we have covered all the groundwork, we have all we need to send coins back and forth between core and BDK wallet.
-
-We will keep things simple here and make the following actions
- - Send 10 BTC from Core to BDK
- - Send back 5 BTC from BDK to Core
- - Display balance of two wallets
-
-In the last line of previous section we got a new address from BDK wallet. We will start from there. Without further discussion lets jump straight into code.
-
-```rust
-fn main() {
-    ...
-
-    // Fetch a fresh address to receive coins
-    let address = wallet.get_address(AddressIndex::New).unwrap().address;
-
-    // Send 10 BTC from Core to BDK
-    core_rpc.send_to_address(&address, Amount::from_btc(10.0).unwrap(), None, None, None, None, None, None).unwrap();
-
-    // Confirm transaction by generating some blocks
-    core_rpc.generate_to_address(1, &core_address).unwrap();
-
-    // Sync the BDK wallet
-    wallet.sync(NoopProgress, None).unwrap();
-    
-    // Create a transaction builder
-    let mut tx_builder = wallet.build_tx();
-
-    // Set recipient of the transaction
-    tx_builder.set_recipients(vec!((core_address.script_pubkey(), 500000000)));
-
-    // Finalise the transaction and extract PSBT
-    let (mut psbt, _) = tx_builder.finish().unwrap();
-
-    // Set signing option
-    let signopt = SignOptions {
-        assume_height: None,
-        ..Default::default()
-    };
-
-    // Sign the above psbt with signing option
-    wallet.sign(&mut psbt, signopt).unwrap();
-
-    // Extract the final transaction
-    let tx = psbt.extract_tx();
-
-    // Broadcast the transaction
-    wallet.broadcast(tx).unwrap();
-
-    // Confirm transaction by generating some blocks
-    core_rpc.generate_to_address(1, &core_address).unwrap();
-
-    // Sync the BDK wallet
-    wallet.sync(NoopProgress, None).unwrap();
-
-    // Fetch and display wallet balances
-    let core_balance = core_rpc.get_balance(None, None).unwrap();
-    let bdk_balance = Amount::from_sat(wallet.get_balance().unwrap());
-    println!("core wallet balance: {:#?}", core_balance);
-    println!("BDK wallet balance: {:#?}", bdk_balance);
-}
-```
-
-The above code segment is mostly straight forward. The only new thing added is `wallet.build_tx()` which returns a `TxBuilder`. BDK allows us to have very fine grained control of cooking up transactions. Almost everything that is possible to do with a Bitcoin transaction can be done in BDK. Here we have a very simple vanilla transaction with no added magic. To get full list of capabilities that `TxBuilder` supports scour its implementation [here](https://github.com/bitcoindevkit/bdk/blob/38d1d0b0e29d38cd370c740d798d96a3c9fcaa1f/src/wallet/tx_builder.rs#L123-L153).
-
-Finally to step through what we did above:
- - We asked core wallet to send 10 BTC to bdk wallet address.
- - We confirmed the transaction, and synced the wallet.
- - We asked BDK to create a transaction sending 5 BTC to core wallet address.
- - We signed and broadcast the transaction. BDK will use the same core node to broadcast the transaction to network.
- - We confirmed the transaction by mining a block, and synced the wallet.
- - We fetched and displayed balance of both core and BDK wallet.
-
-If all goes well, you should see the final updated balance as below:
-```shell
-$ cargo run
-    Compiling bdk-example v0.1.0 (/home/raj/github-repo/bdk-example/bdk-example)
-    Finished dev [unoptimized + debuginfo] target(s) in 3.57s
-    Running `target/debug/bdk-example`
-core wallet balance: Amount(144.99998590 BTC)
-BDK wallet balance: Amount(4.99999859 BTC)
-```
-Voila! We have ~145 BTC (150 - 5) in core wallet and 5 BTC (10 - 5) in BDK wallet. The slight deficiency in the amount are due to transaction fees. Because we are using regtest, the fee is some standard value hardcoded in core node.
-
-Check out the data directory where BDK has created the wallet data files.
-
-```shell
-$ ls ~/.bdk-example/
-blobs  conf  db  snap.0000000000023CAB
-```
-
-And finally, this is what the final `main.rs` file looks like.
-
-```rust
-use bdk::bitcoin::Network;
-use bdk::bitcoin::secp256k1::Secp256k1;
-use bdk::bitcoin::util::bip32::{DerivationPath, KeySource};
-use bdk::bitcoin::Amount;
-use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};
-
-use bdk::blockchain::rpc::{Auth, RpcBlockchain, RpcConfig, wallet_name_from_descriptor};
-use bdk::blockchain::{ConfigurableBlockchain, NoopProgress};
-
-use bdk::keys::bip39::{Mnemonic, Language, MnemonicType};
-use bdk::keys::{GeneratedKey, GeneratableKey, ExtendedKey, DerivableKey, DescriptorKey};
-use bdk::keys::DescriptorKey::Secret;
-
-use bdk::miniscript::miniscript::Segwitv0;
-
-use bdk::Wallet;
-use bdk::wallet::{AddressIndex, signer::SignOptions};
-
-use bdk::sled;
-
-use std::str::FromStr;
-
-fn main() {
-    // Create a RPC interface
-    let rpc_auth = rpc_auth::UserPass(
-        "admin".to_string(),
-        "password".to_string()
-    ); 
-    let core_rpc = Client::new("http://127.0.0.1:18443/wallet/test".to_string(), rpc_auth).unwrap();
-
-    // Create the test wallet 
-    core_rpc.create_wallet("test", None, None, None, None).unwrap();
-    
-    // Get a new address
-    let core_address = core_rpc.get_new_address(None, None).unwrap();
-    
-    // Generate 101 blocks and use the above address as coinbase
-    core_rpc.generate_to_address(101, &core_address).unwrap();
-
-    // Get receive and change descriptor
-    let (receive_desc, change_desc) = get_descriptors();
-    
-    // Use deterministic wallet name derived from descriptor
-    let wallet_name = wallet_name_from_descriptor(
-        &receive_desc,
-        Some(&change_desc),
-        Network::Regtest,
-        &Secp256k1::new()
-    ).unwrap();
-
-    // Create the datadir to store wallet data
-    let mut datadir = dirs_next::home_dir().unwrap();
-    datadir.push(".bdk-example");
-    let database = sled::open(datadir).unwrap();
-    let db_tree = database.open_tree(wallet_name.clone()).unwrap();
-
-    // Set RPC username and password
-    let auth = Auth::UserPass {
-        username: "admin".to_string(),
-        password: "password".to_string()
-    };
-
-    // Set RPC url
-    let mut rpc_url = "http://".to_string();
-    rpc_url.push_str("127.0.0.1:18443");
-
-    // Setup the RPC configuration
-    let rpc_config = RpcConfig {
-        url: rpc_url,
-        auth,
-        network: Network::Regtest,
-        wallet_name,
-        skip_blocks: None,
-    };
-
-    // Use the above configuration to create a RPC blockchain backend
-    let blockchain = RpcBlockchain::from_config(&rpc_config).unwrap();
-
-    // Combine everything and finally create the BDK wallet structure
-    let wallet = Wallet::new(&receive_desc, Some(&change_desc), Network::Regtest, db_tree, blockchain).unwrap();
-
-    // Sync the wallet
-    wallet.sync(NoopProgress, None).unwrap();
-
-    // Fetch a fresh address to receive coins
-    let address = wallet.get_address(AddressIndex::New).unwrap().address;
-
-    // Send 10 BTC from Core to BDK
-    core_rpc.send_to_address(&address, Amount::from_btc(10.0).unwrap(), None, None, None, None, None, None).unwrap();
-
-    // Confirm transaction by generating some blocks
-    core_rpc.generate_to_address(1, &core_address).unwrap();
-
-    // Sync the BDK wallet
-    wallet.sync(NoopProgress, None).unwrap();
-
-    // Create a transaction builder
-    let mut tx_builder = wallet.build_tx();
-
-    // Set recipient of the transaction
-    tx_builder.set_recipients(vec!((core_address.script_pubkey(), 500000000)));
-
-    // Finalise the transaction and extract PSBT
-    let (mut psbt, _) = tx_builder.finish().unwrap();
-
-    // Set signing option
-    let signopt = SignOptions {
-        assume_height: None,
-        ..Default::default()
-    };
-
-    // Sign the above psbt with signing option
-    wallet.sign(&mut psbt, signopt).unwrap();
-
-    // Extract the final transaction
-    let tx = psbt.extract_tx();
-
-    // Broadcast the transaction
-    wallet.broadcast(tx).unwrap();
-
-    // Confirm transaction by generating some blocks
-    core_rpc.generate_to_address(1, &core_address).unwrap();
-
-    // Sync the BDK wallet
-    wallet.sync(NoopProgress, None).unwrap();
-
-    // Fetch and display wallet balances
-    let core_balance = core_rpc.get_balance(None, None).unwrap();
-    let bdk_balance = Amount::from_sat(wallet.get_balance().unwrap());
-    println!("core wallet balance: {:#?}", core_balance);
-    println!("BDK wallet balance: {:#?}", bdk_balance);
-}
-
-// generate fresh descriptor strings and return them via (receive, change) tupple 
-fn get_descriptors() -> (String, String) {
-    // Create a new secp context
-    let secp = Secp256k1::new();
-
-    // You can also set a password to unlock the mnemonic
-    let password = Some("random password".to_string());
-
-    // Generate a fresh menmonic, and from their, a fresh private key xprv
-    let mnemonic: GeneratedKey<_, Segwitv0> =
-                Mnemonic::generate((MnemonicType::Words12, Language::English)).unwrap();
-    let mnemonic = mnemonic.into_key();
-    let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
-    let xprv = xkey.into_xprv(Network::Regtest).unwrap();
-
-    // Derive our dewscriptors to use
-    // We use the following paths for recieve and change descriptor
-    // recieve: "m/84h/1h/0h/0"
-    // change: "m/84h/1h/0h/1" 
-    let mut keys = Vec::new();
-
-    for path in ["m/84h/1h/0h/0", "m/84h/1h/0h/1"] {
-        let deriv_path: DerivationPath = DerivationPath::from_str(path).unwrap();
-        let derived_xprv = &xprv.derive_priv(&secp, &deriv_path).unwrap();
-        let origin: KeySource = (xprv.fingerprint(&secp), deriv_path);
-        let derived_xprv_desc_key: DescriptorKey<Segwitv0> =
-        derived_xprv.into_descriptor_key(Some(origin), DerivationPath::default()).unwrap();
-
-        // Wrap the derived key with the wpkh() string to produce a descriptor string
-        if let Secret(key, _, _) = derived_xprv_desc_key {
-            let mut desc = "wpkh(".to_string();
-            desc.push_str(&key.to_string());
-            desc.push_str(")");
-            keys.push(desc);
-        }
-    }
-    
-    // Return the keys as a tupple
-    (keys[0].clone(), keys[1].clone())
-}
-```
-
-### Conclusion
-In this tutorial we saw some very basic BDK wallet functionality with a bitcoin core backend as the source and sync of blockchain data. This is just tip of the iceberg of BDK capabilities. BDK allows flexibility in all the dimensions of a bitcoin wallet, that is key chain, blockchain backend and database management. With all that power, we just implemented a trustless, non-custodial, private bitcoin wallet, backed by a bitcoin full node, with less than 200 lines of code (including lots of comments).
-
-BDK thus allows wallet devs, to only focus on stuff that they care about, writing wallet logic. All the backend stuff like blockchain, key management, and databases are abstracted away under the hood.
-
-To find and explore more about the BDK capabilities and how it can fit your development need refer the following resources.
-
- - [source code](https://github.com/bitcoindevkit/bdk)
- - [dev docs](https://docs.rs/bdk/0.10.0/bdk/)
- - [community](https://discord.com/invite/d7NkDKm)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/_blog/compact_filters_demo.md b/docs/_blog/compact_filters_demo.md
deleted file mode 100644 (file)
index 283597f..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
----
-title: "Using BDK to create BIP157 SPV wallet (aka Neutrino)"
-description: "Tutorial showing usage of compact filters (BIP157) using bdk-cli command line tools"
-authors:
-    - Rajarshi Maitra
-date: "2021-06-20"
-tags: ["tutorial", "BDK", "bdk-cli", "compact_filters", "BIP157", "Neutrino"]
-permalink: "/blog/2021/06/using-bdk-to-create-bip157-spv-wallet-aka-neutrino/"
----
-
-## Introduction
-
-#### Compact Filters:
-Compact filters are the latest specification of Bitcoin SPV node implementation as per [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki) and [BIP158](https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki). Such light clients were envisioned by Satoshi himself in  his original white paper, but due to lack of robust privacy and trust guarantees using conventional [bloomfilters](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki), these type of nodes never got popular.
-
-Enters [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki), which described a new type of filters for Bitcoin Blockchain data, known as `compact_filters`. The [Neutrino](https://github.com/lightninglabs/neutrino) project pioneered the use of compact filter based light client nodes for using with Lightning Network wallets. Using compact filters, a light-node can talk to one or more full nodes, and fetch relevant information from the blockchain, with much more robust privacy and security guarantees than previously possible. Compact filter based nodes are best suitable to be used with mobile wallets, to create more trustless mobile applications on Bitcoin. Any wallet application that needs to have an "eye on the blockchain" has an use for such light clients.
-
-`BIP157` type filters allows to create tiny sized SPV nodes, that can fetch blockchain data and can identify inconsistency, so it can actively defend itself, while also preserving its privacy. Such nodes are most useful for Lightning Network mobile applications.
-
-Example of such `compact_filters` wallets in wild is [Breeze](https://github.com/breez/breezmobile) Lightning mobile wallet.
-
-Bitcoin core supports serving `BIP157` type filters from `v0.21.0`.
-
-#### BDK and Compact filters
-BDK is a bitcoin wallet development library that can be used to create bitcoin wallets with custom `Database` and `Blockchain` backends. BDK is a [descriptor](https://bitcoindevkit.org/descriptors/) based wallet, i.e. the wallet keychain is described by a set of descriptors.
-
-Using BDK one can instantiate wallets of various kinds as per requirement. BDK abstracts away all the heavy lifting works, and allow wallet devs to concentrate on logic that they care about, i.e. writing wallet codes. For more detailed documentation on BDK capabilities check these [blog](https://bitcoindevkit.org/blog/2020/12/hello-world/), [bog](https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/) and [docs](https://docs.rs/bdk/).
-
-The main three components of abstraction in BDK are
-  - `Database`
-  - `Descriptors`
-  - `Blockchain`
-
-BDK comes with default implementations of all them that developers can start with out of the box. Developers can also create there own custom implementations and plug it into BDK (thanks to rust magic of `Traits`).
-
-BDK also supports [BIP158](https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki) communication protocol, which allows creation of `BIP157` type compact filter SPV nodes. This capability is extended to wallet with BDK's `Blockchain` data structure. The [API](https://docs.rs/bdk/0.8.0/bdk/blockchain/trait.Blockchain.html) for `compact_filters` backend is similar to any other kind of backends, so wallet devs don't need to worry about all the details. Its ok if the dev haven't even heard of `BIP157`, BDK takes care of that in background.
-
-This capability can be unlocked by compiling BDK with the `compact_filters` feature. Once enabled, BDK will be able to create wallets with the `compact_filters` type `Blockchain` backend. (The default backend is electrum server)
-
-#### bdk-cli
-`bdk-cli` is a lightweight [REPL](https://codewith.mu/en/tutorials/1.0/repl) wrapper over the BDK library to facilitate quick and easy demonstration of BDK capabilities in command-line. Wallet devs can use this tool to quickly try out different possibilities with BDK.
-
-In this tutorial, We will use `bdk-cli` to demonstrate some basic wallet functionalities using `compact_filters` backend.
-
-## Tutorial Scope
-Basic wallet workflow we will cover:
-
-  - create and sync a wallet,
-  - receive a transaction,
-  - create a transaction,
-  - sign and broadcast the transaction,
-  - fetch updated balance,
-
-The BDK wallet will have a `BIP157` SPV backend (aka `compact_filters` backend) that will connect with a Bitcoin core node serving filter data.
-
-It will publish and extract transaction data through that node.
-
-We will have a Bitcoin Core wallet and a BDK wallet, sending and receiving transactions between each other, in regtest.
-
-## Prerequisites
-Following things are required to start with the tutorial.
-
-1. A Bitcoin Core regtest node listening at `localhost:18444` signalling for compact filter support.
-2. `bdk-cli` compiled with `compact_filter` features.
-
-If you already have these two setup and working, you can skip this and jump to the [Tutorial](#tutorial) section.
-
-#### Install and run `bitcoind`
-You can definitely do it with your own `bitcoind` installation. `BIP157` support has been included in Bitcoin Core `v0.21.0`. So anything above that will work.
-
-You also need to ensure proper configuration settings for signalling `compact_filters` support.
-
-For ease of testing, the BDK project hosts docker images that can be used to spawn Bitcoin Core with all the relevant configurations.
-
-- spawn a regtest node using [bitcoin-regtest-box](https://github.com/bitcoindevkit/bitcoin-regtest-box) docker file.
-
-  Start the regtest box docker container.
-
-  ```shell
-  $ docker run --detach --rm -p 127.0.0.1:18443-18444:18443-18444/tcp --name bdk-box bitcoindevkit/bitcoind
-  ```
-  This will spin up a docker container running `bicoind` and listening to port `18444` and `18333`. You can keep this terminal alive to see communication events with BDK and the node.
-
-- Check node is reachable
-
-  In another terminal try connecting to the node with `bitcoin-cli`
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest getnetworkinfo
-  {
-    "version": 210000,
-    "subversion": "/Satoshi:0.21.1/",
-    "protocolversion": 70016,
-    "localservices": "0000000000000449",
-    "localservicesnames": [
-      "NETWORK",
-      "WITNESS",
-      "COMPACT_FILTERS",
-      "NETWORK_LIMITED"
-      ...
-    ],
-  }
-
-  ```
-  In the output, the `version` should show `210000`. `localservicesnames` should contain `"COMPACT_FILTERS"`. If you see this, then Bitcoin Core is correctly configured.
-
-#### Install and run bdk-cli
-- Install `bdk-cli` with `compact_filters` feature
-
-  ```shell
-  $ cargo install --git https://github.com/bitcoindevkit/bdk-cli.git bdk-cli --features compact_filters
-  ```
-- Check installation
-  ```shell
-  $ bdk-cli --help
-  ...
-  USAGE:
-      bdk-cli [OPTIONS] <SUBCOMMAND>
-  FLAGS:
-      -h, --help Prints help information
-      -V, --version Prints version information
-  OPTIONS:
-      -n, --network <NETWORK> Sets the network [default: testnet]
-
-  SUBCOMMANDS:
-      help      Prints this message or the help of the given subcommand(s)
-      key       Key management sub-commands
-      repl      Enter REPL command loop mode
-      wallet    Wallet options and sub-commands
-  ```
-Once these are setup correctly, you can start with the tutorial next.
-
-
-
-## Tutorial
-[Note: For brevity `bdk-cli` results are stored in command line variables using `jq` tool. It is recommended to check the full results to see different information returned by `bdk-cli` commands.]
-
-### Bitcoin Core Wallet Generation
-
-This is standard procedure with `bitcoin-cli`.
-
-- Create a wallet and generate 101 blocks.
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest createwallet test
-  {
-    "name": "test",
-    "warning": ""
-  }
-  ```
-
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest getnewaddress
-  bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2
-  ```
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest generatetoaddress 101 bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2
-  [
-  "3813ed6eb716f4743b9657d918799acf743add985a8ded28d8aa3629dd4496b6",
-  "70da855913bdf791b6e458c611cebdef79b7a9840eb103ce58c71c1c7e3c49bc",
-  "682ca732ef72719cd6f82c5047c7690fb1cd2df2543d035ac4ea99e974b8d172",
-  "78799e4771017d4f46aa3c240054e2d61f54cea07ec44cb18ae712761e0aaa1e",
-  ...
-  ]
-  ```
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest getbalance
-  50.00000000
-  ```
-  Now the core wallet has generated new blocks and is funded with test bitcoin.
-
-
-### BDK Wallet Generation
-BDK is a descriptor based wallet library. So in order to use it we will need some descriptors to work with.
-
-BDK wallet will ask for two descriptors as input, corresponding to `receive` and `change` addresses. Its recommended to have these two descriptors separate as BDK will handle them separately and ensure `change` addresses are never used for receiving funds.
-
-Or developers can decide to use a single descriptor too, in that case BDK will use that descriptor for deriving both `receive` and `change` addresses.
-
-We will use `bdk-cli` itself to generate such descriptors.
-
-- #### Generate a privatekey
-  ```shell
-  $ BDK_xprv=$(bdk-cli key generate | jq -r '.xprv')
-  $ echo $BDK_xprv
-  tprv8ZgxMBicQKsPefY7tdq7EKny81n9tfSvUYfSHAZByXdjPAZVysvaB6sFd2YavqfqMBgbHaXUG5oWM6sYvdJn6vnUizzQKTYAJ36bQsfPv4N
-  ```
-  `bdk-cli key generate` will generate a fresh master key with `mnemonic` and `xprv`. We have extracted the value of extended private key and stored it in `BDK_xprv` variable.
-
-  The returned `mnemonic` can be used to restore back the wallet if wallet data directory is lost.
-
-- #### Generate Descriptors
-       `bdk-cli key derive` can derive an `xpub`s given a `master key` and `derivation_path`.
-
-  We will use the following paths for our `receive` and `change` descriptors
-
-       - `receive` path: `m/84h/1h/0h/0`
-       - `change` path: `m/84h/1h/0h/1`,
-
-       We can then simply wrap them in a `"wpkh()"` to create our descriptors string and store them.
-
-  When asked for a new address, BDK will derive one from the `receive` descriptor.
-
-  And while constructing transaction, BDK will use the `change` descriptor to derive change address.
-
-       ```shell
-  $ BDK_recv_desc="wpkh($(bdk-cli key derive --path m/84h/1h/0h/0 --xprv $BDK_xprv | jq -r '.xprv'))"
-  $ echo $BDK_recv_desc
-  wpkh([ff09c7c9/84'/1'/0'/0]tprv8hkdEGgwLLnqsdfkJFidpTj5d6z5qFdP6Qwzsviea3HrS9C2mXXaDivPKCCgcaWvnGNX9eciLUQs91PWYXJqrChfnAagViCgG6L5phaNyWr/*)
-  ```
-  ```shell
-  $ BDK_chng_desc="wpkh($(bdk-cli key derive --path m/84h/1h/0h/1 --xprv $BDK_xprv | jq -r '.xprv'))"
-  $ echo $BDK_chng_desc
-  wpkh([ff09c7c9/84'/1'/0'/1]tprv8hkdEGgwLLnqtbYkGG7fSy7v43RF2SQGGjNuZtmBzEHh7H8xgpXBETQAbVPqi8rkvLNFKLYY4rDzXA4fn5Ha1yuazZqhQPe3uNKmFS7648s/*)
-  ```
-  Note: `BDK_xprv` has been used as the `master key`, this will allow BDK to have signing capabilities.
-  We could have used an `xpub` master key here instead, that would create an `watch-only` wallet.
-
-- #### Create and Sync a wallet
-  We will now instruct BDK to create a new wallet with following instructions
-
-       ```shell
-  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sync
-  {}
-  ```
-    - name (`--wallet`) `bdk-test`,
-    - `receive` descriptor (`-d`) as `$BDK_recv_desc` and change descriptor (`-c`) as `$BDK_chng_desc`,
-    - connected to a full node (`--node`) listening at `127.0.0.1:18444`,
-    - and finally create and sync the wallet with the `sync` command.
-
-  If you are using a `regtest` node, also add `--network regtest`, the default is `testnet`.
-
-  `bdk-cli` makes multiple parallel connections that can be configured with the `--conn-count` parameter (default is 4). This makes syncing parallel and fast. Use `bdk-cli --help` to see all other options.
-
-  Getting an empty return means wallet creation succeeded.
-
-  BDK has created a wallet named `bdk-test` in its data directory. Which is by default stored at `~/.bdk-bitcoin/compact_filters` folder.
-
-  Looking into that folder different files and directories maintained by BDK can be seen.
-  ```shell
-  $ ls .bdk-bitcoin/compact_filters/
-  000004.log  CURRENT   LOCK  MANIFEST-000003  OPTIONS-000010
-  bdk-test    IDENTITY  LOG   OPTIONS-000008
-  ```
-### Recieve Coins
-
-We will use the `core` wallet to send 5 BTC to our`bdk-test` wallet.
-
-- Fetch a new address using `bdk-cli`
-  ```shell
-  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc get_new_address
-  {
-    "address": "bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9"
-  }
-  ```
-
-- Transfer funds to the previous address and generate a block, using `bitcoin-cli`
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest sendtoaddress bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9 5
-
-
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest generatetoaddress 1 bcrt1qw3ht9xtc9pgyvmqay0ap9fw8mxd27az8el0uz3
-  ```
-
-  `core` has sent 5 BTC to our `bdk-test` wallet. Which is confirmed in a new block.
-
-  `bdk-test` can see that now by syncing again.
-
-  (Note: BDK required explicit `sync()` calls to give wallet developers flexibility on when to sync).
-  ```shell
-  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sync
-  {}
-
-  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc get_balance
-  {
-    "satoshi": 500000000
-  }
-  ```
-
-  We can see `500000000` sats balance in our `bdk-test` wallet.
-
-  BDK has fetched blockchain details concerning its wallet descriptors, from the core node, using compact filters.
-
-### Creating a transaction.
-  Now we want to create a transaction sending coins from `bdk-test` wallet to the `core` wallet.
-
-- fetch a new `core` address
-  ```shell
-  $ core_addrs=$(docker exec -it bdk-box /root/bitcoin-cli -regtest getnewaddress | tr -d '\r')
-  ```
-
-- Create a raw transaction using `bdk-cli` to the above address. This will generate a `psbt` which we will sign.
-  ```shell
-  $ psbt=$(bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc create_tx --to $core_addrs:200000000 | jq -r '.psbt')
-  ```
-  (Recommended to check all the other information returned by `bdk-cli create_tx`)
-
-### Sign and Broadcast the transaction
-Asking BDK to sign a transaction is as straight forward as it can get. BDK already holds the `xprv` deatils to sign a transaction. It returns a finalised `signed_psbt` which we will next broadcast to the network.
-
-- Sign the transaction
-  ```shell
-  $ signed_psbt=$(bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sign --psbt $psbt | jq -r '.psbt')
-  ```
-
-- Broadcast the transaction
-  ```shell
-  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc broadcast --psbt $signed_psbt
-  {
-    "txid": "c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252"
-  }
-  ```
-  This makes BDK broadcast the transaction via the connected core node, and it returns the corresponding Txid.
-
-### Confirming the Transaction
- The transaction has been received by the `core` node and waiting in its mempool for inclusion in block.
- We can see the transaction via its `txid` received in previous step.
-
-- Check transaction in mempool
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest gettransaction c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e2248e52e0852252
-  {
-    "amount": 2.00000000,
-    "confirmations": 0,
-    "trusted": false,
-    "txid": "c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252",
-    "walletconflicts": [
-    ],
-    "time": 1621697202,
-    "timereceived": 1621697202,
-    "bip125-replaceable": "no",
-    "details": [
-      {
-        "address": "bcrt1q3h4hs6mve5dcl7da3d4acmlp20hh8c3t4mldwe",
-        "category": "receive",
-        "amount": 2.00000000,
-        "label": "",
-        "vout": 1
-      }
-    ],
-    "hex": "01000000000101d84e8cb7477f9fe6f265b56d5416ff47da9a70be18f65ec50731b8257c67f2bd0100000000ffffffff0273a2e11100000000160014874270187001febc4cebd8cb083cf2c783e8f1ac00c2eb0b000000001600148deb786b6ccd1b8ff9bd8b6bdc6fe153ef73e22b0247304402201037d9ef5b80392296311c8899b1f12a0987778d694a442a88bafa6fbd7a7c9a022011293176255897444d9c71b0b9cd13b2aedb749b142577566c90a63d61025e2c01210202427d16b29c1c8546255363a74326ee9ab3196770bb3fccc7b679d52f9c1ccf00000000"
-  }
-  ```
-  This means, core has recieved the transaction in its mempool and waiting for confirmation.
-
-- Generate 1 block to confirm the transaction
-  ```shell
-  $ docker exec -it bdk-box /root/bitcoin-cli -regtest generatetoaddress 1 bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2
-  [
-    "55436ff0169bbb3e70ab10cb7cdd45ab86204d5d7864a109142d91120d023197"
-  ]
-  ```
-
-- Sync the `bdk-test` wallet and ask for available balance.
-  ```shell
-       $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sync
-       {}
-
-       $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc get_balance
-       {
-               "satoshi": 299999859
-       }
-  ```
-
-       If you see the balance updated, voila!
-
-  What happened here is:
-  - core created a new block containing the transaction.
-  - `bdk-cli` fetched the corresponding filter data.
-  - It noticed it got a concerning transaction.
-  - It asked for the details of that transaction from the core node.
-  - It updated its wallet details with this new information.
-  - The update is reflected in the wallet balance.
-
-### Shutdown Docker ###
-
-You may now shutdown the regtest docker container.
-
-Note: This will also clean up any data in the bitcoin core, including the wallet.
-
-```shell
-$ docker kill bdk-box
-```
-
-## End Words
-
-In this tutorial we went through the process of receiving, creating, signing and broadcasting transaction using the BDK wallet with `compact_filters` feature. This demonstrates how BDK capabilities can be used to create SPV light wallets with integrated `BIP157` type `compact_filters` node.
diff --git a/docs/_blog/descriptor_based_paper_wallet.md b/docs/_blog/descriptor_based_paper_wallet.md
deleted file mode 100644 (file)
index 286eb1f..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
----
-title: "Descriptor-based paper wallets"
-description: "Demonstrate how to create descriptor-based paper wallet and how to spend them with bdk"
-authors:
-    - Riccardo Casatta
-    - Steve Myers
-date: "2021-03-30"
-tags: ["guide", "descriptor", "paper wallets"]
-permalink: "/blog/2021/03/descriptor-based-paper-wallets/"
----
-
-In this post, we will use the [Rusty Paper Wallet] tool to create a multi-owned descriptor-based paper wallet. We will use [bdk] via the [bdk-cli] tool to test our descriptor and to be able to sweep the funds from our paper wallet to a new address.
-
-## About paper wallets
-
-Paper wallets have a lot of drawbacks, as explained in the [paper wallet Wiki article], as always, do your own research before deciding to use it with mainnet bitcoins. In this post we will
-only be using testnet coins.
-
-## Descriptors
-
-The [previous version] of the [Rusty Paper Wallet] followed the original paper wallet design: WIF[^WIF] as secret part with the option to generate a different kind of addresses (legacy, nested segwit, and segwit).
-
-There were plans to [support mnemonic](https://github.com/RCasatta/rusty-paper-wallet/issues/5) instead of WIF keys because it may[^WIFcore] save the sweep transaction[^sweep] and there are more wallets capable of importing a mnemonic instead of a WIF.
-
-However, choosing a single address type or having wallet support for a specific format is the kind of problem [descriptors] solve perfectly, so the latest [Rusty Paper Wallet] version now accepts a descriptor and the network as parameters.
-
-## Example use case
-
-So let's say your grandma wants to buy bitcoin and asked for your help.
-
-You are a little afraid she may lose the private key. At the same time, you don't want to duplicate the keys and give those to her daughters Alice and Barbara, because both of them could spend and accuse the other of having done so.
-
-Even though we trust everyone in the family it is better to play it safe and divide the responsibility of protecting Grandma's bitcoin.
-
-This is a perfect case for a 2 of 3 multi-signature paper wallet. This way also protects the participants from having their copy of the wallet stolen. To compromise Grandma's wallet a thief would need to find and steal at least two of them.
-
-Note that you as the wallet creator are still the single point of trust because you are going to generate the keys for everyone. Setups combining self generated keys from the participants is possible future work.
-
-## Creating the paper wallet
-
-For this example the spending descriptor would be:
-
-`wsh(multi(2,Grandma,Alice,Barbara))`
-
-You need [rust] installed to use [Rusty Paper Wallet]. The -n option below explicitly selects
-generating `testnet` keys. Use `rusty-paper-wallet --help` to see usage instructions and other
-options.
-
-```shell
-$ cargo install rusty-paper-wallet
-$ rusty-paper-wallet "wsh(multi(2,Grandma,Alice,Barbara))" -n testnet
-data:text/html;base64,PCFET0N...
-```
-
-The [output] of the command is very long and has been shortened. The string is a [data URI scheme] paste-able in the address bar of a browser. By using a data URI no files are written on the hard disk, leaving less trace of secret material on the computer.
-It's also a good idea to use incognito mode in the browser to prevent it from saving the page in the history.
-
-The following is the result:
-
-<iframe src="/descriptor-based-paper-wallets/Bitcoin_Paper_Wallet.html" class="example"></iframe>
-
-Under the hood, the command created a key pair randomly for every alias present in the descriptor, then replaced the aliases with the created keys and generated the corresponding address. This address is the same for every paper wallet and it is shown in the upper part of the paper wallet (the public part) along with the alias, linking the paper wallet to the owner.
-
-The lower part is the secret part, the written part is the descriptor with the aliases, followed by a legend linking the aliases with the keys. In the legend, all the keys are public but the one of the owner which is a private WIF. The secret QR code instead contains the descriptor already with the keys.
-
-The paper wallet must then be printed, and it is better to use a printer without wifi and also to be aware that some sensitive data may remain in the printer's cache.
-
-Then the paper wallet must be cut along the dotted lines, the secret part should be folded twice over the black zone[^blackzone]. The black zone helps to avoid showing the secret parts in the presence of back-light. Once the folding is done the paper wallet should be plasticized to prevent being damaged by water.
-
-## BDK
-
-Any descriptor based wallet can be used to check the balance of and sweep the funds from
-Grandma's paper wallet. For this post we'll demonstrate using the [bdk-cli] tool to do these steps.
-Another area where [bdk] could be used with [Rusty Paper Wallet] is to compile a more
-complicated miniscript spending policy into a descriptor, as we have done in the [spending policy demo] post.
-
-## Funding tx
-
-Since Grandma's wallet was created as a `wsh` descriptor, bitcoin can be sent to it from any
-segwit capable wallet, we'll use a public [bitcoin testnet faucet]. Once the funds are sent the
-deposit address `tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw` we can also use this
-address and a testnet explorer to [confirm the funds were received].
-
-## Sweep tx
-
-Now that Grandma's paper wallet is funded it's time to demonstrate how to use [bdk-cli] to sweep these
-funds to a new address. Let's assume Grandma lost her original paper wallet and has asked
-her daughters to sweep them to a new single signature wallet so she can spend them.
-
-### Step 1: Alice creates and signs a PSBT
-
-Alice uses the private text or QR code from her paper wallet to find her private key and the
-public keys for Grandma and Barbara. With this info she creates a PSBT to sweep Grandma's funds
-to a new address (in this example we'll send them back to our [bitcoin testnet faucet]). Notice how Alice
-includes her wallet's descriptor checksum '#em3q73l5', this [guarantees] she has entered her descriptor correctly.
-
-```shell
-$ SWEEP_TO_ADDR=tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2
-
-$ ALICE_WIF=cSSKRHDmQEEutp5LD14tAcixu2ehSNPDTqNek1zMa9Pet98qxHq3
-$ BARBARA_PUBKEY=02a3f3f2658b9812ddeabfbde2fde03f8a65369e4ed621f29fa8ba0cc519b789fb
-$ GRANDMA_PUBKEY=03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee
-$ ALICE_DESCRIPTOR="wsh(multi(2,$GRANDMA_PUBKEY,$ALICE_WIF,$BARBARA_PUBKEY))#em3q73l5"
-
-# confirm descriptor creates the expected deposit address
-$ bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_new_address
-{
-  "address": "tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"
-}
-
-# sync the wallet and show the balance
-$ bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
-{}
-
-$ bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
-{
-  "satoshi": 10000
-}
-
-# create and sign PSBT
-$ UNSIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx --send_all --to $SWEEP_TO_ADDR:0 | jq -r ".psbt")
-
-$ ALICE_SIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sign --psbt $UNSIGNED_PSBT | jq -r ".psbt")
-```
-
-### Step 2: Barbara signs Alice's signed PSBT and broadcasts the tx
-
-Now it's Barbara's turn to use the private text or QR code from her paper wallet to get her private
-key and the public keys for Grandma and Alice. With this info plus Alice's signed PSBT she can
-create a fully signed PSBT to broadcast and complete the sweep of Grandma's funds.
-
-```shell
-$ ALICE_PUBKEY=02e486e32f0f87136fa042cb53219ace8537ea1d036deb2f4293570b94325d11cb
-$ BARBARA_WIF=cSfMLzSZ9NjWUTqL3sFpgWJssnu2qgmE2cm5N1jPDRRJuDcrsPEB
-$ GRANDMA_PUBKEY=03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee
-$ BARBARA_DESCRIPTOR="wsh(multi(2,$GRANDMA_PUBKEY,$ALICE_PUBKEY,$BARBARA_WIF))#nxfa5n0z"
-
-# confirm descriptor creates the expected deposit address
-$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR get_new_address
-{
-  "address": "tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"
-}
-
-# sync the wallet and show the balance
-$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR sync
-{}
-
-$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR get_balance
-{
-  "satoshi": 10000
-}
-
-$ FINAL_PSBT=$(bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR sign --psbt $ALICE_SIGNED_PSBT | jq -r ".psbt")
-
-$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR broadcast --psbt $FINAL_PSBT
-{
-  "txid": "9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59"
-}
-```
-
-And finally we verify that Alice and Barbara successfully created and broadcast Grandma's [sweep tx].
-
-## Conclusion
-
-In this post we showed how to create a multi-sig descriptor based paper wallet using
-[Rusty Paper Wallet] and then sweep the funds from our example paper wallet to a new address. If you
-found this post interesting please comment below. Or give it a try yourself and if you run into any
-problems or would like to suggest improvements leave an issue in the [Rusty Paper Wallet] or
-[bdk-cli] github repos. Thanks!
-
-[paper wallet wiki article]: https://en.bitcoin.it/wiki/Paper_wallet
-[previous version]: https://github.com/RCasatta/rusty-paper-wallet/tree/339fa4418d94f6fdd96f3d0301cab8a0bc09e8bd
-[Rusty Paper Wallet]: https://github.com/RCasatta/rusty-paper-wallet
-[support mnemonic]: https://github.com/RCasatta/rusty-paper-wallet/issues/5
-[descriptors]: /descriptors
-[bdk]: https://github.com/bitcoindevkit/bdk
-[rust]: https://www.rust-lang.org/tools/install
-[output]: /descriptor-based-paper-wallets/data-url.txt
-[data URI scheme]: https://en.wikipedia.org/wiki/Data_URI_scheme
-[bdk-cli]: https://github.com/bitcoindevkit/bdk-cli
-[bitcoin testnet faucet]: https://bitcoinfaucet.uo1.net/
-[confirm the funds were received]: https://mempool.space/testnet/address/tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw
-[sweep tx]: https://mempool.space/testnet/tx/9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59
-[spending policy demo]: /blog/2021/02/spending-policy-demo/#step-4-create-wallet-descriptors-for-each-participant
-[guarantees]: https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
-
-[^WIF]: Wallet Input Format, a string encoding a ECDSA private key  https://en.bitcoin.it/wiki/Wallet_import_format
-[^WIFcore]: Unless the user import the WIF directly into bitcoin core
-[^sweep]: Some wallets refers to sweep as the action to create a transaction taking all the funds from the paper wallet and sending those to the wallet itself.
-[^blackzone]: Ideally, the black zone should be twice as long as the secret part to cover it back and front, long descriptor may leave a shorter black zone, ensure to have you printer set with vertical layout for best results.
diff --git a/docs/_blog/descriptors_in_the_wild.md b/docs/_blog/descriptors_in_the_wild.md
deleted file mode 100644 (file)
index 74634e7..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
----
-title: "Descriptors in the wild"
-description: "Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK"
-authors:
-    - Gabriele Domenichini
-date: "2020-11-18"
-tags: ["guide", "descriptor"]
-permalink: "/blog/2020/11/descriptors-in-the-wild/"
----
-
-I have tried to setup a 2 of 2 multi signature infrastructure with two
-different wallets, which know nothing about each other, but are compliant with
-two very important protocols: [Output Descriptors] and [Partially Signed
-Bitcoin Transactions][PSBT] described in BIP 174.
-
-Before these two protocols came into existence, making a multi signature setup
-and spending from it was possible only if the involved parties were using the
-same wallet (eg. Electrum Desktop Wallet). This limitation was due to the fact
-that the two parties had to agree:
-
-* on the particular type of script and address to use
-* on the way the transaction would be shared composed and signed with all the
-involved parties.
-
-[Output Descriptors] are a way to express which kind scriptPubKey and
-addresses to produce with a key or a series of keys.
-
-[PSBT] is instead the standard protocol used to create a transaction and to enrich
-it with the necessary signatures and other components, to make it valid and complete.
-
-Together they provide a common ground to create and use a multi signature
-infrastructure in a heterogeneous environment, and this is what I have put
-to test.
-
-## The use case
-
-Imagine Alice and Bob owning a company and being willing to put the corporate cash
-in a 2of2 multi signature setup, so that each one of them have to agree and sign each
-transaction.
-
-## The role of Descriptors
-
-If Alice and Bob cannot agree on the software to use, to monitor the same financial
-situation, the two software must control and produce exactly the same series
-of multisignature addresses.
-
-To make two different software produce the same addresses in a deterministic way
-we must ensure that they:
-* produce the same pair of public keys
-* combine them in the same order
-* put them inside the same scriptPubKey to produce the same address
-
-Here is where the [Output Descriptors] come into play. They describe:
-
-* the sequence of public keys each extended key (xpub) will produce
-* the sequence in which the new public keys of various parties will enter into
-the script
-* the type of script the wallet will prepare with that group keys and so the type
-of address the group of keys will produce.
-
-**By sharing the same Descriptor, every compliant wallet will derive
-deterministically the same series of multisig addresses**.
-
-Imagine Alice using Bitcoin Core (from now on ["Core"][Bitcoin Core]) as a
-Wallet and Bob using a "Last generation" wallet, Bitcoin Development Kit
-(from now on ["BDK"][BDK]), which uses descriptors and miniscript natively.
-
-Each of these two software wallets should be able to:
-
-* Create a new address which is seen as belonging to the multi signature
-wallet in both software
-* Express the consent of each party by partially signing the transaction in a way
-the other wallet can understand and complete it with its own signature.
-
-The infrastructure of multiple Extended keys combined toghether to produce
-multiple multisignature addresses is often referred as
-*[Hierarchical Deterministic][HDWallet] multi signature wallet or HDM*.
-
-What follows are the steps to create the HDM usable both in Core and
-in BDK.
-
-*Note: In Core, [Descriptor wallets] are still experimental and in general,
-both wallets should be tested for descriptor capabilities only in testnet.*
-
-## Our playground
-
-We will build a 2of2 key set up that will be used cooperatively by Bitcoin Core
-and Bitcoin Development Kit.
-The steps Alice and Bob will do are:
-
-1. creation of the seed and the derived Extended Master Public and send it to
-the other party
-2. Create the multi signature descriptor for each wallet
-3. Use each other's software to receive testnet coins from a faucet
-4. return part of the coins to the faucet signing the transaction with both
-wallets.
-
-We need:
-* [Bitcoin Dev Kit][BDK]
-* [Bitcoin Core] (v0.21.0 or later)
-
-### 1. Creating the seeds and the derived Extended Public keys
-
-#### Seeds and Extended Master Public
-
-We build an Extended Private Master Key for both wallet and derive a BIP84
-Extended Master Public for Bitcoin Core and then for BDK.
-
-For Bitcoin Core (Alice):
-
-```
-# new Extended wallet data
-export core_key=$(bdk-cli key generate)
-
-# New Extended Master Private
-
-export core_xprv=$(echo $core_key | jq -r '.xprv')
-
-# Now I derive the xpubs (one for receiving and one for the change)
-# together with informations about the derivation path to be communicated
-# to BDK wallet's owner (Bob).
-
-export core_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $core_xprv | jq -r '.xpub')
-export core_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $core_xprv | jq -r '.xpub')
-```
-
-For BDK (Bob) we do the same:
-
-```
-# new Extended wallet data
-
-export BDK_key=$(bdk-cli key generate)
-
-# New Extended Master Private
-
-export BDK_xprv=$(echo $BDK_key | jq -r '.xprv')
-
-# Now I build the derived xpubs to be communicated (to Alice).
-
-export BDK_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $BDK_xprv | jq -r '.xpub')
-export BDK_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $BDK_xprv | jq -r '.xpub')
-```
-
-### 2. Creation of the multi signature descriptor for each wallet
-
-To build a multisig wallet, each wallet owner must compose the descriptor
-adding:
-* his derived extended **private** key AND
-* all the extended **public** keys of the other wallets involved in the
-multi signature setup
-
-*The different nature of the two keys (one is private and one is public) is
-due to the fact that each wallet, to be able to partially sign the transaction,
-**must manage the private key of the wallet's owner*** AND have the other
-party's public key. Otherwise, if we put both public keys, we would obtain
-a watch-only wallet unable to sign the transactions. If we
-had both extended private keys inside the descriptor, we would allow each party
-to finalize the transactions autonomously.
-
-#### In Bitcoin Core:
-
-In our case, the multi signature descriptor for Bitcoin Core will be composed
-with:
-
-* The BIP84 derived Extended **Public** Key from BDK
-* The BIP84 derived Extended **Private** Key from Core.
-
-BDK wallet's owner will send to Core's owner the derived xpub for this purpose.
-This is how the Core's multisig descriptor will be created and put into an
-environment variable:
-
-```
-export core_rec_desc="wsh(multi(2,$BDK_xpub_84_for_rec_desc,$core_xprv/84'/0'/0'/0/*))"
-```
-
-Where of course `$BDK_xpub_84_for_rec_desc`is the derived master public created
-in BDK and received by Core's owner.
-
-The meaning of what is before and after is illustrated in the doc that explain
-the use of [Output Descriptors in Bitcoin Core][Output Descriptors].
-
-We add the necessary checksum using the specific `bitcoin-cli` call.
-
-```
-export core_rec_desc_chksum=$core_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_rec_desc | jq -r '.checksum')
-```
-
-We repeat the same to build the descriptor to receive the change.
-
-```
-export core_chg_desc="wsh(multi(2,$BDK_xpub_84_for_chg_desc,$core_xprv/84'/0'/0'/1/*))"
-export core_chg_desc_chksum=$core_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_chg_desc|jq -r '.checksum')
-```
-
-#### In BDK:
-
-For BDK we set the derivation for receiving addresses and change addresses
-in the command line (maybe setting an alias)
-
-Building the descriptor:
-
-```
-export BDK_rec_desc="wsh(multi(2,$BDK_xprv/84'/0'/0'/0/*,$core_xpub_84_for_rec_desc))"`
-```
-
-Please note that the order of the extended key in the descriptor MUST be the
-same in the 2 wallets.
-
-*We have chosen to put BDK first and in each software wallet, the public key
-derived from BDK will always come first. In alternative, we could have chosen to
-produce the descriptor, [chosing a `soretedmulti` multisignature setup][sortedmulti]*.
-
-```
-export BDK_rec_desc_chksum=$BDK_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_rec_desc | jq -r '.checksum')
-export BDK_chg_desc="wsh(multi(2,$BDK_xprv/84'/0'/0'/1/*,$core_xpub_84_for_chg_desc))"
-export BDK_chg_desc_chksum=$BDK_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_chg_desc | jq -r '.checksum')
-```
-
-To take a look at the variables we have produced so far:
-```
-env  | grep 'core_'
-env  | grep 'BDK_'
-```
-
-Now we will use the multisig descriptor wallet to receive testnet coins with
-Alice and Bob's software
-
-### 3. Use each other's software to receive testnet coins from a faucet
-
-#### In Bitcoin Core
-
-Alice must create an empty, experimental new "descriptors wallet" in Core and
-to import the multisig Output Descriptor.
-
-```
-bitcoin-cli -testnet createwallet "multisig2of2withBDK" false true "" false true false
-````
-The flag are to:
-* use the private keys
-* make it empty
-* no password provided to the wallet
-* reusing of addresses not allowed
-* "new experimental descriptors wallet"
-*  don't load it on start up
-
-```
-bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK importdescriptors "[{\"desc\":\"$core_rec_desc_chksum\",\"timestamp\":\"now\",\"active\":true,\"internal\":false},{\"desc\":\"$core_chg_desc_chksum\",\"timestamp\":\"now\",\"active\":true,\"internal\":true}]"
-```
-Now Alice asks for her first receiving multisignature address.
-
-```
-export first_address=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getnewaddress)
-echo $first_address
-```
-
-#### BDK
-In BDK Bob can specify directly the descriptors on the command line to produce
-the multisig address, because BDK is descriptors aware natively.
-
-```
-repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_new_address`
-```
-
-Et voilà: if we have done everything correctly, the newly created address in
-Core is the same of the newly created address in BDK. this is part of the
-"miracle" of descriptors' interoperability.
-
-#### We ask for testnet coins giving the first created address.
-
-To find testnet coins for free, you can just google "testnet faucet" and you
-should find some satoshis to play with. Just give to the site your first
-generated address and, in twenty minutes, you will find the satoshis in
-your balance both in Core and in BDK.
-
-```
-# to check it in Core:
-
-bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getbalance
-
-# In BDK:
-
-# Sync with the blockchain
-repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sync
-# Get the balance
-repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_balance
-```
-Some testnet faucets have an address to send back the unused satoshi after
-the use. Take note of that because we will use it in the next step.
-
-### 4. we return part of the satoshis received back to the faucet
-
-```
-export psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletcreatefundedpsbt "[]" "[{\"tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a\":0.000012}]" | jq -r '.psbt')
-
-export psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletprocesspsbt $psbt | jq -r '.psbt')
-{
-  "psbt": "cHNidP8BAIkCAAAAATj90EC+NAuXj7y6SseZJucoJM6sGnUcVm9koTveZECTAAAAAAD+////AmACAAAAAAAAIgAg98ol9j4AalD71E0mV5QV0uM6/vCT+pi2twxr/zrvLROwBAAAAAAAACIAIB4zBMipU3xqvNDQlz+PCDXvpkHH1Q95Nu0mgIsnU0jbAAAAAAABAIkCAAAAAQS+ObgGG6UwtvaO3KYph2E3/ws7Q83RbmR3rxC0fKYSAQAAAAD+////AtAHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNDAHQAAAAAAACIAIBQpiDTgPIMt0ld8cmuYqlY+EIPjvrmMqZruDhs61hQNAAAAAAEBK9AHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNAiAgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAAQEFR1IhArn3tec7n7318rnWqf0dIIwtLtfxo6Zt0HV70UvZYaWvIQNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfVKuIgYCufe15zufvfXyudap/R0gjC0u1/Gjpm3QdXvRS9lhpa8YNEw2cFQAAIAAAACAAAAAgAAAAAAAAAAAIgYDbdI+wHtIgO6pS6Ja7jai1pDwPeidKoDCytTO1jhjAH0YO/laXFQAAIAAAACAAAAAgAAAAAAAAAAAAAEBR1IhAqccvA3rL13D1K4GeWjcahDsO3P8oaVNBttk4MlCKXIcIQLHKhjmPuCQjyS77ZfaMN2tdgNKcf/+57VXGZhz/UWTl1KuIgICpxy8DesvXcPUrgZ5aNxqEOw7c/yhpU0G22TgyUIpchwYNEw2cFQAAIAAAACAAAAAgAEAAAADAAAAIgICxyoY5j7gkI8ku+2X2jDdrXYDSnH//ue1VxmYc/1Fk5cYO/laXFQAAIAAAACAAAAAgAEAAAADAAAAAAA=",
-  "complete": false
-}
-```
-
-Exactly! Note the `"complete": false`. We have processed the transaction with
-Core but we miss one of the necessary key of the multisig 2of2 setup (The one
-contained inside BDK).
-
-`tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a` is the address
-we got from the faucet site to return the satoshis.
-
-The [PSBT] is sent over to the BDK wallet owner who tries to sign the
-transaction:
-
-```
-repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sign --psbt $psbt
-{
-  "is_finalized": true,
-  "psbt": "cHNidP8BAIkCAAAAATj90EC+NAuXj7y6SseZJucoJM6sGnUcVm9koTveZECTAAAAAAD+////AmACAAAAAAAAIgAg98ol9j4AalD71E0mV5QV0uM6/vCT+pi2twxr/zrvLROwBAAAAAAAACIAIB4zBMipU3xqvNDQlz+PCDXvpkHH1Q95Nu0mgIsnU0jbAAAAAAABAIkCAAAAAQS+ObgGG6UwtvaO3KYph2E3/ws7Q83RbmR3rxC0fKYSAQAAAAD+////AtAHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNDAHQAAAAAAACIAIBQpiDTgPIMt0ld8cmuYqlY+EIPjvrmMqZruDhs61hQNAAAAAAEBK9AHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNAiAgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAASICArn3tec7n7318rnWqf0dIIwtLtfxo6Zt0HV70UvZYaWvRzBEAiBkVDLgVEwvENnLx+04o7gGpGjFDBwAXTJmf8Yvo35oygIgbuBkHsvPC9jmZcMZ9P+Pwp01yxSaWo+5feyPmd3ai1kBAQVHUiECufe15zufvfXyudap/R0gjC0u1/Gjpm3QdXvRS9lhpa8hA23SPsB7SIDuqUuiWu42otaQ8D3onSqAwsrUztY4YwB9Uq4iBgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfRg7+VpcVAAAgAAAAIAAAACAAAAAAAAAAAAiBgK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlrxg0TDZwVAAAgAAAAIAAAACAAAAAAAAAAAABBwABCNoEAEcwRAIgZFQy4FRMLxDZy8ftOKO4BqRoxQwcAF0yZn/GL6N+aMoCIG7gZB7LzwvY5mXDGfT/j8KdNcsUmlqPuX3sj5nd2otZAUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAAUdSIQK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlryEDbdI+wHtIgO6pS6Ja7jai1pDwPeidKoDCytTO1jhjAH1SrgABAUdSIQKnHLwN6y9dw9SuBnlo3GoQ7Dtz/KGlTQbbZODJQilyHCECxyoY5j7gkI8ku+2X2jDdrXYDSnH//ue1VxmYc/1Fk5dSriICAqccvA3rL13D1K4GeWjcahDsO3P8oaVNBttk4MlCKXIcGDRMNnBUAACAAAAAgAAAAIABAAAAAwAAACICAscqGOY+4JCPJLvtl9ow3a12A0px//7ntVcZmHP9RZOXGDv5WlxUAACAAAAAgAAAAIABAAAAAwAAAAAA"
-}
-```
-The signature has succeded (note the "is_finalized": true,) and now we can
-broadcast the transction.
-```
-repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint broadcast --psbt "cHNidP8BAIkCAAAAATj90EC+NAuXj7y6SseZJucoJM6sGnUcVm9koTveZECTAAAAAAD+////AmACAAAAAAAAIgAg98ol9j4AalD71E0mV5QV0uM6/vCT+pi2twxr/zrvLROwBAAAAAAAACIAIB4zBMipU3xqvNDQlz+PCDXvpkHH1Q95Nu0mgIsnU0jbAAAAAAABAIkCAAAAAQS+ObgGG6UwtvaO3KYph2E3/ws7Q83RbmR3rxC0fKYSAQAAAAD+////AtAHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNDAHQAAAAAAACIAIBQpiDTgPIMt0ld8cmuYqlY+EIPjvrmMqZruDhs61hQNAAAAAAEBK9AHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNAiAgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAASICArn3tec7n7318rnWqf0dIIwtLtfxo6Zt0HV70UvZYaWvRzBEAiBkVDLgVEwvENnLx+04o7gGpGjFDBwAXTJmf8Yvo35oygIgbuBkHsvPC9jmZcMZ9P+Pwp01yxSaWo+5feyPmd3ai1kBAQVHUiECufe15zufvfXyudap/R0gjC0u1/Gjpm3QdXvRS9lhpa8hA23SPsB7SIDuqUuiWu42otaQ8D3onSqAwsrUztY4YwB9Uq4iBgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfRg7+VpcVAAAgAAAAIAAAACAAAAAAAAAAAAiBgK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlrxg0TDZwVAAAgAAAAIAAAACAAAAAAAAAAAABBwABCNoEAEcwRAIgZFQy4FRMLxDZy8ftOKO4BqRoxQwcAF0yZn/GL6N+aMoCIG7gZB7LzwvY5mXDGfT/j8KdNcsUmlqPuX3sj5nd2otZAUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAAUdSIQK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlryEDbdI+wHtIgO6pS6Ja7jai1pDwPeidKoDCytTO1jhjAH1SrgABAUdSIQKnHLwN6y9dw9SuBnlo3GoQ7Dtz/KGlTQbbZODJQilyHCECxyoY5j7gkI8ku+2X2jDdrXYDSnH//ue1VxmYc/1Fk5dSriICAqccvA3rL13D1K4GeWjcahDsO3P8oaVNBttk4MlCKXIcGDRMNnBUAACAAAAAgAAAAIABAAAAAwAAACICAscqGOY+4JCPJLvtl9ow3a12A0px//7ntVcZmHP9RZOXGDv5WlxUAACAAAAAgAAAAIABAAAAAwAAAAAA"
-{
-  "txid": "a0b082e3b0579822d4a0b0fa95a4c4662f6b128ffd43fdcfe53c37473ce85dee"
-}
-```
-
-## Conclusion
-
-We have built an HDM and we have used it with two indipendent wallets, which
-are compatible with [BIP 174][PSBT] and [Output Descriptors]. Hopefully we
-will see many other compatible wallets beyound [Bitcoin Core] and [BDK],
-with which we will be able to easily set up multi signature schemes.
-
-
-[Descriptor wallets]: https://github.com/bitcoin/bitcoin/pull/16528
-[Electrum]: https://electrum.org
-[Output Descriptors]: https://bitcoinops.org/en/topics/output-script-descriptors/
-[PSBT]: https://en.bitcoin.it/wiki/BIP_0174
-[HDWallet]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
-[sortedmulti]: https://github.com/bitcoin/bitcoin/pull/17056?ref=tokendaily
-[BDK]: https://bitcoindevkit.org/
-[Bitcoin Core]: https://bitcoincore.org/
-[pycoin]: https://github.com/richardkiss/pycoin
diff --git a/docs/_blog/hidden-power-of-bitcoin.md b/docs/_blog/hidden-power-of-bitcoin.md
deleted file mode 100644 (file)
index 0119e25..0000000
+++ /dev/null
@@ -1,582 +0,0 @@
----
-title: "Miniscript Policy & Descriptors - Hidden Powers of Bitcoin"
-description: "Introduction to Descriptor and Miniscript, making a Multisig Wallet and Testing Miniscript Policies"
-authors:
-    - Sandipan Dey
-    - Rajarshi Maitra
-date: "2022-01-02"
-tags: ["tutorial", "bdk", "bdk-cli", "miniscript", "descriptor", "bitcoin-cli"]
-hidden: true
-draft: false
----
-
-To send people BTC - we simply scan a QR Code *(or paste an address)*, enter some amount and *whoosh* - sent!
-Users might think, just like traditional currency, we can only exchange money using Bitcoin.
-As it so happens, the underlying technology Bitcoin supports specify outputs not as addresses, but as programming scripts.
-This opens us to a world of possibilities using Bitcoin.
-
-### Script
-
-Bitcoin supports [Script](https://en.bitcoin.it/wiki/Script), a **stack-based** lightweight programming language.
-Any script written in **Script** *(pun intended)* contains `OP_*` codes and raw byte arrays that Bitcoin Full Nodes understand and process.
-Currently, there are `117` op-codes in use.
-You can read more about these op-codes straight [here](https://en.bitcoin.it/wiki/Script).
-
-Script is intentionally left [Turing incomplete](https://en.wikipedia.org/wiki/Turing_completeness) which is why there is no [halting problem](https://en.wikipedia.org/wiki/Halting_problem) with scripts.
-There are no loops and overall, it's a very constrained programming language.
-
-A transaction is considered valid only when the Script returns `true` at the end of execution.
-Output Script (aka scriptpubkey) define the conditions under which coins associated with them can be spent. To spend a particular coin implies finding an input script (aka scriptsig) such that a script made out of concatenation of `scriptsig + scriptpubkey` evaluates to `true`.
-
-For example, a basic legacy `Pay-to-PubKey-Hash` transaction would look like:
-
-```script
-scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
-scriptSig: <sig> <pubKey>
-```
-
-##### Examples of things achievable using Bitcoin Script:
-
-1. `Pay Someone (p2pkh/p2wpkh)` - A specific public key must sign to spend the coins.
-2. `Escrow (2-of-3-multisig)` - Two parties need to sign together to spend the coins.
-3. `Vault (locked)` - A specific key will not be able to spend the coins until a timeout but another master key will always be able to spend them.
-4. `HTLC` - The receiver needs disclose a secret before a timeout, else the coins are transferred back to the payee.
-
-##### Motivation for Policies
-
-Unfortunately, due to its low-level and unusual stack-based nature, Script is pretty hard to reason about and use.
-Despite being around since Bitcoin's creation, writing and understanding Script is not trivial.
-This is why the scripts for the above few examples are pretty lengthy and might not make sense at the first glance.
-When writing a script, we would want to know that if the logic we wrote is **correct**, **optimal** and **efficient in size** (use lower [weight](https://en.bitcoin.it/wiki/Weight_units)).
-
-The community wanted an easy alternative way of writing Script that would create the most optimized Script code.
-This gave rise to **Miniscript**.
-
-### Miniscript
-
-[Miniscript](http://bitcoin.sipa.be/miniscript/) tackles the above problems head-on.
-It is an expressive way to create policies on Bitcoin Scripts in a structured and simple fashion.
-Using Miniscript, it's difficult to go wrong.
-
-Another very important goal of Miniscript is to replace any key used in a policy with another policy.
-This is important because people might have multiple keys and complicated timelocks in their existing setup.
-While signing a new policy, they would want to use their existing setup to also generate addresses for this new setup.
-This is accomplished using something called **Output Descriptors** which we will get into in next section.
-
-Miniscript compiler compiles a **spending policy** down to Miniscript.
-It doesn't contain any signature, it's mainly a combinator language for designing spending conditions.
-You can try out the compiler online by using [this link](http://bitcoin.sipa.be/miniscript/#:~:text=Policy%20to%20Miniscript%20compiler).
-
-##### Fragments
-
-Here are some fragments which can be combined to create powerful expressions.
-
-1. `pk(key)` - Specifies a given public key
-2. `thresh(k, expr_1, expr_2, ..., expr_n)` - Specifies k of n multisig using expressions.
-3. `older(T)` - Timelock for T blocks
-4. `and(expr_1, expr_2)` - Both expressions should evaluate to true. 
-5. `or(expr_1, expr_2)` - Any one of the expressions should evaluate to true.
-6. `aor(expr_1, expr_2)` - Similar to `or` but `expr_1` has a more probability to evaluate to true.
-
-Bitcoin Script allows us to use another alternate stack. The combinator functions use this second stack to evaluate expressions of `thresh`, `and`, `aor` and `or`.
-The complete Miniscript Reference can be found [here](http://bitcoin.sipa.be/miniscript/#:~:text=Miniscript%20reference).
-
-##### Example Policies
-
-Here are the Miniscript Policies for the examples we looked at earlier. 
-Note `A`, `B`, `C` are placeholders for keys *(`xpub`/`xprv`)* involved in the tx.
-Descriptors are high level description of scriptpubkey (p2pkh, p2sh etc). 
-And miniscripts are semantics that describes the actual redeemscript. 
-In general you have Descriptor(Miniscript) format.
-
-1. Pay A (pay-to-public-key)
-```
-pk(A)
-```
-
-2. Escrow Account between A, B and third-party C.
-```
-thresh(2,pk(A),pk(B),pk(C))
-```
-
-3. Vault for A time-locked for T blocks with B as the master key.
-```
-aor(and(pk(A),time(T)),pk(B))
-```
-
-4. HTLC payment to B, which, if unspent for T blocks, returns to A.
-```
-aor(and(pk(A),time(T)),and(pk(B),hash(H))))
-```
-
-The Miniscript Policy Compiler is written in Rust and is present in [this repository](https://github.com/rust-bitcoin/rust-miniscript). 
-In this blog, we will later use the same using [bitcoindevkit/bdk](https://github.com/bitcoindevkit/bdk), a lightweight descriptor-based wallet library
-with a [cli](https://github.com/bitcoindevkit/bdk-cli). 
-
-### Descriptors
-
-The Bitcoin scriptpubkey supports various schemes like P2PKH, P2SH, P2WPKH, P2TR (Segwit v1) etc.
-A Descriptor is a simple "description" of what scriptpubkey to be used for a given policy.
-It can inclue a single pubkey within itself, or an entire miniscript policy.
-On the other hand, Miniscript policies are used to derive the redeemscript (the actual executable script), whereas the descriptor describes how the redeemscript will be encumbered within the scriptpubkey.
-
-In other words, a descriptor "describes" the procedure to create an *address*, given a *spending condition*.
-
-They make it easier to deal with Multisig or complicated key setups.
-Descriptors are super portable and can be easily used by any wallet to determine the list of all addresses that can be generated from the same.
-This feature creates a common stage for all Bitcoin apps and software.
-
-The concept of descriptor came into existence in 2018 and since then, a lot of wallets have added support for descriptors.
-You can read the descriptor doc from `bitcoin-core` [here](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).
-
-According to Bitcoin Core, Output Descriptors are "a simple language which can be used to describe collections of output scripts".
-They bring in themselves, derivation paths, master xpub/xprv fingerprints and paths to generate addresses from.
-Let's understand this with an example of an Output Descriptor:
-
-```
-
-Descriptor: pkh([d34db33f/44'/0'/0']xpub6ERaJH[...]LJRcEL/1/*)#ml40v0wf
-            <1> <--------2---------><----------3---------><4> <---5--->
-
-Sections:
-1 - address type specifier (here, describing P2PK type addresses)
-2 - master key fingerprint and derivation path from master
-3 - xpub at m/44'/0'/0
-4 - path to deriving keys/addresses at
-5 - checksum for the descriptor
-```
-A descriptor have three parts:
- - *address type specifier* (item 1) : describes the type of address created by this descriptor.
- - *policy* : the spending condition that locks funds into this address.
- - *checksum* : for quick verification.
-
-The address type specifiers currently supported are `pk`, `pkh`, `sh`, `wpkh`, `wsh` for corresponding address type and recently added `tr` for taproot addresses.
-
-There is a special address specifier called `combo` that creates addresses of all types from spending policy policy.
-
-After the address specifier, comes the *policy* that describes how the funds in the address can be spent. The descriptor
-above in the example has a simple spending policy of "spend by the correct private key". There can be more complicated policies,
-and we will touch them in later sections.
-
-`multi` is a special keyword that can be used as both *address type* and *policy*.
-When used as an *address type* like `multi(...)`, it will create an address from the raw multisig scriptpubkey.
-While when used as a *policy* like `wsh(multi(...))` it will create that specific address type from the multisig script.
-Of course we cannot use `pk(multi(...))`, `pkh(multi(...))` or `wpkh(multi(...))`, because these address types cannot hold scripts (any scripts) inside them.
-
-For example a descriptor like `wsh(multi(2, PKA, PKB, PKC))` describes a P2WSH type address created by a `2-of-3` multisig
-script using `PKA`, `PKB` and `PKC` pubkeys.
-
-### Where it all comes together...
-
-In this section, we are going to make a descriptor-based wallet and derive addresses from `bitcoin-cli` and then use `bdk-cli` to confirm that the addresses generated for descriptor wallets are deterministic for a given descriptor.
-
-We will also try to create a vault miniscript policy and push funds to the vault with a lock time of 2 months. 
-During this time, we will try to break our vault and see our transactions failing.
-
-##### Tools and Armor
-
-- [docker](https://docs.docker.com/engine/install/)
-- [bdk-cli](https://github.com/bitcoindevkit/bdk-cli)
-- [miniscriptc](https://bitcoindevkit.org/bdk-cli/compiler/#installation)
-
-##### Setting Up
-
-We require `bitcoind` to run in `regtest` mode. Use the following config file, or any other config
-that you are familiar with.
-
-```txt
-regtest=1
-fallbackfee=0.0001
-server=1
-
-rpcuser=user
-rpcpassword=password
-```
-
-```bash
-# Start Bitcoin Core
-bitcoind
-```
-
-#### Keys and Generating Addresses
-
-Quick installation for `bdk-cli` and `miniscriptc`:
-```bash
-cargo install bdk-cli --features=rpc,compiler
-cargo install bdk --features="compiler" --example miniscriptc
-```
-
-Let us first generate an XPRV and create the wpkh wallet descriptor
-```bash
-XPRV=$(bdk-cli key generate | jq -r '.xprv')
-EX_DESC="wpkh($XPRV/86'/1'/0'/0/*)"
-EX_DESC_CS=$(elcli getdescriptorinfo $EX_DESC | jq -r '.checksum')
-EX_DESC=$EX_DESC#$EX_DESC_CS
-
-# Set this descriptor in a wallet in bitcoin-cli
-bitcoin-cli -named createwallet wallet_name="mywallet" descriptors=true
-bitcoin-cli -rpcwallet="mywallet" importdescriptors "[{\"desc\":\"$EX_DESC\", \"timestamp\":\"now\", \"active\": true, \"range\": [0,100]}]"
-
-echo $EX_DESC
-```
-
-It should look something like this:
-```
-wpkh(tprv8ZgxMBicQKsPeuazF16EdPZw84eHj55AU8ZKgZgdhu3sXcHnFgjzskfDvZdTaAFHYNCbKqrurFo9onSaT7zGT1i3u3j7LKhVZF5sJA39WPN/86'/1'/0'/0/*)#40hv8z77
-```
-
-Now, we will generate 10 addresses using `bitcoin-cli` and thereafter `bdk-cli` using this above descriptor.
-Notice how both of them output the same set of addresses.
-
-```bash
-# Generation via bdk-cli
-repeat 10 { bdk-cli -n regtest wallet --descriptor $EX_DESC -w mywallet get_new_address | jq -r ".address" }
-bcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp
-bcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur
-bcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez
-bcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99
-bcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv
-bcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy
-bcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j
-bcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp
-bcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67
-bcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz
-
-# Generation via bitcoin-cli
-repeat 10 { bitcoin-cli -rpcwallet="mywallet" getnewaddress }
-bcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp
-bcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur
-bcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez
-bcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99
-bcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv
-bcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy
-bcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j
-bcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp
-bcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67
-bcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz
-```
-
-Notes:
-- The `repeat n {}` syntax will only work in `zsh`, you can use other loops for your shell, or just manually repeat the code 10 times.
-- In case you get different outputs in either of the cases, try deleting `~/.bdk-bitcoin` and retrying (thanks [@Steve](https://twitter.com/notmandatory) for this tip!)
-
-Note that both `bdk-cli` and `bitcoin-cli` produced the exact same addresses. So now we have definitive proof that descriptors can make wallets portable. That single string will be able to make any wallet generate the same set of addresses and hence they can sync and broadcast transactions in the same manner!
-
-#### Making a MultiSig Descriptor for Funds
-
-In the real-life, most of us hold two kinds of savings accounts - one to store huge funds saved throughout our lifetime *(probably without internet banking functionalities)* 
-and another for regular expenses.
-
-In the Bitcoin world, to store huge funds, most people prefer to use a Multisig descriptor with a `2-of-3` or `3-of-4` setup. 
-They can have one key stored in their PC, one key stored in a hardware wallet, one key stored in writing in a secure vault and another key learnt by heart.
-In case of a mishap like a house burning on fire or permanent memory loss, they would still be able to recover their funds by using the other keys.
-
-Here's how a secure `2-of-3` descriptor generation would look like:
-
-```bash
-# xprv generation
-K1_XPRV=$(bdk-cli key generate | jq -r ".xprv")
-K2_XPRV=$(bdk-cli key generate | jq -r ".xprv")
-K3_XPRV=$(bdk-cli key generate | jq -r ".xprv")
-
-# xpub generation
-K1_XPUB=$(bdk-cli key derive --xprv $K1_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-K2_XPUB=$(bdk-cli key derive --xprv $K2_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-K3_XPUB=$(bdk-cli key derive --xprv $K3_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-
-# Descriptors for each key - Since we used BIP-84 generation paths for xpubs,
-# we need to append the same to the xprvs so that our wallet can understand 
-# which path to generate addresses and xpubs from
-K1_DESC="wsh(multi(2,$K1_XPRV/84'/1'/0'/0/*,$K2_XPUB,$K3_XPUB))"
-K2_DESC="wsh(multi(2,$K1_XPUB,$K2_XPRV/84'/1'/0'/0/*,$K3_XPUB))"
-K3_DESC="wsh(multi(2,$K1_XPUB,$K2_XPUB,$K3_XPRV/84'/1'/0'/0/*))"
-```
-
-Lets create three bdk wallets aliases with above descriptors for easy future use
-and do initial sync to create the wallet files
-```bash
-alias k1wallet='bdk-cli -n regtest wallet -w K1 -d $K1_DESC'
-alias k2wallet='bdk-cli -n regtest wallet -w K2 -d $K2_DESC'
-alias k3wallet='bdk-cli -n regtest wallet -w K3 -d $K3_DESC'
-
-k1wallet sync
-{}
-k2wallet sync
-{}
-k3wallet sync
-{}
-```
-
-Now, let us send some funds to an address generated by `k1wallet`.
-
-```
-# ask regtest to generate 101 blocks, so we get 50 regtest coins to play with.
-# because coinbase amounts are only spendable after 100 blocks, we generate
-# 101 blocks, to use the first block's coinbase amount.
-CORE_ADDR=$(bitcoin-cli getnewaddress)
-bitcoin-cli generatetoaddress 101 $CORE_ADDR
-bitcoin-cli getbalance
-50.00000000
-
-# And then send 10 btc to an address generated by `K1` descriptor
-BDK_ADDR=$(k1wallet get_new_address | jq -r ".address")
-bitcoin-cli -rpcwallet=mywallet sendtoaddress $BDK_ADDR 10
-
-# Confirm the transaction by creating one more block
-bitcoin-cli generatetoaddress 1 $CORE_ADDR
-```
-
-Now sync the wallets and check balances in each
-```bash
-k1wallet sync
-{}
-k1wallet get_balance
-{
-  "satoshi": 1000000000
-}
-
-k2wallet sync
-{}
-k2wallet get_balance
-{
-  "satoshi": 1000000000
-}
-
-k3wallet sync
-{}
-k3wallet get_balance
-{
-  "satoshi": 1000000000
-}
-```
-
-Everyone has the same amount of balance. 
-This happened because it was a multisig wallet.
-Now, let's try to spend some balance.
-We will give back some balance to the wallet maintained by `bitcoin-cli`.
-But remember, this is a `2-of-3` multisig wallet.
-That's why we will need at least two keys to sign to make a transaction.
-
-Here's where we will require to use a [PSBT](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) or a *partially signed bitcoin transaction*. 
-Bitcoin uses PSBTs as the standard protocol to create a transaction and add one or more signatures to it before broadcasting the same to 
-the network which finally can become a proper valid *transaction*.
-
-We will aks `k2wallet` to create and sign the transaction then `k1wallet` and `k3wallet` will co-sign it.
-Note that `k2wallet` even if it creates the transaction, doesn't need to sign it, because its a `2-of-3` multisig!
-```bash
-# create the transaction, can be started by anyone
-PSBT=$(k2wallet create_tx --to "$CORE_ADDR:100000000" | jq -r ".psbt")
-
-# Sign the transaction by K1 and look at the output
-# it should say the psbt is not finalized since only one party has signed
-k1wallet sign --psbt $PSBT
-{
-   "is_finalized": false,
-   "psbt": "[...]"
-}
-
-# Saving the PSBT signed by K1
-K1_SIGNED_PSBT=$(k1wallet sign --psbt $PSBT | jq -r ".psbt")
-
-# Sign by K3 - should be finalized this time
-# Notice that this time, the input psbt was the signed PSBT of K1
-k3wallet sign --psbt $K1_SIGNED_PSBT
-{
-   "is_finalized": true,
-   "psbt": "[...]"
-}
-
-# Saving the PSBT signed by K3
-SIGNED_PSBT=$(k3wallet sign --psbt $K1_SIGNED_PSBT | jq -r ".psbt")
-
-# Broadcast the transaction, again doesn't really matter who broadcasts
-k2wallet broadcast --psbt $SIGNED_PSBT
-{
-   "txid": "49e2706fc73c49605692bf1b9ce58baf1eb0307ea39b3118628994fd56c9b642"
-}
-
-# Confirm the transaction by generating one block
-bitcoin-cli generatetoaddress 1 $CORE_ADDR
-
-# Sync and check balance - it should have gone down by 100000000 + tx fees
-k1wallet sync
-k1wallet get_balance
-{
-  "satoshi": 899999810
-}
-# Check similarly for `k2wallet` and `k3wallet` and they should all have same balance
-```
-
-So this proves we can definitely do transactions with multisig wallets with complicated descriptors.
-Since for Bitcoin, having keys equal having access to the accounts, we need to keep our keys safe.
-For legacy single key wallets, we used to keep backups of the mnemonic codes in multiple places.
-It was pretty insecure because in case any one of those backups leaks, our entire account would be compromised.
-Complicated multisig wallet descriptors are definitely a step forward - just in case a single key leak or are lost, no one would be able to take charge of the funds we hold.
-
-Another problem with multisig was syncing between wallets to always create consistent addresses. How would
-one wallet know whats the next address to create without talking to other wallets? The answer is `descriptors + PSBT`.
-If all the wallet shares the correct descriptor string they will always create the exact sequence of addresses and
-by passing around PSBTs they would know how to sign them, without talking to each other. This solves a major problem of multisig interoperability. And BDK makes this process as seamless as possible.
-
-### Retention Bonus - Smart Contract with Bitcoin
-
-Let us consider that a company wants to give its employees a retention bonus for two months.
-If an employee stays with that company for over 2 months, the employee would get 1 BTC as a reward.
-This would be a smart contract between the company and an employee.
-The employee should be able to see that he would get his funds after two months.
-The company would require confidence that the employee would not be able to withdraw the reward before two months have passed.
-
-The Miniscript policy for this contract would be as follows:
-```
-or(99@and(pk(E),older(8640)),pk(C))
-```
-where `E` is the employee and `C` is the company.
-
-I should emphasize over here that this policy will let the company still transfer funds after the designated 2 months.
-It's not possible to block them after the lock time has passed, atleast not in a single policy.
-
-Surely, after two months, the funds can be unlocked by the employee but before that, the company can revoke the funds.
-Let us compile this policy down to a descriptor. And this time we will ask help from the `miniscript` program.
-
-```bash
-# The Descriptor will be on the log, the E and C are placeholders
-miniscriptc "or(99@and(pk(E),older(8640)),pk(C))" sh-wsh
-[2021-08-05T12:25:40Z INFO  miniscriptc] Compiling policy: or(99@and(pk(E),older(8640)),pk(C))
-[2021-08-05T12:25:40Z INFO  miniscriptc] ... Descriptor: sh(wsh(andor(pk(E),older(8640),pk(C))))#55wzucxa
-Error: Descriptor(Miniscript(Unexpected("Key too short (<66 char), doesn't match any format")))
-```
-
-So the compiled descriptor is
-```
-sh(wsh(andor(pk(E),older(8640),pk(C))))
-```
-
-Let's make the keys, generate addresses using the above descriptor and fund it.
-```bash
-# xprvs
-E_XPRV=$(bdk-cli key generate | jq -r ".xprv")
-C_XPRV=$(bdk-cli key generate | jq -r ".xprv")
-
-# xpubs
-E_XPUB=$(bdk-cli key derive --xprv $E_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-C_XPUB=$(bdk-cli key derive --xprv $C_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-
-# descriptors using the compiled miniscript
-# please note in case company or the employee was using a complicated multisig descriptor,
-# it may as well have been added here like we did in the example before
-E_DESC="sh(wsh(andor(pk($E_XPRV/84'/1'/0'/0/*),older(8640),pk($C_XPUB))))"
-C_DESC="sh(wsh(andor(pk($E_XPUB),older(8640),pk($C_XPRV/84'/1'/0'/0/*))))"
-
-# Create wallet aliases for easy access and sync the wallet to create initial wallet files
-alias Cwallet='bdk-cli -n regtest wallet -w C -d $C_DESC'
-alias Ewallet='bdk-cli -n regtest wallet -w E -d $E_DESC'
-
-Cwallet sync
-{}
-Ewallet sync
-{}
-
-# get some funds in  Cwallet's address
-C_ADDR=$(Cwallet get_new_address | jq -r ".address")
-bitcoin-cli -rpcwallet=mywallet sendtoaddress $C_ADDR 10
-
-# Confirm the transaction
-bitcoin-cli generatetoaddress 1 $CORE_ADDR
-
-# Sync and check balance
-Cwallet sync
-{}
-Cwallet get_balance
-{
-  "satoshi": 1000000000
-}
-
-# Just as before, the employe can also see the fund in their wallet
-Ewallet sync
-{}
-Ewallet get_balance
-{
-  "satoshi": 1000000000
-}
-```
-
-According to the spending policy, for `E` has to wait for 8640 blocks before he can spend the coins.
-But let's check what happens if `E` tries to transact before the designated 2 months anyway.
-
-```bash
-# address to send the transaction to
-E_ADDR=$(Ewallet getnewaddress | jq -r ".address")
-
-# get external_policy id - this identifies which policy the wallet will try to sign against
-POLICY_ID=$(Ewallet policies | jq -r ".external | .id")
-
-# create the tx (external_policy id from last step in my case is j7ncy3au
-PSBT=$(Ewallet create_tx --to "$E_ADDR:100000000" --external_policy "{\"$POLICY_ID\":[0]}" | jq -r ".psbt")
-
-# sign and save the signed psbt
-SIGNED_PSBT=$(Ewallet sign --psbt $PSBT | jq -r ".psbt")
-
-# now let's try to broadcast - and see it failing
-Ewallet broadcast --psbt $SIGNED_PSBT
-[2021-08-05T17:48:45Z ERROR bdk_cli] Electrum(Protocol(Object({"code": Number(2), "message": String("sendrawtransaction RPC error: {\"code\":-26,\"message\":\"non-BIP68-final\"}")})))
-```
-
-We get an error saying the transaction we sent is **Not BIP68 Final**.
-[BIP68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) is a relative lock-time specification that ensures consensus when a signed transaction is sent which is invalid at a given time because the lock time isn't passed.
-So that's an expected error.
-
-Now let's simulate two months passing and retry.
-
-```bash
-# simulate two months
-# this will take around 1 mins to complete
-bitcoin-cli generatetoaddress 8640 $CORE_ADDR
-
-# create, sign and broadcast tx
-PSBT=$(Ewallet create_tx --to $E_ADDR:100000000 --external_policy "{\"$POLICY_ID\":[0]}" | jq -r ".psbt")
-SIGNED_PSBT=$(Ewallet sign --psbt $PSBT | jq -r ".psbt")
-Ewallet broadcast --psbt $SIGNED_PSBT
-{
-  "txid": "2a0919bb3ce6e26018698ad1169965301a9ceab6d3da2a3dcb41343dc48e0dba"
-}
-
-# Confirm the transaction
-bitcoin-cli generatetoaddress 1 $CORE_ADDR
-
-# Sync and check balances
-Cwallet sync
-{}
-Cwallet get_balance
-{
-  "satoshi": 999999810
-}
-
-Ewallet sync
-{}
-Ewallet get_balance
-{
-  "satoshi": 999999810
-}
-```
-
-So this time it worked, because we have simulated 2 months passing by generating 8640 blocks. And both the Company
-and Employe wallet gets updated.
-Hence, we saw that we can generate some smart contracts using Bitcoin.
-
-### Inspirations
-
-1. [Descriptors from Bitcoin Core](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md)
-1. [Miniscript](http://bitcoin.sipa.be/miniscript)
-1. [Output Script Descriptors](https://bitcoinops.org/en/topics/output-script-descriptors)
-1. [Descriptors in Bitcoin Dev Kit](https://bitcoindevkit.org/descriptors)
-1. [Role of Descriptors](https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/#the-role-of-descriptors)
-1. [Making a Taproot Descriptor Wallet using bitcoin-cli](https://gist.github.com/notmandatory/483c7edd098550c235da75d5babcf255)
-1. [Miniscripts SBC '19 - Video](https://www.youtube.com/watch?v=XM1lzN4Zfks)
-1. [Rethinking Wallet Architecture: Native Descriptor Wallets - Video](https://www.youtube.com/watch?v=xC25NzIjzog)
-
-Special thanks to my mentor [Steve Myers](https://twitter.com/notmandatory) for the constant motivation and support he gave me and for clearing so many doubts!
-Immense thanks to [Raj](https://github.com/rajarshimaitra) for reviewing this blog and giving such detailed suggestions.
-Many of the lines added here are his.
-Also, thanks to the folks at the `#miniscript` IRC channel to help me out with the Retention Bonus policy.
-
-This blog was written during [Summer of Bitcoin 2021](https://summerofbitcoin.org) by [Sandipan Dey](https://twitter.com/@sandipndev).
\ No newline at end of file
diff --git a/docs/_blog/spending_policy_demo.md b/docs/_blog/spending_policy_demo.md
deleted file mode 100644 (file)
index 344afd5..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
----
-title: "Spending Policy Demo"
-description: "Demonstrate how to use a descriptor wallet with different spending policies"
-authors:
-    - Steve Myers
-    - thunderbiscuit
-date: "2021-02-23"
-tags: ["guide", "descriptor"]
-permalink: "/blog/2021/02/spending-policy-demo/"
----
-
-In this post we will use the [bdk-cli](https://github.com/bitcoindevkit/bdk-cli) tool to demonstrate how to use the [bdk](https://github.com/bitcoindevkit/bdk) library to:
-
-1. generate *testnet* public and private keys
-2. create [PSBT](https://bitcoinops.org/en/topics/psbt/)s that can be spent based on different [miniscript spending policies](http://bitcoin.sipa.be/miniscript/)
-3. cooperatively sign and finalize the resulting PSBTs
-4. broadcast and confirm spending transactions
-
-The scenario we will simulate is a wallet with two spending policies:
-
-A. **three** out of **three** signers must sign spending transaction input [UTXO](https://developer.bitcoin.org/glossary.html)s, **OR**
-
-B. **two** out of **three** signers must sign **AND** the input UTXOs must be a relative number of blocks older than the spending transaction's block
-
-In a real-world wallet a longer relative time-lock would probably be used, but we chose a two block time-lock to make testing easier.
-
-*Note: If you repeat these instructions on your own your extended keys, addresses, and other values will be different than shown in this post, but the end results should be the same.*
-
-## Initial Setup
-
-### Step 0: Install a recent version `bdk-cli`
-
-```bash
-cargo install bdk-cli --features electrum
-
-# confirm bdk-cli is installed
-bdk-cli --version
-BDK CLI 0.4.0
-
-# bdk-cli usage can be explored with the `help` sub-command
-bdk-cli help
-```
-
-### Step 1: Generate private extended keys
-
-Generate new extended private keys for each of our wallet participants:
-
-```bash
-bdk-cli key generate | tee alice-key.json
-{
-  "fingerprint": "5adb4683",
-  "mnemonic": "witness poverty pulse crush era item game rose bargain quantum spawn sure way behave also basket journey worry stem entry toddler floor way bone",
-  "xprv": "tprv8ZgxMBicQKsPeAuGznXJZwfWHgWo86dFuufRBZN7ZT44UzoNG2cYmZLNLrnsm7eXhGSeccRU2nTtxunT11UkpqrRhJQefBnFJeHBddF68bg"
-}
-
-bdk-cli key generate | tee bob-key.json
-{
-  "fingerprint": "5fdec309",
-  "mnemonic": "shiver atom february jealous spy gallery upset height captain snake tooth master ugly orbit amazing nice parrot elevator own olympic great relief ozone violin",
-  "xprv": "tprv8ZgxMBicQKsPei56wJPNt9u2132Ynncp2qXdfSHszobnyjaGjQwxQBGASUidc1unmEmpyMQ9XzLgvbN36MDW7LNziVFdXVGMrx6ckMHuRmd"
-}
-
-bdk-cli key generate | tee carol-key.json
-{
-  "fingerprint": "de41e56d",
-  "mnemonic": "upon bridge side tool style lounge need faculty middle nation armed corn valve that undo ribbon rent digital adapt capable embody zero shiver carpet",
-  "xprv": "tprv8ZgxMBicQKsPf2edJLnXsF2AKwkCshCy2Z7fQD6FxiNVGsbkvpLRfxM8FSKrLqqpLFzLzVUBwgE9F5MQASrbedKCrGk1NG8oJgqYtmTLQEU"
-}
-```
-
-### Step 2: Extract private extended keys
-
-Here we use the `jq` Unix command to parse the json output of the `bdk-cli` commands.
-
-```bash
-export ALICE_XPRV=$(cat alice-key.json | jq -r '.xprv')
-
-export BOB_XPRV=$(cat bob-key.json | jq -r '.xprv')
-
-export CAROL_XPRV=$(cat carol-key.json | jq -r '.xprv')
-```
-
-### Step 3: Derive public extended keys
-
-For this example we are using the [BIP-84](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki) key path: `m/84h/1h/0h/0/*` to derive extended public keys to share with other wallet participants.
-
-Note that the `key derive` sub-command will generate a tpub for the last hardened node in the given derivation path. You'll also notice that `bdk-cli` will returns our tpub with the key origin (fingerprint/path) added to it (the metadata part that looks like `[5adb4683/84'/1'/0']` right before the tpub). This key origin information is not necessary in order to use a tpub and generate addresses, but it's good practice to include it because some signers require it.
-
-```bash
-export ALICE_XPUB=$(bdk-cli key derive --xprv $ALICE_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-echo \"$ALICE_XPUB\"
-"[5adb4683/84'/1'/0']tpubDCyRBuncqwyAjSNiw1GWLmwQsWyhgPMEBpx3ZNpnCwZwf3HXerspTpaneN81KRxkwj8vjqH9pNWEPgNhen7dfE212SHfxBBbsCywxQGxvvu/0/*"
-
-export BOB_XPUB=$(bdk-cli key derive --xprv $BOB_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-echo \"$BOB_XPUB\"
-"[5fdec309/84'/1'/0']tpubDDQcUeBH9JFtgZEsHZBhmRu8AuZ8ceJY1umnipPVEg1had2coGMCWdFBXNnZWKoCPic3EMgDZTdmkAVNoakwNZu2ESSW36rQvts6VXGx4bU/0/*"
-
-export CAROL_XPUB=$(bdk-cli key derive --xprv $CAROL_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
-echo \"$CAROL_XPUB\"
-"[de41e56d/84'/1'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/0/*"
-```
-
-### Step 4: Create wallet descriptors for each participant
-
-We used the [BDK Playground Policy Compiler](https://bitcoindevkit.org/bdk-cli/playground/) to compile the [miniscript](http://bitcoin.sipa.be/miniscript/) policy:
-
-`thresh(3,pk(Alice),pk(Bob),pk(Carol),older(2))`
-
-To the [output descriptor](https://bitcoindevkit.org/descriptors/):
-
-`wsh(thresh(3,pk(Alice),s:pk(Bob),s:pk(Carol),sdv:older(2)))`
-
-This descriptor requires spending transaction inputs must be signed by all three signers, or by two signers and the spent UTXOs must be older than two blocks.
-
-Each participant's descriptor only uses their own XPRV key plus the XPUB keys of the other participants.
-
-```bash
-export ALICE_DESCRIPTOR="wsh(thresh(3,pk($ALICE_XPRV/84'/1'/0'/0/*),s:pk($BOB_XPUB),s:pk($CAROL_XPUB),sdv:older(2)))"
-
-export BOB_DESCRIPTOR="wsh(thresh(3,pk($ALICE_XPUB),s:pk($BOB_XPRV/84'/1'/0'/0/*),s:pk($CAROL_XPUB),sdv:older(2)))"
-
-export CAROL_DESCRIPTOR="wsh(thresh(3,pk($ALICE_XPUB),s:pk($BOB_XPUB),s:pk($CAROL_XPRV/84'/1'/0'/0/*),sdv:older(2)))"
-```
-
-## Policy A. Three signatures
-
-### Step 1a: Create a testnet [segwit0](https://en.bitcoin.it/wiki/Segregated_Witness) receive address
-
-This step can be done independently by Alice, Bob, or Carol.
-
-```bash
-bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR get_new_address
-{
-  "address": "tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e"
-}
-```
-
-### Step 2a: Send testnet bitcoin from a faucet to receive address
-
-After a faucet payment is sent, use a testnet block explorer to confirm the transaction was included in a block.
-
-[https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e](https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e)
-
-### Step 3a: Sync participant wallets and confirm balance
-
-This step must be done by Alice, Bob, and Carol so their individual descriptor wallets know about the faucet transaction they will later be spending the output of.
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
-{}
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
-{
-  "satoshi": 10000
-}
-
-bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sync
-{}
-bdk-cli wallet -w bob -d $BOB_DESCRIPTOR get_balance
-{
-  "satoshi": 10000
-}
-
-bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR sync
-{}
-bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR get_balance
-{
-  "satoshi": 10000
-}
-```
-
-### Step 4a: View wallet spending policies
-
-This can also be done by any wallet participant, as long as they have the same descriptor and extended public keys from the other particpants..
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR policies
-{
-  "external": {
-    "contribution": {
-      "conditions": {
-        "0": [
-          {}
-        ],
-        "3": [
-          {
-            "csv": 2
-          }
-        ]
-      },
-      "items": [
-        0,
-        3
-      ],
-      "m": 3,
-      "n": 4,
-      "type": "PARTIAL"
-    },
-    "id": "ydtnup84",
-    "items": [
-      {
-        "contribution": {
-          "condition": {},
-          "type": "COMPLETE"
-        },
-        "fingerprint": "5adb4683",
-        "id": "uyxvyzqt",
-        "satisfaction": {
-          "type": "NONE"
-        },
-        "type": "SIGNATURE"
-      },
-      {
-        "contribution": {
-          "type": "NONE"
-        },
-        "fingerprint": "5fdec309",
-        "id": "dzkmxcgu",
-        "satisfaction": {
-          "type": "NONE"
-        },
-        "type": "SIGNATURE"
-      },
-      {
-        "contribution": {
-          "type": "NONE"
-        },
-        "fingerprint": "de41e56d",
-        "id": "ekfu5uaw",
-        "satisfaction": {
-          "type": "NONE"
-        },
-        "type": "SIGNATURE"
-      },
-      {
-        "contribution": {
-          "condition": {
-            "csv": 2
-          },
-          "type": "COMPLETE"
-        },
-        "id": "8kel7sdw",
-        "satisfaction": {
-          "type": "NONE"
-        },
-        "type": "RELATIVETIMELOCK",
-        "value": 2
-      }
-    ],
-    "satisfaction": {
-      "type": "NONE"
-    },
-    "threshold": 3,
-    "type": "THRESH"
-  },
-  "internal": null
-}
-```
-
-### Step 5a: Create spending transaction
-
-The transaction can also be created by Alice, Bob, or Carol, or even an untrusted coordinator that only has all three tpubs.
-
-Note that the argument provided to the --external_policy flag contains the id retrieved from the `policies` subcommand in the above step, in this case `ydtnup84`.
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,2]}"
-{
-  "details": {
-    "fees": 169,
-    "height": null,
-    "received": 0,
-    "sent": 10000,
-    "timestamp": 1614058791,
-    "transaction": null,
-    "txid": "3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"
-  },
-  "psbt": "cHNidP8BAFIBAAAAAYx7T0cL7EoUYBEU0mSL6+DS4VQafUzJgAf0Ftlbkya5AQAAAAD/////AWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgCBH16JNfSPhmjJR75EdDB+gSCEF7tStNOLqw/k3BvA0BBXchA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxrHwhA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mrJN8IQIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOKyTfHZjUrJpaJNThyIGAi82No/6bA0LQO2BoHoQ0H8M8+VtQNHr41nhLDTvSPM4DO66tnIAAAAAAAAAACIGA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxGFrbRoNUAACAAQAAgAAAAIAAAAAAAAAAACIGA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mDEMxpeYAAAAAAAAAAAAA"
-}
-
-export UNSIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,2]}" | jq -r ".psbt")
-```
-
-### Step 6a: Sign and finalize PSBTs
-
-```bash
-# ALICE SIGNS
-export ALICE_SIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sign --psbt $UNSIGNED_PSBT | jq -r ".psbt")
-
-# BOB SIGNS
-export ALICE_BOB_SIGNED_PSBT=$(bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sign --psbt $ALICE_SIGNED_PSBT | jq -r ".psbt")
-
-# CAROL SIGNS
-export FINAL_PSBT=$(bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR sign --psbt $ALICE_BOB_SIGNED_PSBT | jq -r ".psbt")
-
-## PSBT is finalized
-bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR sign --psbt $ALICE_BOB_SIGNED_PSBT
-{
-  "is_finalized": true,
-  "psbt": "cHNidP8BAFIBAAAAAYx7T0cL7EoUYBEU0mSL6+DS4VQafUzJgAf0Ftlbkya5AQAAAAD/////AWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgCBH16JNfSPhmjJR75EdDB+gSCEF7tStNOLqw/k3BvA0iAgIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOEcwRAIgRPXSwFLfzD1YQzw5FGYA0TgiQ+D88hSOVDbvyUZDiPUCIAbguaSGgCbBAXo5sIxpZ4c1dcGkYyrrqnDjc1jcdJ1CASICA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxSDBFAiEA0kdkvlA+k5kUBWVUM8SkR4Ua9pnXF66ECVwIM1l0doACIF0aMiORVC35+M3GHF2Vl8Q7t455mebrr1HuLaAyxBOYASICA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mRzBEAiBPJlQEnuVDHgfgOdTZNlIcRZz2iqHoMWfDmLMFqJSOQAIgCuOcTKp/VaaqwIjnYfMKO3eQ1k9pOygSWt6teT1o13QBAQV3IQN3NQJNpHBjszoenkVxSn6Z6cz9Zc33FyGIcRRmRudZsax8IQO+WA10Swy7fnl+VLBNN5iBlErED9jKyfZZte3Blw8NpqyTfCECLzY2j/psDQtA7YGgehDQfwzz5W1A0evjWeEsNO9I8zisk3x2Y1KyaWiTU4ciBgIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOBjeQeVtVAAAgAEAAIAAAACAAAAAAAAAAAAiBgN3NQJNpHBjszoenkVxSn6Z6cz9Zc33FyGIcRRmRudZsQwpbm6KAAAAAAAAAAAiBgO+WA10Swy7fnl+VLBNN5iBlErED9jKyfZZte3Blw8NpgxDMaXmAAAAAAAAAAABBwABCP1TAQUARzBEAiBE9dLAUt/MPVhDPDkUZgDROCJD4PzyFI5UNu/JRkOI9QIgBuC5pIaAJsEBejmwjGlnhzV1waRjKuuqcONzWNx0nUIBRzBEAiBPJlQEnuVDHgfgOdTZNlIcRZz2iqHoMWfDmLMFqJSOQAIgCuOcTKp/VaaqwIjnYfMKO3eQ1k9pOygSWt6teT1o13QBSDBFAiEA0kdkvlA+k5kUBWVUM8SkR4Ua9pnXF66ECVwIM1l0doACIF0aMiORVC35+M3GHF2Vl8Q7t455mebrr1HuLaAyxBOYAXchA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxrHwhA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mrJN8IQIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOKyTfHZjUrJpaJNThwAA"
-```
-
-### Step 7a: Broadcast finalized PSBT
-
-```bash
-bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR broadcast --psbt $FINAL_PSBT
-{
-  "txid": "3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"
-}
-```
-
-### Step 8a: Confirm transaction included in a testnet block
-
-[https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e](https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e)
-
-And new wallet balance is now zero.
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
-{}
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
-{
-  "satoshi": 0
-}
-```
-
-### DONE!
-
-## Policy B. Two signatures after a relative time lock
-
-Now we will use the same extended private and public keys, and the same descriptors to receive and spend testnet bitcoin using only two of our participants signatures after the transaction input's relative time-lock has expired.
-
-### Step 1b: Create a new testnet receive address
-
-The receive address can still be generated by Alice, Bob, or Carol.
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_new_address
-{
-  "address": "tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9"
-}
-```
-
-### Step 2b: Fund new address from testnet faucet
-
-After the faucet payment is sent, confirm using a testnet block explorer to verify the transaction was included in a block.
-
-[https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9](https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9)
-
-### Step 3b: Sync wallet and confirm wallet balance
-
-This step must be done by Alice and Bob so their individual descriptor wallets know about the faucet transaction they will later be spending the output of.
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
-{}
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
-{
-  "satoshi": 10000
-}
-
-bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sync
-{}
-bdk-cli wallet -w bob -d $BOB_DESCRIPTOR get_balance
-{
-  "satoshi": 10000
-}
-
-# NO CAROL SHE LOST HER KEY!
-```
-
-### Step 4b: Create spending transaction
-
-This spending transaction uses Alice and Bob's keys plus a two block relative time-lock, see above [Step 4a](#step-4a-view-wallet-spending-policies) for the policy id. The transaction can be created by Alice or Bob.
-
-A time based relative time-lock can be used instead of one based on blocks but is slightly more complicated to calculate. See
-[BIP-68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#specification) for the details.
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,3]}"
-{
-  "details": {
-    "fees": 169,
-    "height": null,
-    "received": 0,
-    "sent": 10000,
-    "timestamp": 1614059434,
-    "transaction": null,
-    "txid": "6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"
-  },
-  "psbt": "cHNidP8BAFICAAAAAYmc6mhj4Cf4pcJyBvxSbCd9IB1yDGs+plzb95t7++v0AAAAAAACAAAAAWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgOfTlC2vtnGDNEC2n4j++Wxusqryh4QyqDCqEOQZ5mm4BBXchAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCpprHwhAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFrJN8IQOrU70B/wo/oUUCKFQ2cIsBxx6SysE7uVwxyu0ozM4zYqyTfHZjUrJpaJNThyIGAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCppGFrbRoNUAACAAQAAgAAAAIAAAAAAAQAAACIGAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFDEMxpeYAAAAAAQAAACIGA6tTvQH/Cj+hRQIoVDZwiwHHHpLKwTu5XDHK7SjMzjNiDO66tnIAAAAAAQAAAAAA"
-}
-
-export UNSIGNED_PSBT2=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,3]}" | jq -r ".psbt")
-```
-
-### Step 5b: Sign and finalize PSBTs
-
-```bash
-# ALICE SIGNS
-export ALICE_SIGNED_PSBT2=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sign --psbt $UNSIGNED_PSBT2 | jq -r ".psbt")
-
-# BOB SIGNS
-export FINAL_PSBT2=$(bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sign --psbt $ALICE_SIGNED_PSBT2 | jq -r ".psbt")
-
-# CAROL DOES *NOT* SIGN
-```
-
-### Step 6b: Broadcast finalized PSBT
-
-```bash
-bdk-cli wallet -w bob -d $BOB_DESCRIPTOR broadcast --psbt $FINAL_PSBT2
-thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Electrum(Protocol(String("sendrawtransaction RPC error: {\"code\":-26,\"message\":\"non-BIP68-final\"}")))', src/bdk_cli.rs:168:50
-
-# Oops we didn't wait long enough for the relative time lock to expire
-
-# Try again in ~20 mins and it is successfully broadcast
-
-bdk-cli wallet -w bob -d $BOB_DESCRIPTOR broadcast --psbt $FINAL_PSBT2
-{
-  "txid": "6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"
-}
-```
-
-### Step 7b: View confirmed transaction
-
-[https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28](https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28)
-
-And wallet balance is again zero
-
-```bash
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
-{}
-bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
-{
-  "satoshi": 0
-}
-```
-
-### Done again!
-
-In this demo we showed how to receive and spend bitcoin using two different descriptor wallet policies using the `bdk` library and `bdk-cli` wallet tool.
diff --git a/docs/tutorials/Bitcoin_Core_RPC_Demo.md b/docs/tutorials/Bitcoin_Core_RPC_Demo.md
new file mode 100644 (file)
index 0000000..cff2d6f
--- /dev/null
@@ -0,0 +1,666 @@
+---
+title: "Using BDK to build a wallet backed by a Bitcoin Core full node"
+description: "Tutorial showing usage of Bitcoin core backend with BDK wallet"
+authors:
+    - Rajarshi Maitra
+date: "2021-08-21"
+tags: ["tutorial", "BDK", "Bitcoin Core", "RPC", "Wallet"]
+hidden: true
+draft: false
+---
+
+### Introduction
+BDK wallet developer library can be used to easily deploy wallets with various kinds of blockchain backend support, like [`electrum`](https://github.com/romanz/electrs), [`esplora`](https://github.com/Blockstream/esplora), `compact-filters` ([BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki)) etc. With the latest release of BDK [`v0.10.0`](https://github.com/bitcoindevkit/bdk/releases/tag/v0.10.0), BDK now supports Bitcoin Core as a blockchain backend. BDK talks with Bitcoin Core using rust-bitcoin's [bitcoincore-rpc](https://github.com/rust-bitcoin/rust-bitcoincore-rpc) library.
+
+This allows wallet devs to quickly deploy their wallet that can talk to a bitcoin full node (home raspi nodes) out of the box. Wallet devs don't need to worry about connecting to a full node with correct RPC calls, all of that is handled by BDK under the hood. All they need is to identify the full node's RPC IP address and the correct RPC credentials.
+
+In this tutorial we will see how to write a very simplistic wallet code that can connect to a bitcoin core node and maintain its balance and make transactions.
+
+Unlike other tutorials, we will not use `bdk-cli` tools, but instead write rust code directly using `BDK` devkit. In the end we will end up with our own simple bitcoin wallet.
+
+### Prerequisite
+To run with this tutorial you would need to have a bitcoin core node running in regtest mode. Get the bitcoin core binary either from the [bitcoin core repo](https://bitcoincore.org/bin/bitcoin-core-0.21.1/) or [build from source](https://github.com/bitcoin/bitcoin/blob/v0.21.1/doc/build-unix.md).
+
+Then configure the node with a following `bitcoin.conf` file
+```txt
+regtest=1
+fallbackfee=0.0001
+server=1
+txindex=1
+rpcuser=admin
+rpcpassword=password
+```
+
+Apart from that, you would need to install rust in your system. Grab the installation one-liner from [here](https://www.rust-lang.org/tools/install). 
+
+### Setting Up
+Create a new cargo binary repository.
+```shell
+mkdir ~/tutorial
+cd tutorial
+cargo new bdk-example
+cd bdk-example
+```
+This will create a new project folder named `bdk-example` with `src/main.rs` and a `cargo.toml`. 
+```shell
+$ tree -L 3 .
+.
+├── Cargo.toml
+└── src
+    └── main.rs
+
+1 directory, 2 files
+```
+Opening `main.rs` you will see some predefined code like this
+
+``` rust
+fn main() {
+    println!("Hello, world!");
+}
+```
+Try running `cargo run` and if everything is set, you should see "Hello, world!" printed in your terminal
+```shell
+$ cargo run
+    Compiling bdk-example v0.1.0 (/home/raj/github-repo/tutorial/bdk-example)
+    Finished dev [unoptimized + debuginfo] target(s) in 0.95s
+    Running `target/debug/bdk-example`
+Hello, world!
+```
+Of course we will not use the given `println!()` statement, but we will put our main code in the `main()` function.
+
+`cargo new` will also produce a skeleton `Cargo.toml` file like this
+```toml
+[package]
+name = "bdk-example"
+version = "0.1.0"
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+```
+
+### Setting dependencies
+Once the rust binary is compiled and running, we now need to specify the dependencies we need to work on our library.
+
+Remember that BDK provides almost everything we would need to build a wallet out of the box. So we don't need any more dependencies apart from BDK. We will use another small rust crate called [`dirs_next`](https://crates.io/crates/dirs-next) to find our home directory and store wallet files in a subfolder there.
+
+Add the dependencies into `Cargo.toml` like below
+```toml
+[package]
+name = "bdk-example"
+version = "0.1.0"
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+bdk = { version = "^0.10", default-features = false, features = ["all-keys", "key-value-db", "rpc"]}
+dirs-next = "2.0"
+```
+We disabled the default BDK feature (which specifies blockchain backend as an electrum server) and we requested the following features:
+ - **all-keys**: Adds BIP39 key derivation capabilities
+ - **key-value-db**: Adds a persistance storage capability
+ - **rpc**: Adds the RPC blockchain backend capability.
+
+Now that we have the dependcies added, we can import them in the `main.rs` file to use in our code.
+Add the following imports at the start of `main.rs`
+
+```rust
+use bdk::bitcoin::Network;
+use bdk::bitcoin::secp256k1::Secp256k1;
+use bdk::bitcoin::util::bip32::{DerivationPath, KeySource};
+use bdk::bitcoin::Amount;
+use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};
+
+use bdk::blockchain::rpc::{Auth, RpcBlockchain, RpcConfig, wallet_name_from_descriptor};
+use bdk::blockchain::{ConfigurableBlockchain, NoopProgress};
+
+use bdk::keys::bip39::{Mnemonic, Language, MnemonicType};
+use bdk::keys::{GeneratedKey, GeneratableKey, ExtendedKey, DerivableKey, DescriptorKey};
+use bdk::keys::DescriptorKey::Secret;
+
+use bdk::miniscript::miniscript::Segwitv0;
+
+use bdk::Wallet;
+use bdk::wallet::{AddressIndex, signer::SignOptions};
+
+use bdk::sled;
+
+use std::str::FromStr;
+```
+With this we are now ready to add our wallet code.
+
+### Getting Descriptors
+
+BDK is a descriptor based wallet library. That means when we specify our wallet key-chain we need to tell BDK about it in the format of a descriptor. You can read up on descriptors more [here](https://bitcoindevkit.org/descriptors/). A descriptor string looks like this
+`"wpkh([b8b575c2/84'/1'/0'/0]tprv8icWtRzy9CWgFxpGMLSdAeE4wWyz39XGc6SwykeTo13tYm14JkVVQAf7jz8WDDarCgNJrG3aEPJEqchDWeJdiaWpS3FwbLB9SzsN57V7qxB/*)"`.
+
+This describes a SegwitV0 descriptor of a key derived at path `m/84'/1'/0'/0`. If you already have a descriptor from other sources, you can use that. Otherwise, BDK has your back. BDK can be used to generate a fresh master key with mnemonic, and then derive child keys from it given a specific path. Putting the key in a descriptor is as simple as wrapping it with a `wpkh()` string.
+
+We will use a dedicated function that will create fresh receive and change descriptors from BDK for our purpose. It will also generate the mnemonic word list for later regenerating the wallet. But we will ignore that for our scope.
+
+Add a function named `get-descriptor()` below the `main()` function as shown
+```rust
+fn main() {
+    ...
+}
+
+// generate fresh descriptor strings and return them via (receive, change) tuple
+fn get_descriptors() -> (String, String) {
+    // Create a new secp context
+    let secp = Secp256k1::new();
+     
+    // You can also set a password to unlock the mnemonic
+    let password = Some("random password".to_string());
+
+    // Generate a fresh mnemonic, and from there a privatekey
+    let mnemonic: GeneratedKey<_, Segwitv0> =
+                Mnemonic::generate((MnemonicType::Words12, Language::English)).unwrap();
+    let mnemonic = mnemonic.into_key();
+    let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
+    let xprv = xkey.into_xprv(Network::Regtest).unwrap();
+
+    // Create derived privkey from the above master privkey
+    // We use the following derivation paths for receive and change keys
+    // receive: "m/84h/1h/0h/0"
+    // change: "m/84h/1h/0h/1" 
+    let mut keys = Vec::new();
+
+    for path in ["m/84h/1h/0h/0", "m/84h/1h/0h/1"] {
+        let deriv_path: DerivationPath = DerivationPath::from_str(path).unwrap();
+        let derived_xprv = &xprv.derive_priv(&secp, &deriv_path).unwrap();
+        let origin: KeySource = (xprv.fingerprint(&secp), deriv_path);
+        let derived_xprv_desc_key: DescriptorKey<Segwitv0> =
+        derived_xprv.into_descriptor_key(Some(origin), DerivationPath::default()).unwrap();
+
+        // Wrap the derived key with the wpkh() string to produce a descriptor string
+        if let Secret(key, _, _) = derived_xprv_desc_key {
+            let mut desc = "wpkh(".to_string();
+            desc.push_str(&key.to_string());
+            desc.push_str(")");
+            keys.push(desc);
+        }
+    }
+    
+    // Return the keys as a tuple
+    (keys[0].clone(), keys[1].clone())
+}
+```
+
+To check that the above added function is working as expected, call it in the main function and print the descriptors
+``` rust
+use ...
+
+fn main() {
+    let (receive_desc, change_desc) = get_descriptors();
+    println!("recv: {:#?}, \nchng: {:#?}", receive_desc, change_desc);
+}
+
+fn get_descriptors() -> (String, String) {
+    ...
+}
+```
+Running the binary should produces the following result
+```shell
+$ cargo run
+recv: "wpkh([89df6a67/84'/1'/0'/0]tprv8iSRXyLtTKJN9qt1jyPVqwhDMEaYztXunPaRQznaH1z8gj8e2g7RnF2ZoHP56VEXwMn76AiV1Je6nJmZbFistwAQCrRGmSrsoKfdqfTDNA1/*)", 
+chng: "wpkh([89df6a67/84'/1'/0'/1]tprv8iSRXyLtTKJNCECQxBJ19cgx2ueS7mC7GNq7VqTWY3RNPMBY7DfTb9HUnXpJqa14jCJNRmi4yGxfoTVS4WLBXDkvTLq4vujeAD9NfDtSxGP/*)"
+```
+Voila! Now we have nice descriptors strings handy to use for our BDK wallet construction.
+
+### Talking to Bitcoin Core Programmatically
+Like all other tutorials we will use two wallets to send coins back and forth. A Bitcoin Core wallet accessible via `bitcoin-cli` command line tools, and a BDK wallet maintained by BDK library.    
+
+But unlike other tutorials, we won't be using `bitcoin-cli` to talk to the Core wallet (we can, but let's spice things up). Instead, we will use the `bitcoin-rpc` library, to talk with our core node listening at `127.0.0.1:18443`, from inside our main function. This will allow us to write code, that will handle both the core and BDK wallet, from inside of the same function, and we won't have to switch terminals!
+
+Remember we imported `use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};`? Thats exactly for this purpose.
+
+Start the `bitcoind` node.
+
+you should see bitcoind listening at port 18443
+```shell
+$ sudo netstat -nptl | grep 18443 
+tcp        0      0 0.0.0.0:18443           0.0.0.0:*               LISTEN      135532/bitcoind 
+```
+
+Lets create a core rpc interface in our main function.
+```rust
+fn main() {
+    ...
+    
+    // Create a RPC interface
+    let rpc_auth = rpc_auth::UserPass(
+        "admin".to_string(),
+        "password".to_string()
+    ); 
+    let core_rpc = Client::new("http://127.0.0.1:18443/wallet/test".to_string(), rpc_auth).unwrap();
+    println!("{:#?}", core_rpc.get_blockchain_info().unwrap());
+}
+```
+We have provided our RPC authentication `username` and `password` (same as provided in `bitcoin.conf` file).
+We have provided the RPC address of our local bitcoin node, with the path to a wallet file, named `test`. And then asked the rpc client to give us the current blockchain info.
+If everything goes well, running `cargo run` you should see an output like below:
+```shell
+$ cargo run
+...
+GetBlockchainInfoResult {
+    chain: "regtest",
+    blocks: 0,
+    headers: 0,
+    best_block_hash: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206,
+    difficulty: 0.00000000046565423739069247,
+    median_time: 1296688602,
+    verification_progress: 1.0,
+    initial_block_download: true,
+    ...
+```
+Thats it. Now we can programmatically talk to our core node.
+
+### Get some balance in core wallet.
+We have told our rpc client that we would use a wallet named `test`. But currently, our core node doesn't have such a wallet. So let's create the wallet and fund it with some test coins.
+```rust
+fn main() {
+    ...
+
+    // Create the test wallet 
+    core_rpc.create_wallet("test", None, None, None, None).unwrap();
+    
+    // Get a new address
+    let core_address = core_rpc.get_new_address(None, None).unwrap();
+    
+    // Generate 101 blocks and use the above address as coinbase
+    core_rpc.generate_to_address(101, &core_address).unwrap();
+    
+    // fetch the new balance
+    let core_balance = core_rpc.get_balance(None, None).unwrap();
+    
+    // Show balance
+    println!("core balance: {:#?}", core_balance);
+}
+```
+This will create a wallet in bitcoin core named `test`. generate 101 blocks and use a new address from the wallet as coinbase wallet. Because required coinbase maturity in bitcoin is 100 blocks, by generating 101 blocks, we will have the balance of the first coinbase block reward available for use.
+The last `println!()` statement will show the new updated balance as 50 BTC.
+```shell
+$ cargo run
+...
+core balance: Amount(50.00000000 BTC)       
+```
+Great! We now have 50 regtest BTC to play with.
+
+### Setup the BDK wallet
+Now that we are done setting up the core wallet. The last remaining step is to setup the BDK wallet. For this we will use the previous descriptor generation function and write code as below.
+
+**Note**: You might want to comment out the previous code in `main()`, as running them again will create more coins in core, which isn't an issue, but might be confusing.
+
+```rust
+fn main() {
+    ...
+
+    // Get receive and change descriptor
+    let (receive_desc, change_desc) = get_descriptors();
+    
+    // Use deterministic wallet name derived from descriptor
+    let wallet_name = wallet_name_from_descriptor(
+        &receive_desc,
+        Some(&change_desc),
+        Network::Regtest,
+        &Secp256k1::new()
+    ).unwrap();
+
+    // Create the datadir to store wallet data
+    let mut datadir = dirs_next::home_dir().unwrap();
+    datadir.push(".bdk-example");
+    let database = sled::open(datadir).unwrap();
+    let db_tree = database.open_tree(wallet_name.clone()).unwrap();
+
+    // Set RPC username, password and url
+    let auth = Auth::UserPass {
+        username: "admin".to_string(),
+        password: "password".to_string()
+    };
+    let mut rpc_url = "http://".to_string();
+    rpc_url.push_str("127.0.0.1:18443");
+
+    // Setup the RPC configuration
+    let rpc_config = RpcConfig {
+        url: rpc_url,
+        auth,
+        network: Network::Regtest,
+        wallet_name,
+        skip_blocks: None,
+    };
+
+    // Use the above configuration to create a RPC blockchain backend
+    let blockchain = RpcBlockchain::from_config(&rpc_config).unwrap();
+
+    // Combine everything and finally create the BDK wallet structure
+    let wallet = Wallet::new(&receive_desc, Some(&change_desc), Network::Regtest, db_tree, blockchain).unwrap();
+
+    // Sync the wallet
+    wallet.sync(NoopProgress, None).unwrap();
+
+    // Fetch a fresh address to receive coins
+    let address = wallet.get_address(AddressIndex::New).unwrap().address;
+
+    println!("bdk address: {:#?}", address);
+}
+```
+That's a lot of code. They are divided into logical sections. Let's discuss each step one by one.
+ - First we used our previous `get_descriptors()` function to generate two descriptor strings. One for generating receive addresses and one for change addresses.
+ - Then we used a special function from BDK called `wallet_name_from_descriptor()` to derive a name of the wallet from our descriptors. This allows us to have wallet names deterministically linked with descriptors. So in future if we use a different descriptor, the wallet will automatically have a different name. This allows us to not mix wallet names with same descriptor, and given the descriptors we can always determine what was the name we used. It is recommended to derive wallet names like this while using a core backend. Note that this wallet will be created inside the core node. So just like we accessed the `test` wallet, we could also access this wallet.
+ - Then we created a data directory at path `/home/username/.bdk-example`. We use `dirs_next` to find our home path, and then appended that with `.bdk-example`. All the BDK wallet files will be created and maintained in that directory. In the Database we instructed BDK to create a new `Tree` with `wallet_name`, so given a descriptor, BDK will always know which DB Tree to refer (`Tree` is a `sled` specific term).
+ - Then like we did previously, we created the rpc username/password authentication, and specified the rpc url. Note that we cannot use the same `rpc_auth` we used before for `core_rpc` as BDK auth and bitcoin-rpc auth are slightly separate structures.
+ - We combined all this information and created an `RpcConfig` structure.
+ - We used the rpc configuration to create a `RpcBlockchain` structure.
+ - Finally we used the Descriptors, Database, and Blockchain to create our final BDK `wallet` structure.
+
+Now that we have a our wallet cooked, in the end, we instructed it to sync with the bitcoin core backend, and fetch us a new address.
+
+If all goes well, you should see an address printed in the terminal.
+
+```shell
+cargo run
+    Finished dev [unoptimized + debuginfo] target(s) in 2.99s
+    Running `target/debug/bdk-example`
+bdk address: bcrt1q9vkmujggvzs0rd4z6069v3v0jucje7ua7ap308
+```
+
+### Sending Sats Around
+
+Now that we have covered all the groundwork, we have all we need to send coins back and forth between core and BDK wallet.
+
+We will keep things simple here and make the following actions
+ - Send 10 BTC from Core to BDK
+ - Send back 5 BTC from BDK to Core
+ - Display balance of two wallets
+
+In the last line of previous section we got a new address from BDK wallet. We will start from there. Without further discussion lets jump straight into code.
+
+```rust
+fn main() {
+    ...
+
+    // Fetch a fresh address to receive coins
+    let address = wallet.get_address(AddressIndex::New).unwrap().address;
+
+    // Send 10 BTC from Core to BDK
+    core_rpc.send_to_address(&address, Amount::from_btc(10.0).unwrap(), None, None, None, None, None, None).unwrap();
+
+    // Confirm transaction by generating some blocks
+    core_rpc.generate_to_address(1, &core_address).unwrap();
+
+    // Sync the BDK wallet
+    wallet.sync(NoopProgress, None).unwrap();
+    
+    // Create a transaction builder
+    let mut tx_builder = wallet.build_tx();
+
+    // Set recipient of the transaction
+    tx_builder.set_recipients(vec!((core_address.script_pubkey(), 500000000)));
+
+    // Finalise the transaction and extract PSBT
+    let (mut psbt, _) = tx_builder.finish().unwrap();
+
+    // Set signing option
+    let signopt = SignOptions {
+        assume_height: None,
+        ..Default::default()
+    };
+
+    // Sign the above psbt with signing option
+    wallet.sign(&mut psbt, signopt).unwrap();
+
+    // Extract the final transaction
+    let tx = psbt.extract_tx();
+
+    // Broadcast the transaction
+    wallet.broadcast(tx).unwrap();
+
+    // Confirm transaction by generating some blocks
+    core_rpc.generate_to_address(1, &core_address).unwrap();
+
+    // Sync the BDK wallet
+    wallet.sync(NoopProgress, None).unwrap();
+
+    // Fetch and display wallet balances
+    let core_balance = core_rpc.get_balance(None, None).unwrap();
+    let bdk_balance = Amount::from_sat(wallet.get_balance().unwrap());
+    println!("core wallet balance: {:#?}", core_balance);
+    println!("BDK wallet balance: {:#?}", bdk_balance);
+}
+```
+
+The above code segment is mostly straight forward. The only new thing added is `wallet.build_tx()` which returns a `TxBuilder`. BDK allows us to have very fine grained control of cooking up transactions. Almost everything that is possible to do with a Bitcoin transaction can be done in BDK. Here we have a very simple vanilla transaction with no added magic. To get full list of capabilities that `TxBuilder` supports scour its implementation [here](https://github.com/bitcoindevkit/bdk/blob/38d1d0b0e29d38cd370c740d798d96a3c9fcaa1f/src/wallet/tx_builder.rs#L123-L153).
+
+Finally to step through what we did above:
+ - We asked core wallet to send 10 BTC to bdk wallet address.
+ - We confirmed the transaction, and synced the wallet.
+ - We asked BDK to create a transaction sending 5 BTC to core wallet address.
+ - We signed and broadcast the transaction. BDK will use the same core node to broadcast the transaction to network.
+ - We confirmed the transaction by mining a block, and synced the wallet.
+ - We fetched and displayed balance of both core and BDK wallet.
+
+If all goes well, you should see the final updated balance as below:
+```shell
+$ cargo run
+    Compiling bdk-example v0.1.0 (/home/raj/github-repo/bdk-example/bdk-example)
+    Finished dev [unoptimized + debuginfo] target(s) in 3.57s
+    Running `target/debug/bdk-example`
+core wallet balance: Amount(144.99998590 BTC)
+BDK wallet balance: Amount(4.99999859 BTC)
+```
+Voila! We have ~145 BTC (150 - 5) in core wallet and 5 BTC (10 - 5) in BDK wallet. The slight deficiency in the amount are due to transaction fees. Because we are using regtest, the fee is some standard value hardcoded in core node.
+
+Check out the data directory where BDK has created the wallet data files.
+
+```shell
+$ ls ~/.bdk-example/
+blobs  conf  db  snap.0000000000023CAB
+```
+
+And finally, this is what the final `main.rs` file looks like.
+
+```rust
+use bdk::bitcoin::Network;
+use bdk::bitcoin::secp256k1::Secp256k1;
+use bdk::bitcoin::util::bip32::{DerivationPath, KeySource};
+use bdk::bitcoin::Amount;
+use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};
+
+use bdk::blockchain::rpc::{Auth, RpcBlockchain, RpcConfig, wallet_name_from_descriptor};
+use bdk::blockchain::{ConfigurableBlockchain, NoopProgress};
+
+use bdk::keys::bip39::{Mnemonic, Language, MnemonicType};
+use bdk::keys::{GeneratedKey, GeneratableKey, ExtendedKey, DerivableKey, DescriptorKey};
+use bdk::keys::DescriptorKey::Secret;
+
+use bdk::miniscript::miniscript::Segwitv0;
+
+use bdk::Wallet;
+use bdk::wallet::{AddressIndex, signer::SignOptions};
+
+use bdk::sled;
+
+use std::str::FromStr;
+
+fn main() {
+    // Create a RPC interface
+    let rpc_auth = rpc_auth::UserPass(
+        "admin".to_string(),
+        "password".to_string()
+    ); 
+    let core_rpc = Client::new("http://127.0.0.1:18443/wallet/test".to_string(), rpc_auth).unwrap();
+
+    // Create the test wallet 
+    core_rpc.create_wallet("test", None, None, None, None).unwrap();
+    
+    // Get a new address
+    let core_address = core_rpc.get_new_address(None, None).unwrap();
+    
+    // Generate 101 blocks and use the above address as coinbase
+    core_rpc.generate_to_address(101, &core_address).unwrap();
+
+    // Get receive and change descriptor
+    let (receive_desc, change_desc) = get_descriptors();
+    
+    // Use deterministic wallet name derived from descriptor
+    let wallet_name = wallet_name_from_descriptor(
+        &receive_desc,
+        Some(&change_desc),
+        Network::Regtest,
+        &Secp256k1::new()
+    ).unwrap();
+
+    // Create the datadir to store wallet data
+    let mut datadir = dirs_next::home_dir().unwrap();
+    datadir.push(".bdk-example");
+    let database = sled::open(datadir).unwrap();
+    let db_tree = database.open_tree(wallet_name.clone()).unwrap();
+
+    // Set RPC username and password
+    let auth = Auth::UserPass {
+        username: "admin".to_string(),
+        password: "password".to_string()
+    };
+
+    // Set RPC url
+    let mut rpc_url = "http://".to_string();
+    rpc_url.push_str("127.0.0.1:18443");
+
+    // Setup the RPC configuration
+    let rpc_config = RpcConfig {
+        url: rpc_url,
+        auth,
+        network: Network::Regtest,
+        wallet_name,
+        skip_blocks: None,
+    };
+
+    // Use the above configuration to create a RPC blockchain backend
+    let blockchain = RpcBlockchain::from_config(&rpc_config).unwrap();
+
+    // Combine everything and finally create the BDK wallet structure
+    let wallet = Wallet::new(&receive_desc, Some(&change_desc), Network::Regtest, db_tree, blockchain).unwrap();
+
+    // Sync the wallet
+    wallet.sync(NoopProgress, None).unwrap();
+
+    // Fetch a fresh address to receive coins
+    let address = wallet.get_address(AddressIndex::New).unwrap().address;
+
+    // Send 10 BTC from Core to BDK
+    core_rpc.send_to_address(&address, Amount::from_btc(10.0).unwrap(), None, None, None, None, None, None).unwrap();
+
+    // Confirm transaction by generating some blocks
+    core_rpc.generate_to_address(1, &core_address).unwrap();
+
+    // Sync the BDK wallet
+    wallet.sync(NoopProgress, None).unwrap();
+
+    // Create a transaction builder
+    let mut tx_builder = wallet.build_tx();
+
+    // Set recipient of the transaction
+    tx_builder.set_recipients(vec!((core_address.script_pubkey(), 500000000)));
+
+    // Finalise the transaction and extract PSBT
+    let (mut psbt, _) = tx_builder.finish().unwrap();
+
+    // Set signing option
+    let signopt = SignOptions {
+        assume_height: None,
+        ..Default::default()
+    };
+
+    // Sign the above psbt with signing option
+    wallet.sign(&mut psbt, signopt).unwrap();
+
+    // Extract the final transaction
+    let tx = psbt.extract_tx();
+
+    // Broadcast the transaction
+    wallet.broadcast(tx).unwrap();
+
+    // Confirm transaction by generating some blocks
+    core_rpc.generate_to_address(1, &core_address).unwrap();
+
+    // Sync the BDK wallet
+    wallet.sync(NoopProgress, None).unwrap();
+
+    // Fetch and display wallet balances
+    let core_balance = core_rpc.get_balance(None, None).unwrap();
+    let bdk_balance = Amount::from_sat(wallet.get_balance().unwrap());
+    println!("core wallet balance: {:#?}", core_balance);
+    println!("BDK wallet balance: {:#?}", bdk_balance);
+}
+
+// generate fresh descriptor strings and return them via (receive, change) tupple 
+fn get_descriptors() -> (String, String) {
+    // Create a new secp context
+    let secp = Secp256k1::new();
+
+    // You can also set a password to unlock the mnemonic
+    let password = Some("random password".to_string());
+
+    // Generate a fresh menmonic, and from their, a fresh private key xprv
+    let mnemonic: GeneratedKey<_, Segwitv0> =
+                Mnemonic::generate((MnemonicType::Words12, Language::English)).unwrap();
+    let mnemonic = mnemonic.into_key();
+    let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
+    let xprv = xkey.into_xprv(Network::Regtest).unwrap();
+
+    // Derive our dewscriptors to use
+    // We use the following paths for recieve and change descriptor
+    // recieve: "m/84h/1h/0h/0"
+    // change: "m/84h/1h/0h/1" 
+    let mut keys = Vec::new();
+
+    for path in ["m/84h/1h/0h/0", "m/84h/1h/0h/1"] {
+        let deriv_path: DerivationPath = DerivationPath::from_str(path).unwrap();
+        let derived_xprv = &xprv.derive_priv(&secp, &deriv_path).unwrap();
+        let origin: KeySource = (xprv.fingerprint(&secp), deriv_path);
+        let derived_xprv_desc_key: DescriptorKey<Segwitv0> =
+        derived_xprv.into_descriptor_key(Some(origin), DerivationPath::default()).unwrap();
+
+        // Wrap the derived key with the wpkh() string to produce a descriptor string
+        if let Secret(key, _, _) = derived_xprv_desc_key {
+            let mut desc = "wpkh(".to_string();
+            desc.push_str(&key.to_string());
+            desc.push_str(")");
+            keys.push(desc);
+        }
+    }
+    
+    // Return the keys as a tupple
+    (keys[0].clone(), keys[1].clone())
+}
+```
+
+### Conclusion
+In this tutorial we saw some very basic BDK wallet functionality with a bitcoin core backend as the source and sync of blockchain data. This is just tip of the iceberg of BDK capabilities. BDK allows flexibility in all the dimensions of a bitcoin wallet, that is key chain, blockchain backend and database management. With all that power, we just implemented a trustless, non-custodial, private bitcoin wallet, backed by a bitcoin full node, with less than 200 lines of code (including lots of comments).
+
+BDK thus allows wallet devs, to only focus on stuff that they care about, writing wallet logic. All the backend stuff like blockchain, key management, and databases are abstracted away under the hood.
+
+To find and explore more about the BDK capabilities and how it can fit your development need refer the following resources.
+
+ - [source code](https://github.com/bitcoindevkit/bdk)
+ - [dev docs](https://docs.rs/bdk/0.10.0/bdk/)
+ - [community](https://discord.com/invite/d7NkDKm)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/tutorials/compact_filters_demo.md b/docs/tutorials/compact_filters_demo.md
new file mode 100644 (file)
index 0000000..283597f
--- /dev/null
@@ -0,0 +1,385 @@
+---
+title: "Using BDK to create BIP157 SPV wallet (aka Neutrino)"
+description: "Tutorial showing usage of compact filters (BIP157) using bdk-cli command line tools"
+authors:
+    - Rajarshi Maitra
+date: "2021-06-20"
+tags: ["tutorial", "BDK", "bdk-cli", "compact_filters", "BIP157", "Neutrino"]
+permalink: "/blog/2021/06/using-bdk-to-create-bip157-spv-wallet-aka-neutrino/"
+---
+
+## Introduction
+
+#### Compact Filters:
+Compact filters are the latest specification of Bitcoin SPV node implementation as per [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki) and [BIP158](https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki). Such light clients were envisioned by Satoshi himself in  his original white paper, but due to lack of robust privacy and trust guarantees using conventional [bloomfilters](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki), these type of nodes never got popular.
+
+Enters [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki), which described a new type of filters for Bitcoin Blockchain data, known as `compact_filters`. The [Neutrino](https://github.com/lightninglabs/neutrino) project pioneered the use of compact filter based light client nodes for using with Lightning Network wallets. Using compact filters, a light-node can talk to one or more full nodes, and fetch relevant information from the blockchain, with much more robust privacy and security guarantees than previously possible. Compact filter based nodes are best suitable to be used with mobile wallets, to create more trustless mobile applications on Bitcoin. Any wallet application that needs to have an "eye on the blockchain" has an use for such light clients.
+
+`BIP157` type filters allows to create tiny sized SPV nodes, that can fetch blockchain data and can identify inconsistency, so it can actively defend itself, while also preserving its privacy. Such nodes are most useful for Lightning Network mobile applications.
+
+Example of such `compact_filters` wallets in wild is [Breeze](https://github.com/breez/breezmobile) Lightning mobile wallet.
+
+Bitcoin core supports serving `BIP157` type filters from `v0.21.0`.
+
+#### BDK and Compact filters
+BDK is a bitcoin wallet development library that can be used to create bitcoin wallets with custom `Database` and `Blockchain` backends. BDK is a [descriptor](https://bitcoindevkit.org/descriptors/) based wallet, i.e. the wallet keychain is described by a set of descriptors.
+
+Using BDK one can instantiate wallets of various kinds as per requirement. BDK abstracts away all the heavy lifting works, and allow wallet devs to concentrate on logic that they care about, i.e. writing wallet codes. For more detailed documentation on BDK capabilities check these [blog](https://bitcoindevkit.org/blog/2020/12/hello-world/), [bog](https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/) and [docs](https://docs.rs/bdk/).
+
+The main three components of abstraction in BDK are
+  - `Database`
+  - `Descriptors`
+  - `Blockchain`
+
+BDK comes with default implementations of all them that developers can start with out of the box. Developers can also create there own custom implementations and plug it into BDK (thanks to rust magic of `Traits`).
+
+BDK also supports [BIP158](https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki) communication protocol, which allows creation of `BIP157` type compact filter SPV nodes. This capability is extended to wallet with BDK's `Blockchain` data structure. The [API](https://docs.rs/bdk/0.8.0/bdk/blockchain/trait.Blockchain.html) for `compact_filters` backend is similar to any other kind of backends, so wallet devs don't need to worry about all the details. Its ok if the dev haven't even heard of `BIP157`, BDK takes care of that in background.
+
+This capability can be unlocked by compiling BDK with the `compact_filters` feature. Once enabled, BDK will be able to create wallets with the `compact_filters` type `Blockchain` backend. (The default backend is electrum server)
+
+#### bdk-cli
+`bdk-cli` is a lightweight [REPL](https://codewith.mu/en/tutorials/1.0/repl) wrapper over the BDK library to facilitate quick and easy demonstration of BDK capabilities in command-line. Wallet devs can use this tool to quickly try out different possibilities with BDK.
+
+In this tutorial, We will use `bdk-cli` to demonstrate some basic wallet functionalities using `compact_filters` backend.
+
+## Tutorial Scope
+Basic wallet workflow we will cover:
+
+  - create and sync a wallet,
+  - receive a transaction,
+  - create a transaction,
+  - sign and broadcast the transaction,
+  - fetch updated balance,
+
+The BDK wallet will have a `BIP157` SPV backend (aka `compact_filters` backend) that will connect with a Bitcoin core node serving filter data.
+
+It will publish and extract transaction data through that node.
+
+We will have a Bitcoin Core wallet and a BDK wallet, sending and receiving transactions between each other, in regtest.
+
+## Prerequisites
+Following things are required to start with the tutorial.
+
+1. A Bitcoin Core regtest node listening at `localhost:18444` signalling for compact filter support.
+2. `bdk-cli` compiled with `compact_filter` features.
+
+If you already have these two setup and working, you can skip this and jump to the [Tutorial](#tutorial) section.
+
+#### Install and run `bitcoind`
+You can definitely do it with your own `bitcoind` installation. `BIP157` support has been included in Bitcoin Core `v0.21.0`. So anything above that will work.
+
+You also need to ensure proper configuration settings for signalling `compact_filters` support.
+
+For ease of testing, the BDK project hosts docker images that can be used to spawn Bitcoin Core with all the relevant configurations.
+
+- spawn a regtest node using [bitcoin-regtest-box](https://github.com/bitcoindevkit/bitcoin-regtest-box) docker file.
+
+  Start the regtest box docker container.
+
+  ```shell
+  $ docker run --detach --rm -p 127.0.0.1:18443-18444:18443-18444/tcp --name bdk-box bitcoindevkit/bitcoind
+  ```
+  This will spin up a docker container running `bicoind` and listening to port `18444` and `18333`. You can keep this terminal alive to see communication events with BDK and the node.
+
+- Check node is reachable
+
+  In another terminal try connecting to the node with `bitcoin-cli`
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest getnetworkinfo
+  {
+    "version": 210000,
+    "subversion": "/Satoshi:0.21.1/",
+    "protocolversion": 70016,
+    "localservices": "0000000000000449",
+    "localservicesnames": [
+      "NETWORK",
+      "WITNESS",
+      "COMPACT_FILTERS",
+      "NETWORK_LIMITED"
+      ...
+    ],
+  }
+
+  ```
+  In the output, the `version` should show `210000`. `localservicesnames` should contain `"COMPACT_FILTERS"`. If you see this, then Bitcoin Core is correctly configured.
+
+#### Install and run bdk-cli
+- Install `bdk-cli` with `compact_filters` feature
+
+  ```shell
+  $ cargo install --git https://github.com/bitcoindevkit/bdk-cli.git bdk-cli --features compact_filters
+  ```
+- Check installation
+  ```shell
+  $ bdk-cli --help
+  ...
+  USAGE:
+      bdk-cli [OPTIONS] <SUBCOMMAND>
+  FLAGS:
+      -h, --help Prints help information
+      -V, --version Prints version information
+  OPTIONS:
+      -n, --network <NETWORK> Sets the network [default: testnet]
+
+  SUBCOMMANDS:
+      help      Prints this message or the help of the given subcommand(s)
+      key       Key management sub-commands
+      repl      Enter REPL command loop mode
+      wallet    Wallet options and sub-commands
+  ```
+Once these are setup correctly, you can start with the tutorial next.
+
+
+
+## Tutorial
+[Note: For brevity `bdk-cli` results are stored in command line variables using `jq` tool. It is recommended to check the full results to see different information returned by `bdk-cli` commands.]
+
+### Bitcoin Core Wallet Generation
+
+This is standard procedure with `bitcoin-cli`.
+
+- Create a wallet and generate 101 blocks.
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest createwallet test
+  {
+    "name": "test",
+    "warning": ""
+  }
+  ```
+
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest getnewaddress
+  bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2
+  ```
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest generatetoaddress 101 bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2
+  [
+  "3813ed6eb716f4743b9657d918799acf743add985a8ded28d8aa3629dd4496b6",
+  "70da855913bdf791b6e458c611cebdef79b7a9840eb103ce58c71c1c7e3c49bc",
+  "682ca732ef72719cd6f82c5047c7690fb1cd2df2543d035ac4ea99e974b8d172",
+  "78799e4771017d4f46aa3c240054e2d61f54cea07ec44cb18ae712761e0aaa1e",
+  ...
+  ]
+  ```
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest getbalance
+  50.00000000
+  ```
+  Now the core wallet has generated new blocks and is funded with test bitcoin.
+
+
+### BDK Wallet Generation
+BDK is a descriptor based wallet library. So in order to use it we will need some descriptors to work with.
+
+BDK wallet will ask for two descriptors as input, corresponding to `receive` and `change` addresses. Its recommended to have these two descriptors separate as BDK will handle them separately and ensure `change` addresses are never used for receiving funds.
+
+Or developers can decide to use a single descriptor too, in that case BDK will use that descriptor for deriving both `receive` and `change` addresses.
+
+We will use `bdk-cli` itself to generate such descriptors.
+
+- #### Generate a privatekey
+  ```shell
+  $ BDK_xprv=$(bdk-cli key generate | jq -r '.xprv')
+  $ echo $BDK_xprv
+  tprv8ZgxMBicQKsPefY7tdq7EKny81n9tfSvUYfSHAZByXdjPAZVysvaB6sFd2YavqfqMBgbHaXUG5oWM6sYvdJn6vnUizzQKTYAJ36bQsfPv4N
+  ```
+  `bdk-cli key generate` will generate a fresh master key with `mnemonic` and `xprv`. We have extracted the value of extended private key and stored it in `BDK_xprv` variable.
+
+  The returned `mnemonic` can be used to restore back the wallet if wallet data directory is lost.
+
+- #### Generate Descriptors
+       `bdk-cli key derive` can derive an `xpub`s given a `master key` and `derivation_path`.
+
+  We will use the following paths for our `receive` and `change` descriptors
+
+       - `receive` path: `m/84h/1h/0h/0`
+       - `change` path: `m/84h/1h/0h/1`,
+
+       We can then simply wrap them in a `"wpkh()"` to create our descriptors string and store them.
+
+  When asked for a new address, BDK will derive one from the `receive` descriptor.
+
+  And while constructing transaction, BDK will use the `change` descriptor to derive change address.
+
+       ```shell
+  $ BDK_recv_desc="wpkh($(bdk-cli key derive --path m/84h/1h/0h/0 --xprv $BDK_xprv | jq -r '.xprv'))"
+  $ echo $BDK_recv_desc
+  wpkh([ff09c7c9/84'/1'/0'/0]tprv8hkdEGgwLLnqsdfkJFidpTj5d6z5qFdP6Qwzsviea3HrS9C2mXXaDivPKCCgcaWvnGNX9eciLUQs91PWYXJqrChfnAagViCgG6L5phaNyWr/*)
+  ```
+  ```shell
+  $ BDK_chng_desc="wpkh($(bdk-cli key derive --path m/84h/1h/0h/1 --xprv $BDK_xprv | jq -r '.xprv'))"
+  $ echo $BDK_chng_desc
+  wpkh([ff09c7c9/84'/1'/0'/1]tprv8hkdEGgwLLnqtbYkGG7fSy7v43RF2SQGGjNuZtmBzEHh7H8xgpXBETQAbVPqi8rkvLNFKLYY4rDzXA4fn5Ha1yuazZqhQPe3uNKmFS7648s/*)
+  ```
+  Note: `BDK_xprv` has been used as the `master key`, this will allow BDK to have signing capabilities.
+  We could have used an `xpub` master key here instead, that would create an `watch-only` wallet.
+
+- #### Create and Sync a wallet
+  We will now instruct BDK to create a new wallet with following instructions
+
+       ```shell
+  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sync
+  {}
+  ```
+    - name (`--wallet`) `bdk-test`,
+    - `receive` descriptor (`-d`) as `$BDK_recv_desc` and change descriptor (`-c`) as `$BDK_chng_desc`,
+    - connected to a full node (`--node`) listening at `127.0.0.1:18444`,
+    - and finally create and sync the wallet with the `sync` command.
+
+  If you are using a `regtest` node, also add `--network regtest`, the default is `testnet`.
+
+  `bdk-cli` makes multiple parallel connections that can be configured with the `--conn-count` parameter (default is 4). This makes syncing parallel and fast. Use `bdk-cli --help` to see all other options.
+
+  Getting an empty return means wallet creation succeeded.
+
+  BDK has created a wallet named `bdk-test` in its data directory. Which is by default stored at `~/.bdk-bitcoin/compact_filters` folder.
+
+  Looking into that folder different files and directories maintained by BDK can be seen.
+  ```shell
+  $ ls .bdk-bitcoin/compact_filters/
+  000004.log  CURRENT   LOCK  MANIFEST-000003  OPTIONS-000010
+  bdk-test    IDENTITY  LOG   OPTIONS-000008
+  ```
+### Recieve Coins
+
+We will use the `core` wallet to send 5 BTC to our`bdk-test` wallet.
+
+- Fetch a new address using `bdk-cli`
+  ```shell
+  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc get_new_address
+  {
+    "address": "bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9"
+  }
+  ```
+
+- Transfer funds to the previous address and generate a block, using `bitcoin-cli`
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest sendtoaddress bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9 5
+
+
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest generatetoaddress 1 bcrt1qw3ht9xtc9pgyvmqay0ap9fw8mxd27az8el0uz3
+  ```
+
+  `core` has sent 5 BTC to our `bdk-test` wallet. Which is confirmed in a new block.
+
+  `bdk-test` can see that now by syncing again.
+
+  (Note: BDK required explicit `sync()` calls to give wallet developers flexibility on when to sync).
+  ```shell
+  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sync
+  {}
+
+  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc get_balance
+  {
+    "satoshi": 500000000
+  }
+  ```
+
+  We can see `500000000` sats balance in our `bdk-test` wallet.
+
+  BDK has fetched blockchain details concerning its wallet descriptors, from the core node, using compact filters.
+
+### Creating a transaction.
+  Now we want to create a transaction sending coins from `bdk-test` wallet to the `core` wallet.
+
+- fetch a new `core` address
+  ```shell
+  $ core_addrs=$(docker exec -it bdk-box /root/bitcoin-cli -regtest getnewaddress | tr -d '\r')
+  ```
+
+- Create a raw transaction using `bdk-cli` to the above address. This will generate a `psbt` which we will sign.
+  ```shell
+  $ psbt=$(bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc create_tx --to $core_addrs:200000000 | jq -r '.psbt')
+  ```
+  (Recommended to check all the other information returned by `bdk-cli create_tx`)
+
+### Sign and Broadcast the transaction
+Asking BDK to sign a transaction is as straight forward as it can get. BDK already holds the `xprv` deatils to sign a transaction. It returns a finalised `signed_psbt` which we will next broadcast to the network.
+
+- Sign the transaction
+  ```shell
+  $ signed_psbt=$(bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sign --psbt $psbt | jq -r '.psbt')
+  ```
+
+- Broadcast the transaction
+  ```shell
+  $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc broadcast --psbt $signed_psbt
+  {
+    "txid": "c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252"
+  }
+  ```
+  This makes BDK broadcast the transaction via the connected core node, and it returns the corresponding Txid.
+
+### Confirming the Transaction
+ The transaction has been received by the `core` node and waiting in its mempool for inclusion in block.
+ We can see the transaction via its `txid` received in previous step.
+
+- Check transaction in mempool
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest gettransaction c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e2248e52e0852252
+  {
+    "amount": 2.00000000,
+    "confirmations": 0,
+    "trusted": false,
+    "txid": "c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252",
+    "walletconflicts": [
+    ],
+    "time": 1621697202,
+    "timereceived": 1621697202,
+    "bip125-replaceable": "no",
+    "details": [
+      {
+        "address": "bcrt1q3h4hs6mve5dcl7da3d4acmlp20hh8c3t4mldwe",
+        "category": "receive",
+        "amount": 2.00000000,
+        "label": "",
+        "vout": 1
+      }
+    ],
+    "hex": "01000000000101d84e8cb7477f9fe6f265b56d5416ff47da9a70be18f65ec50731b8257c67f2bd0100000000ffffffff0273a2e11100000000160014874270187001febc4cebd8cb083cf2c783e8f1ac00c2eb0b000000001600148deb786b6ccd1b8ff9bd8b6bdc6fe153ef73e22b0247304402201037d9ef5b80392296311c8899b1f12a0987778d694a442a88bafa6fbd7a7c9a022011293176255897444d9c71b0b9cd13b2aedb749b142577566c90a63d61025e2c01210202427d16b29c1c8546255363a74326ee9ab3196770bb3fccc7b679d52f9c1ccf00000000"
+  }
+  ```
+  This means, core has recieved the transaction in its mempool and waiting for confirmation.
+
+- Generate 1 block to confirm the transaction
+  ```shell
+  $ docker exec -it bdk-box /root/bitcoin-cli -regtest generatetoaddress 1 bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2
+  [
+    "55436ff0169bbb3e70ab10cb7cdd45ab86204d5d7864a109142d91120d023197"
+  ]
+  ```
+
+- Sync the `bdk-test` wallet and ask for available balance.
+  ```shell
+       $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc sync
+       {}
+
+       $ bdk-cli --network regtest wallet --node "127.0.0.1:18444" --wallet bdk-test -d $BDK_recv_desc -c $BDK_chng_desc get_balance
+       {
+               "satoshi": 299999859
+       }
+  ```
+
+       If you see the balance updated, voila!
+
+  What happened here is:
+  - core created a new block containing the transaction.
+  - `bdk-cli` fetched the corresponding filter data.
+  - It noticed it got a concerning transaction.
+  - It asked for the details of that transaction from the core node.
+  - It updated its wallet details with this new information.
+  - The update is reflected in the wallet balance.
+
+### Shutdown Docker ###
+
+You may now shutdown the regtest docker container.
+
+Note: This will also clean up any data in the bitcoin core, including the wallet.
+
+```shell
+$ docker kill bdk-box
+```
+
+## End Words
+
+In this tutorial we went through the process of receiving, creating, signing and broadcasting transaction using the BDK wallet with `compact_filters` feature. This demonstrates how BDK capabilities can be used to create SPV light wallets with integrated `BIP157` type `compact_filters` node.
diff --git a/docs/tutorials/descriptor_based_paper_wallet.md b/docs/tutorials/descriptor_based_paper_wallet.md
new file mode 100644 (file)
index 0000000..7157600
--- /dev/null
@@ -0,0 +1,190 @@
+---
+title: "Making Descriptor-based paper wallets"
+description: "Demonstrate how to create descriptor-based paper wallet and how to spend them with bdk"
+authors:
+    - Riccardo Casatta
+    - Steve Myers
+date: "2021-03-30"
+tags: ["guide", "descriptor", "paper wallets"]
+permalink: "/blog/2021/03/descriptor-based-paper-wallets/"
+---
+
+In this post, we will use the [Rusty Paper Wallet] tool to create a multi-owned descriptor-based paper wallet. We will use [bdk] via the [bdk-cli] tool to test our descriptor and to be able to sweep the funds from our paper wallet to a new address.
+
+## About paper wallets
+
+Paper wallets have a lot of drawbacks, as explained in the [paper wallet Wiki article], as always, do your own research before deciding to use it with mainnet bitcoins. In this post we will
+only be using testnet coins.
+
+## Descriptors
+
+The [previous version] of the [Rusty Paper Wallet] followed the original paper wallet design: WIF[^WIF] as secret part with the option to generate a different kind of addresses (legacy, nested segwit, and segwit).
+
+There were plans to [support mnemonic](https://github.com/RCasatta/rusty-paper-wallet/issues/5) instead of WIF keys because it may[^WIFcore] save the sweep transaction[^sweep] and there are more wallets capable of importing a mnemonic instead of a WIF.
+
+However, choosing a single address type or having wallet support for a specific format is the kind of problem [descriptors] solve perfectly, so the latest [Rusty Paper Wallet] version now accepts a descriptor and the network as parameters.
+
+## Example use case
+
+So let's say your grandma wants to buy bitcoin and asked for your help.
+
+You are a little afraid she may lose the private key. At the same time, you don't want to duplicate the keys and give those to her daughters Alice and Barbara, because both of them could spend and accuse the other of having done so.
+
+Even though we trust everyone in the family it is better to play it safe and divide the responsibility of protecting Grandma's bitcoin.
+
+This is a perfect case for a 2 of 3 multi-signature paper wallet. This way also protects the participants from having their copy of the wallet stolen. To compromise Grandma's wallet a thief would need to find and steal at least two of them.
+
+Note that you as the wallet creator are still the single point of trust because you are going to generate the keys for everyone. Setups combining self generated keys from the participants is possible future work.
+
+## Creating the paper wallet
+
+For this example the spending descriptor would be:
+
+`wsh(multi(2,Grandma,Alice,Barbara))`
+
+You need [rust] installed to use [Rusty Paper Wallet]. The -n option below explicitly selects
+generating `testnet` keys. Use `rusty-paper-wallet --help` to see usage instructions and other
+options.
+
+```shell
+$ cargo install rusty-paper-wallet
+$ rusty-paper-wallet "wsh(multi(2,Grandma,Alice,Barbara))" -n testnet
+data:text/html;base64,PCFET0N...
+```
+
+The [output] of the command is very long and has been shortened. The string is a [data URI scheme] paste-able in the address bar of a browser. By using a data URI no files are written on the hard disk, leaving less trace of secret material on the computer.
+It's also a good idea to use incognito mode in the browser to prevent it from saving the page in the history.
+
+The following is the result:
+
+<iframe src="/descriptor-based-paper-wallets/Bitcoin_Paper_Wallet.html" class="example"></iframe>
+
+Under the hood, the command created a key pair randomly for every alias present in the descriptor, then replaced the aliases with the created keys and generated the corresponding address. This address is the same for every paper wallet and it is shown in the upper part of the paper wallet (the public part) along with the alias, linking the paper wallet to the owner.
+
+The lower part is the secret part, the written part is the descriptor with the aliases, followed by a legend linking the aliases with the keys. In the legend, all the keys are public but the one of the owner which is a private WIF. The secret QR code instead contains the descriptor already with the keys.
+
+The paper wallet must then be printed, and it is better to use a printer without wifi and also to be aware that some sensitive data may remain in the printer's cache.
+
+Then the paper wallet must be cut along the dotted lines, the secret part should be folded twice over the black zone[^blackzone]. The black zone helps to avoid showing the secret parts in the presence of back-light. Once the folding is done the paper wallet should be plasticized to prevent being damaged by water.
+
+## BDK
+
+Any descriptor based wallet can be used to check the balance of and sweep the funds from
+Grandma's paper wallet. For this post we'll demonstrate using the [bdk-cli] tool to do these steps.
+Another area where [bdk] could be used with [Rusty Paper Wallet] is to compile a more
+complicated miniscript spending policy into a descriptor, as we have done in the [spending policy demo] post.
+
+## Funding tx
+
+Since Grandma's wallet was created as a `wsh` descriptor, bitcoin can be sent to it from any
+segwit capable wallet, we'll use a public [bitcoin testnet faucet]. Once the funds are sent the
+deposit address `tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw` we can also use this
+address and a testnet explorer to [confirm the funds were received].
+
+## Sweep tx
+
+Now that Grandma's paper wallet is funded it's time to demonstrate how to use [bdk-cli] to sweep these
+funds to a new address. Let's assume Grandma lost her original paper wallet and has asked
+her daughters to sweep them to a new single signature wallet so she can spend them.
+
+### Step 1: Alice creates and signs a PSBT
+
+Alice uses the private text or QR code from her paper wallet to find her private key and the
+public keys for Grandma and Barbara. With this info she creates a PSBT to sweep Grandma's funds
+to a new address (in this example we'll send them back to our [bitcoin testnet faucet]). Notice how Alice
+includes her wallet's descriptor checksum '#em3q73l5', this [guarantees] she has entered her descriptor correctly.
+
+```shell
+$ SWEEP_TO_ADDR=tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2
+
+$ ALICE_WIF=cSSKRHDmQEEutp5LD14tAcixu2ehSNPDTqNek1zMa9Pet98qxHq3
+$ BARBARA_PUBKEY=02a3f3f2658b9812ddeabfbde2fde03f8a65369e4ed621f29fa8ba0cc519b789fb
+$ GRANDMA_PUBKEY=03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee
+$ ALICE_DESCRIPTOR="wsh(multi(2,$GRANDMA_PUBKEY,$ALICE_WIF,$BARBARA_PUBKEY))#em3q73l5"
+
+# confirm descriptor creates the expected deposit address
+$ bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_new_address
+{
+  "address": "tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"
+}
+
+# sync the wallet and show the balance
+$ bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
+{}
+
+$ bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
+{
+  "satoshi": 10000
+}
+
+# create and sign PSBT
+$ UNSIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx --send_all --to $SWEEP_TO_ADDR:0 | jq -r ".psbt")
+
+$ ALICE_SIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sign --psbt $UNSIGNED_PSBT | jq -r ".psbt")
+```
+
+### Step 2: Barbara signs Alice's signed PSBT and broadcasts the tx
+
+Now it's Barbara's turn to use the private text or QR code from her paper wallet to get her private
+key and the public keys for Grandma and Alice. With this info plus Alice's signed PSBT she can
+create a fully signed PSBT to broadcast and complete the sweep of Grandma's funds.
+
+```shell
+$ ALICE_PUBKEY=02e486e32f0f87136fa042cb53219ace8537ea1d036deb2f4293570b94325d11cb
+$ BARBARA_WIF=cSfMLzSZ9NjWUTqL3sFpgWJssnu2qgmE2cm5N1jPDRRJuDcrsPEB
+$ GRANDMA_PUBKEY=03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee
+$ BARBARA_DESCRIPTOR="wsh(multi(2,$GRANDMA_PUBKEY,$ALICE_PUBKEY,$BARBARA_WIF))#nxfa5n0z"
+
+# confirm descriptor creates the expected deposit address
+$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR get_new_address
+{
+  "address": "tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"
+}
+
+# sync the wallet and show the balance
+$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR sync
+{}
+
+$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR get_balance
+{
+  "satoshi": 10000
+}
+
+$ FINAL_PSBT=$(bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR sign --psbt $ALICE_SIGNED_PSBT | jq -r ".psbt")
+
+$ bdk-cli wallet -w barbara -d $BARBARA_DESCRIPTOR broadcast --psbt $FINAL_PSBT
+{
+  "txid": "9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59"
+}
+```
+
+And finally we verify that Alice and Barbara successfully created and broadcast Grandma's [sweep tx].
+
+## Conclusion
+
+In this post we showed how to create a multi-sig descriptor based paper wallet using
+[Rusty Paper Wallet] and then sweep the funds from our example paper wallet to a new address. If you
+found this post interesting please comment below. Or give it a try yourself and if you run into any
+problems or would like to suggest improvements leave an issue in the [Rusty Paper Wallet] or
+[bdk-cli] github repos. Thanks!
+
+[paper wallet wiki article]: https://en.bitcoin.it/wiki/Paper_wallet
+[previous version]: https://github.com/RCasatta/rusty-paper-wallet/tree/339fa4418d94f6fdd96f3d0301cab8a0bc09e8bd
+[Rusty Paper Wallet]: https://github.com/RCasatta/rusty-paper-wallet
+[support mnemonic]: https://github.com/RCasatta/rusty-paper-wallet/issues/5
+[descriptors]: /descriptors
+[bdk]: https://github.com/bitcoindevkit/bdk
+[rust]: https://www.rust-lang.org/tools/install
+[output]: /descriptor-based-paper-wallets/data-url.txt
+[data URI scheme]: https://en.wikipedia.org/wiki/Data_URI_scheme
+[bdk-cli]: https://github.com/bitcoindevkit/bdk-cli
+[bitcoin testnet faucet]: https://bitcoinfaucet.uo1.net/
+[confirm the funds were received]: https://mempool.space/testnet/address/tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw
+[sweep tx]: https://mempool.space/testnet/tx/9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59
+[spending policy demo]: /blog/2021/02/spending-policy-demo/#step-4-create-wallet-descriptors-for-each-participant
+[guarantees]: https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
+
+[^WIF]: Wallet Input Format, a string encoding a ECDSA private key  https://en.bitcoin.it/wiki/Wallet_import_format
+[^WIFcore]: Unless the user import the WIF directly into bitcoin core
+[^sweep]: Some wallets refers to sweep as the action to create a transaction taking all the funds from the paper wallet and sending those to the wallet itself.
+[^blackzone]: Ideally, the black zone should be twice as long as the secret part to cover it back and front, long descriptor may leave a shorter black zone, ensure to have you printer set with vertical layout for best results.
diff --git a/docs/tutorials/descriptors_in_the_wild.md b/docs/tutorials/descriptors_in_the_wild.md
new file mode 100644 (file)
index 0000000..74634e7
--- /dev/null
@@ -0,0 +1,344 @@
+---
+title: "Descriptors in the wild"
+description: "Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK"
+authors:
+    - Gabriele Domenichini
+date: "2020-11-18"
+tags: ["guide", "descriptor"]
+permalink: "/blog/2020/11/descriptors-in-the-wild/"
+---
+
+I have tried to setup a 2 of 2 multi signature infrastructure with two
+different wallets, which know nothing about each other, but are compliant with
+two very important protocols: [Output Descriptors] and [Partially Signed
+Bitcoin Transactions][PSBT] described in BIP 174.
+
+Before these two protocols came into existence, making a multi signature setup
+and spending from it was possible only if the involved parties were using the
+same wallet (eg. Electrum Desktop Wallet). This limitation was due to the fact
+that the two parties had to agree:
+
+* on the particular type of script and address to use
+* on the way the transaction would be shared composed and signed with all the
+involved parties.
+
+[Output Descriptors] are a way to express which kind scriptPubKey and
+addresses to produce with a key or a series of keys.
+
+[PSBT] is instead the standard protocol used to create a transaction and to enrich
+it with the necessary signatures and other components, to make it valid and complete.
+
+Together they provide a common ground to create and use a multi signature
+infrastructure in a heterogeneous environment, and this is what I have put
+to test.
+
+## The use case
+
+Imagine Alice and Bob owning a company and being willing to put the corporate cash
+in a 2of2 multi signature setup, so that each one of them have to agree and sign each
+transaction.
+
+## The role of Descriptors
+
+If Alice and Bob cannot agree on the software to use, to monitor the same financial
+situation, the two software must control and produce exactly the same series
+of multisignature addresses.
+
+To make two different software produce the same addresses in a deterministic way
+we must ensure that they:
+* produce the same pair of public keys
+* combine them in the same order
+* put them inside the same scriptPubKey to produce the same address
+
+Here is where the [Output Descriptors] come into play. They describe:
+
+* the sequence of public keys each extended key (xpub) will produce
+* the sequence in which the new public keys of various parties will enter into
+the script
+* the type of script the wallet will prepare with that group keys and so the type
+of address the group of keys will produce.
+
+**By sharing the same Descriptor, every compliant wallet will derive
+deterministically the same series of multisig addresses**.
+
+Imagine Alice using Bitcoin Core (from now on ["Core"][Bitcoin Core]) as a
+Wallet and Bob using a "Last generation" wallet, Bitcoin Development Kit
+(from now on ["BDK"][BDK]), which uses descriptors and miniscript natively.
+
+Each of these two software wallets should be able to:
+
+* Create a new address which is seen as belonging to the multi signature
+wallet in both software
+* Express the consent of each party by partially signing the transaction in a way
+the other wallet can understand and complete it with its own signature.
+
+The infrastructure of multiple Extended keys combined toghether to produce
+multiple multisignature addresses is often referred as
+*[Hierarchical Deterministic][HDWallet] multi signature wallet or HDM*.
+
+What follows are the steps to create the HDM usable both in Core and
+in BDK.
+
+*Note: In Core, [Descriptor wallets] are still experimental and in general,
+both wallets should be tested for descriptor capabilities only in testnet.*
+
+## Our playground
+
+We will build a 2of2 key set up that will be used cooperatively by Bitcoin Core
+and Bitcoin Development Kit.
+The steps Alice and Bob will do are:
+
+1. creation of the seed and the derived Extended Master Public and send it to
+the other party
+2. Create the multi signature descriptor for each wallet
+3. Use each other's software to receive testnet coins from a faucet
+4. return part of the coins to the faucet signing the transaction with both
+wallets.
+
+We need:
+* [Bitcoin Dev Kit][BDK]
+* [Bitcoin Core] (v0.21.0 or later)
+
+### 1. Creating the seeds and the derived Extended Public keys
+
+#### Seeds and Extended Master Public
+
+We build an Extended Private Master Key for both wallet and derive a BIP84
+Extended Master Public for Bitcoin Core and then for BDK.
+
+For Bitcoin Core (Alice):
+
+```
+# new Extended wallet data
+export core_key=$(bdk-cli key generate)
+
+# New Extended Master Private
+
+export core_xprv=$(echo $core_key | jq -r '.xprv')
+
+# Now I derive the xpubs (one for receiving and one for the change)
+# together with informations about the derivation path to be communicated
+# to BDK wallet's owner (Bob).
+
+export core_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $core_xprv | jq -r '.xpub')
+export core_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $core_xprv | jq -r '.xpub')
+```
+
+For BDK (Bob) we do the same:
+
+```
+# new Extended wallet data
+
+export BDK_key=$(bdk-cli key generate)
+
+# New Extended Master Private
+
+export BDK_xprv=$(echo $BDK_key | jq -r '.xprv')
+
+# Now I build the derived xpubs to be communicated (to Alice).
+
+export BDK_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $BDK_xprv | jq -r '.xpub')
+export BDK_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $BDK_xprv | jq -r '.xpub')
+```
+
+### 2. Creation of the multi signature descriptor for each wallet
+
+To build a multisig wallet, each wallet owner must compose the descriptor
+adding:
+* his derived extended **private** key AND
+* all the extended **public** keys of the other wallets involved in the
+multi signature setup
+
+*The different nature of the two keys (one is private and one is public) is
+due to the fact that each wallet, to be able to partially sign the transaction,
+**must manage the private key of the wallet's owner*** AND have the other
+party's public key. Otherwise, if we put both public keys, we would obtain
+a watch-only wallet unable to sign the transactions. If we
+had both extended private keys inside the descriptor, we would allow each party
+to finalize the transactions autonomously.
+
+#### In Bitcoin Core:
+
+In our case, the multi signature descriptor for Bitcoin Core will be composed
+with:
+
+* The BIP84 derived Extended **Public** Key from BDK
+* The BIP84 derived Extended **Private** Key from Core.
+
+BDK wallet's owner will send to Core's owner the derived xpub for this purpose.
+This is how the Core's multisig descriptor will be created and put into an
+environment variable:
+
+```
+export core_rec_desc="wsh(multi(2,$BDK_xpub_84_for_rec_desc,$core_xprv/84'/0'/0'/0/*))"
+```
+
+Where of course `$BDK_xpub_84_for_rec_desc`is the derived master public created
+in BDK and received by Core's owner.
+
+The meaning of what is before and after is illustrated in the doc that explain
+the use of [Output Descriptors in Bitcoin Core][Output Descriptors].
+
+We add the necessary checksum using the specific `bitcoin-cli` call.
+
+```
+export core_rec_desc_chksum=$core_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_rec_desc | jq -r '.checksum')
+```
+
+We repeat the same to build the descriptor to receive the change.
+
+```
+export core_chg_desc="wsh(multi(2,$BDK_xpub_84_for_chg_desc,$core_xprv/84'/0'/0'/1/*))"
+export core_chg_desc_chksum=$core_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_chg_desc|jq -r '.checksum')
+```
+
+#### In BDK:
+
+For BDK we set the derivation for receiving addresses and change addresses
+in the command line (maybe setting an alias)
+
+Building the descriptor:
+
+```
+export BDK_rec_desc="wsh(multi(2,$BDK_xprv/84'/0'/0'/0/*,$core_xpub_84_for_rec_desc))"`
+```
+
+Please note that the order of the extended key in the descriptor MUST be the
+same in the 2 wallets.
+
+*We have chosen to put BDK first and in each software wallet, the public key
+derived from BDK will always come first. In alternative, we could have chosen to
+produce the descriptor, [chosing a `soretedmulti` multisignature setup][sortedmulti]*.
+
+```
+export BDK_rec_desc_chksum=$BDK_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_rec_desc | jq -r '.checksum')
+export BDK_chg_desc="wsh(multi(2,$BDK_xprv/84'/0'/0'/1/*,$core_xpub_84_for_chg_desc))"
+export BDK_chg_desc_chksum=$BDK_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_chg_desc | jq -r '.checksum')
+```
+
+To take a look at the variables we have produced so far:
+```
+env  | grep 'core_'
+env  | grep 'BDK_'
+```
+
+Now we will use the multisig descriptor wallet to receive testnet coins with
+Alice and Bob's software
+
+### 3. Use each other's software to receive testnet coins from a faucet
+
+#### In Bitcoin Core
+
+Alice must create an empty, experimental new "descriptors wallet" in Core and
+to import the multisig Output Descriptor.
+
+```
+bitcoin-cli -testnet createwallet "multisig2of2withBDK" false true "" false true false
+````
+The flag are to:
+* use the private keys
+* make it empty
+* no password provided to the wallet
+* reusing of addresses not allowed
+* "new experimental descriptors wallet"
+*  don't load it on start up
+
+```
+bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK importdescriptors "[{\"desc\":\"$core_rec_desc_chksum\",\"timestamp\":\"now\",\"active\":true,\"internal\":false},{\"desc\":\"$core_chg_desc_chksum\",\"timestamp\":\"now\",\"active\":true,\"internal\":true}]"
+```
+Now Alice asks for her first receiving multisignature address.
+
+```
+export first_address=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getnewaddress)
+echo $first_address
+```
+
+#### BDK
+In BDK Bob can specify directly the descriptors on the command line to produce
+the multisig address, because BDK is descriptors aware natively.
+
+```
+repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_new_address`
+```
+
+Et voilà: if we have done everything correctly, the newly created address in
+Core is the same of the newly created address in BDK. this is part of the
+"miracle" of descriptors' interoperability.
+
+#### We ask for testnet coins giving the first created address.
+
+To find testnet coins for free, you can just google "testnet faucet" and you
+should find some satoshis to play with. Just give to the site your first
+generated address and, in twenty minutes, you will find the satoshis in
+your balance both in Core and in BDK.
+
+```
+# to check it in Core:
+
+bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getbalance
+
+# In BDK:
+
+# Sync with the blockchain
+repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sync
+# Get the balance
+repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_balance
+```
+Some testnet faucets have an address to send back the unused satoshi after
+the use. Take note of that because we will use it in the next step.
+
+### 4. we return part of the satoshis received back to the faucet
+
+```
+export psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletcreatefundedpsbt "[]" "[{\"tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a\":0.000012}]" | jq -r '.psbt')
+
+export psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletprocesspsbt $psbt | jq -r '.psbt')
+{
+  "psbt": "cHNidP8BAIkCAAAAATj90EC+NAuXj7y6SseZJucoJM6sGnUcVm9koTveZECTAAAAAAD+////AmACAAAAAAAAIgAg98ol9j4AalD71E0mV5QV0uM6/vCT+pi2twxr/zrvLROwBAAAAAAAACIAIB4zBMipU3xqvNDQlz+PCDXvpkHH1Q95Nu0mgIsnU0jbAAAAAAABAIkCAAAAAQS+ObgGG6UwtvaO3KYph2E3/ws7Q83RbmR3rxC0fKYSAQAAAAD+////AtAHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNDAHQAAAAAAACIAIBQpiDTgPIMt0ld8cmuYqlY+EIPjvrmMqZruDhs61hQNAAAAAAEBK9AHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNAiAgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAAQEFR1IhArn3tec7n7318rnWqf0dIIwtLtfxo6Zt0HV70UvZYaWvIQNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfVKuIgYCufe15zufvfXyudap/R0gjC0u1/Gjpm3QdXvRS9lhpa8YNEw2cFQAAIAAAACAAAAAgAAAAAAAAAAAIgYDbdI+wHtIgO6pS6Ja7jai1pDwPeidKoDCytTO1jhjAH0YO/laXFQAAIAAAACAAAAAgAAAAAAAAAAAAAEBR1IhAqccvA3rL13D1K4GeWjcahDsO3P8oaVNBttk4MlCKXIcIQLHKhjmPuCQjyS77ZfaMN2tdgNKcf/+57VXGZhz/UWTl1KuIgICpxy8DesvXcPUrgZ5aNxqEOw7c/yhpU0G22TgyUIpchwYNEw2cFQAAIAAAACAAAAAgAEAAAADAAAAIgICxyoY5j7gkI8ku+2X2jDdrXYDSnH//ue1VxmYc/1Fk5cYO/laXFQAAIAAAACAAAAAgAEAAAADAAAAAAA=",
+  "complete": false
+}
+```
+
+Exactly! Note the `"complete": false`. We have processed the transaction with
+Core but we miss one of the necessary key of the multisig 2of2 setup (The one
+contained inside BDK).
+
+`tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a` is the address
+we got from the faucet site to return the satoshis.
+
+The [PSBT] is sent over to the BDK wallet owner who tries to sign the
+transaction:
+
+```
+repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sign --psbt $psbt
+{
+  "is_finalized": true,
+  "psbt": "cHNidP8BAIkCAAAAATj90EC+NAuXj7y6SseZJucoJM6sGnUcVm9koTveZECTAAAAAAD+////AmACAAAAAAAAIgAg98ol9j4AalD71E0mV5QV0uM6/vCT+pi2twxr/zrvLROwBAAAAAAAACIAIB4zBMipU3xqvNDQlz+PCDXvpkHH1Q95Nu0mgIsnU0jbAAAAAAABAIkCAAAAAQS+ObgGG6UwtvaO3KYph2E3/ws7Q83RbmR3rxC0fKYSAQAAAAD+////AtAHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNDAHQAAAAAAACIAIBQpiDTgPIMt0ld8cmuYqlY+EIPjvrmMqZruDhs61hQNAAAAAAEBK9AHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNAiAgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAASICArn3tec7n7318rnWqf0dIIwtLtfxo6Zt0HV70UvZYaWvRzBEAiBkVDLgVEwvENnLx+04o7gGpGjFDBwAXTJmf8Yvo35oygIgbuBkHsvPC9jmZcMZ9P+Pwp01yxSaWo+5feyPmd3ai1kBAQVHUiECufe15zufvfXyudap/R0gjC0u1/Gjpm3QdXvRS9lhpa8hA23SPsB7SIDuqUuiWu42otaQ8D3onSqAwsrUztY4YwB9Uq4iBgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfRg7+VpcVAAAgAAAAIAAAACAAAAAAAAAAAAiBgK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlrxg0TDZwVAAAgAAAAIAAAACAAAAAAAAAAAABBwABCNoEAEcwRAIgZFQy4FRMLxDZy8ftOKO4BqRoxQwcAF0yZn/GL6N+aMoCIG7gZB7LzwvY5mXDGfT/j8KdNcsUmlqPuX3sj5nd2otZAUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAAUdSIQK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlryEDbdI+wHtIgO6pS6Ja7jai1pDwPeidKoDCytTO1jhjAH1SrgABAUdSIQKnHLwN6y9dw9SuBnlo3GoQ7Dtz/KGlTQbbZODJQilyHCECxyoY5j7gkI8ku+2X2jDdrXYDSnH//ue1VxmYc/1Fk5dSriICAqccvA3rL13D1K4GeWjcahDsO3P8oaVNBttk4MlCKXIcGDRMNnBUAACAAAAAgAAAAIABAAAAAwAAACICAscqGOY+4JCPJLvtl9ow3a12A0px//7ntVcZmHP9RZOXGDv5WlxUAACAAAAAgAAAAIABAAAAAwAAAAAA"
+}
+```
+The signature has succeded (note the "is_finalized": true,) and now we can
+broadcast the transction.
+```
+repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint broadcast --psbt "cHNidP8BAIkCAAAAATj90EC+NAuXj7y6SseZJucoJM6sGnUcVm9koTveZECTAAAAAAD+////AmACAAAAAAAAIgAg98ol9j4AalD71E0mV5QV0uM6/vCT+pi2twxr/zrvLROwBAAAAAAAACIAIB4zBMipU3xqvNDQlz+PCDXvpkHH1Q95Nu0mgIsnU0jbAAAAAAABAIkCAAAAAQS+ObgGG6UwtvaO3KYph2E3/ws7Q83RbmR3rxC0fKYSAQAAAAD+////AtAHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNDAHQAAAAAAACIAIBQpiDTgPIMt0ld8cmuYqlY+EIPjvrmMqZruDhs61hQNAAAAAAEBK9AHAAAAAAAAIgAg6GXadcNj7k4yKUbnVlTLiedXQFXYdCBoNygop/PISNAiAgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAASICArn3tec7n7318rnWqf0dIIwtLtfxo6Zt0HV70UvZYaWvRzBEAiBkVDLgVEwvENnLx+04o7gGpGjFDBwAXTJmf8Yvo35oygIgbuBkHsvPC9jmZcMZ9P+Pwp01yxSaWo+5feyPmd3ai1kBAQVHUiECufe15zufvfXyudap/R0gjC0u1/Gjpm3QdXvRS9lhpa8hA23SPsB7SIDuqUuiWu42otaQ8D3onSqAwsrUztY4YwB9Uq4iBgNt0j7Ae0iA7qlLolruNqLWkPA96J0qgMLK1M7WOGMAfRg7+VpcVAAAgAAAAIAAAACAAAAAAAAAAAAiBgK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlrxg0TDZwVAAAgAAAAIAAAACAAAAAAAAAAAABBwABCNoEAEcwRAIgZFQy4FRMLxDZy8ftOKO4BqRoxQwcAF0yZn/GL6N+aMoCIG7gZB7LzwvY5mXDGfT/j8KdNcsUmlqPuX3sj5nd2otZAUcwRAIgS6x0i1J1HRzllIPf4WlFY+Dl8kCCLK81TL2djZxTFXMCICJVBKkKNxu1w1mRVor6iFTSVXiJjmWwBXVeJLISvBwAAUdSIQK597XnO5+99fK51qn9HSCMLS7X8aOmbdB1e9FL2WGlryEDbdI+wHtIgO6pS6Ja7jai1pDwPeidKoDCytTO1jhjAH1SrgABAUdSIQKnHLwN6y9dw9SuBnlo3GoQ7Dtz/KGlTQbbZODJQilyHCECxyoY5j7gkI8ku+2X2jDdrXYDSnH//ue1VxmYc/1Fk5dSriICAqccvA3rL13D1K4GeWjcahDsO3P8oaVNBttk4MlCKXIcGDRMNnBUAACAAAAAgAAAAIABAAAAAwAAACICAscqGOY+4JCPJLvtl9ow3a12A0px//7ntVcZmHP9RZOXGDv5WlxUAACAAAAAgAAAAIABAAAAAwAAAAAA"
+{
+  "txid": "a0b082e3b0579822d4a0b0fa95a4c4662f6b128ffd43fdcfe53c37473ce85dee"
+}
+```
+
+## Conclusion
+
+We have built an HDM and we have used it with two indipendent wallets, which
+are compatible with [BIP 174][PSBT] and [Output Descriptors]. Hopefully we
+will see many other compatible wallets beyound [Bitcoin Core] and [BDK],
+with which we will be able to easily set up multi signature schemes.
+
+
+[Descriptor wallets]: https://github.com/bitcoin/bitcoin/pull/16528
+[Electrum]: https://electrum.org
+[Output Descriptors]: https://bitcoinops.org/en/topics/output-script-descriptors/
+[PSBT]: https://en.bitcoin.it/wiki/BIP_0174
+[HDWallet]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
+[sortedmulti]: https://github.com/bitcoin/bitcoin/pull/17056?ref=tokendaily
+[BDK]: https://bitcoindevkit.org/
+[Bitcoin Core]: https://bitcoincore.org/
+[pycoin]: https://github.com/richardkiss/pycoin
diff --git a/docs/tutorials/hidden-power-of-bitcoin.md b/docs/tutorials/hidden-power-of-bitcoin.md
new file mode 100644 (file)
index 0000000..0119e25
--- /dev/null
@@ -0,0 +1,582 @@
+---
+title: "Miniscript Policy & Descriptors - Hidden Powers of Bitcoin"
+description: "Introduction to Descriptor and Miniscript, making a Multisig Wallet and Testing Miniscript Policies"
+authors:
+    - Sandipan Dey
+    - Rajarshi Maitra
+date: "2022-01-02"
+tags: ["tutorial", "bdk", "bdk-cli", "miniscript", "descriptor", "bitcoin-cli"]
+hidden: true
+draft: false
+---
+
+To send people BTC - we simply scan a QR Code *(or paste an address)*, enter some amount and *whoosh* - sent!
+Users might think, just like traditional currency, we can only exchange money using Bitcoin.
+As it so happens, the underlying technology Bitcoin supports specify outputs not as addresses, but as programming scripts.
+This opens us to a world of possibilities using Bitcoin.
+
+### Script
+
+Bitcoin supports [Script](https://en.bitcoin.it/wiki/Script), a **stack-based** lightweight programming language.
+Any script written in **Script** *(pun intended)* contains `OP_*` codes and raw byte arrays that Bitcoin Full Nodes understand and process.
+Currently, there are `117` op-codes in use.
+You can read more about these op-codes straight [here](https://en.bitcoin.it/wiki/Script).
+
+Script is intentionally left [Turing incomplete](https://en.wikipedia.org/wiki/Turing_completeness) which is why there is no [halting problem](https://en.wikipedia.org/wiki/Halting_problem) with scripts.
+There are no loops and overall, it's a very constrained programming language.
+
+A transaction is considered valid only when the Script returns `true` at the end of execution.
+Output Script (aka scriptpubkey) define the conditions under which coins associated with them can be spent. To spend a particular coin implies finding an input script (aka scriptsig) such that a script made out of concatenation of `scriptsig + scriptpubkey` evaluates to `true`.
+
+For example, a basic legacy `Pay-to-PubKey-Hash` transaction would look like:
+
+```script
+scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
+scriptSig: <sig> <pubKey>
+```
+
+##### Examples of things achievable using Bitcoin Script:
+
+1. `Pay Someone (p2pkh/p2wpkh)` - A specific public key must sign to spend the coins.
+2. `Escrow (2-of-3-multisig)` - Two parties need to sign together to spend the coins.
+3. `Vault (locked)` - A specific key will not be able to spend the coins until a timeout but another master key will always be able to spend them.
+4. `HTLC` - The receiver needs disclose a secret before a timeout, else the coins are transferred back to the payee.
+
+##### Motivation for Policies
+
+Unfortunately, due to its low-level and unusual stack-based nature, Script is pretty hard to reason about and use.
+Despite being around since Bitcoin's creation, writing and understanding Script is not trivial.
+This is why the scripts for the above few examples are pretty lengthy and might not make sense at the first glance.
+When writing a script, we would want to know that if the logic we wrote is **correct**, **optimal** and **efficient in size** (use lower [weight](https://en.bitcoin.it/wiki/Weight_units)).
+
+The community wanted an easy alternative way of writing Script that would create the most optimized Script code.
+This gave rise to **Miniscript**.
+
+### Miniscript
+
+[Miniscript](http://bitcoin.sipa.be/miniscript/) tackles the above problems head-on.
+It is an expressive way to create policies on Bitcoin Scripts in a structured and simple fashion.
+Using Miniscript, it's difficult to go wrong.
+
+Another very important goal of Miniscript is to replace any key used in a policy with another policy.
+This is important because people might have multiple keys and complicated timelocks in their existing setup.
+While signing a new policy, they would want to use their existing setup to also generate addresses for this new setup.
+This is accomplished using something called **Output Descriptors** which we will get into in next section.
+
+Miniscript compiler compiles a **spending policy** down to Miniscript.
+It doesn't contain any signature, it's mainly a combinator language for designing spending conditions.
+You can try out the compiler online by using [this link](http://bitcoin.sipa.be/miniscript/#:~:text=Policy%20to%20Miniscript%20compiler).
+
+##### Fragments
+
+Here are some fragments which can be combined to create powerful expressions.
+
+1. `pk(key)` - Specifies a given public key
+2. `thresh(k, expr_1, expr_2, ..., expr_n)` - Specifies k of n multisig using expressions.
+3. `older(T)` - Timelock for T blocks
+4. `and(expr_1, expr_2)` - Both expressions should evaluate to true. 
+5. `or(expr_1, expr_2)` - Any one of the expressions should evaluate to true.
+6. `aor(expr_1, expr_2)` - Similar to `or` but `expr_1` has a more probability to evaluate to true.
+
+Bitcoin Script allows us to use another alternate stack. The combinator functions use this second stack to evaluate expressions of `thresh`, `and`, `aor` and `or`.
+The complete Miniscript Reference can be found [here](http://bitcoin.sipa.be/miniscript/#:~:text=Miniscript%20reference).
+
+##### Example Policies
+
+Here are the Miniscript Policies for the examples we looked at earlier. 
+Note `A`, `B`, `C` are placeholders for keys *(`xpub`/`xprv`)* involved in the tx.
+Descriptors are high level description of scriptpubkey (p2pkh, p2sh etc). 
+And miniscripts are semantics that describes the actual redeemscript. 
+In general you have Descriptor(Miniscript) format.
+
+1. Pay A (pay-to-public-key)
+```
+pk(A)
+```
+
+2. Escrow Account between A, B and third-party C.
+```
+thresh(2,pk(A),pk(B),pk(C))
+```
+
+3. Vault for A time-locked for T blocks with B as the master key.
+```
+aor(and(pk(A),time(T)),pk(B))
+```
+
+4. HTLC payment to B, which, if unspent for T blocks, returns to A.
+```
+aor(and(pk(A),time(T)),and(pk(B),hash(H))))
+```
+
+The Miniscript Policy Compiler is written in Rust and is present in [this repository](https://github.com/rust-bitcoin/rust-miniscript). 
+In this blog, we will later use the same using [bitcoindevkit/bdk](https://github.com/bitcoindevkit/bdk), a lightweight descriptor-based wallet library
+with a [cli](https://github.com/bitcoindevkit/bdk-cli). 
+
+### Descriptors
+
+The Bitcoin scriptpubkey supports various schemes like P2PKH, P2SH, P2WPKH, P2TR (Segwit v1) etc.
+A Descriptor is a simple "description" of what scriptpubkey to be used for a given policy.
+It can inclue a single pubkey within itself, or an entire miniscript policy.
+On the other hand, Miniscript policies are used to derive the redeemscript (the actual executable script), whereas the descriptor describes how the redeemscript will be encumbered within the scriptpubkey.
+
+In other words, a descriptor "describes" the procedure to create an *address*, given a *spending condition*.
+
+They make it easier to deal with Multisig or complicated key setups.
+Descriptors are super portable and can be easily used by any wallet to determine the list of all addresses that can be generated from the same.
+This feature creates a common stage for all Bitcoin apps and software.
+
+The concept of descriptor came into existence in 2018 and since then, a lot of wallets have added support for descriptors.
+You can read the descriptor doc from `bitcoin-core` [here](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).
+
+According to Bitcoin Core, Output Descriptors are "a simple language which can be used to describe collections of output scripts".
+They bring in themselves, derivation paths, master xpub/xprv fingerprints and paths to generate addresses from.
+Let's understand this with an example of an Output Descriptor:
+
+```
+
+Descriptor: pkh([d34db33f/44'/0'/0']xpub6ERaJH[...]LJRcEL/1/*)#ml40v0wf
+            <1> <--------2---------><----------3---------><4> <---5--->
+
+Sections:
+1 - address type specifier (here, describing P2PK type addresses)
+2 - master key fingerprint and derivation path from master
+3 - xpub at m/44'/0'/0
+4 - path to deriving keys/addresses at
+5 - checksum for the descriptor
+```
+A descriptor have three parts:
+ - *address type specifier* (item 1) : describes the type of address created by this descriptor.
+ - *policy* : the spending condition that locks funds into this address.
+ - *checksum* : for quick verification.
+
+The address type specifiers currently supported are `pk`, `pkh`, `sh`, `wpkh`, `wsh` for corresponding address type and recently added `tr` for taproot addresses.
+
+There is a special address specifier called `combo` that creates addresses of all types from spending policy policy.
+
+After the address specifier, comes the *policy* that describes how the funds in the address can be spent. The descriptor
+above in the example has a simple spending policy of "spend by the correct private key". There can be more complicated policies,
+and we will touch them in later sections.
+
+`multi` is a special keyword that can be used as both *address type* and *policy*.
+When used as an *address type* like `multi(...)`, it will create an address from the raw multisig scriptpubkey.
+While when used as a *policy* like `wsh(multi(...))` it will create that specific address type from the multisig script.
+Of course we cannot use `pk(multi(...))`, `pkh(multi(...))` or `wpkh(multi(...))`, because these address types cannot hold scripts (any scripts) inside them.
+
+For example a descriptor like `wsh(multi(2, PKA, PKB, PKC))` describes a P2WSH type address created by a `2-of-3` multisig
+script using `PKA`, `PKB` and `PKC` pubkeys.
+
+### Where it all comes together...
+
+In this section, we are going to make a descriptor-based wallet and derive addresses from `bitcoin-cli` and then use `bdk-cli` to confirm that the addresses generated for descriptor wallets are deterministic for a given descriptor.
+
+We will also try to create a vault miniscript policy and push funds to the vault with a lock time of 2 months. 
+During this time, we will try to break our vault and see our transactions failing.
+
+##### Tools and Armor
+
+- [docker](https://docs.docker.com/engine/install/)
+- [bdk-cli](https://github.com/bitcoindevkit/bdk-cli)
+- [miniscriptc](https://bitcoindevkit.org/bdk-cli/compiler/#installation)
+
+##### Setting Up
+
+We require `bitcoind` to run in `regtest` mode. Use the following config file, or any other config
+that you are familiar with.
+
+```txt
+regtest=1
+fallbackfee=0.0001
+server=1
+
+rpcuser=user
+rpcpassword=password
+```
+
+```bash
+# Start Bitcoin Core
+bitcoind
+```
+
+#### Keys and Generating Addresses
+
+Quick installation for `bdk-cli` and `miniscriptc`:
+```bash
+cargo install bdk-cli --features=rpc,compiler
+cargo install bdk --features="compiler" --example miniscriptc
+```
+
+Let us first generate an XPRV and create the wpkh wallet descriptor
+```bash
+XPRV=$(bdk-cli key generate | jq -r '.xprv')
+EX_DESC="wpkh($XPRV/86'/1'/0'/0/*)"
+EX_DESC_CS=$(elcli getdescriptorinfo $EX_DESC | jq -r '.checksum')
+EX_DESC=$EX_DESC#$EX_DESC_CS
+
+# Set this descriptor in a wallet in bitcoin-cli
+bitcoin-cli -named createwallet wallet_name="mywallet" descriptors=true
+bitcoin-cli -rpcwallet="mywallet" importdescriptors "[{\"desc\":\"$EX_DESC\", \"timestamp\":\"now\", \"active\": true, \"range\": [0,100]}]"
+
+echo $EX_DESC
+```
+
+It should look something like this:
+```
+wpkh(tprv8ZgxMBicQKsPeuazF16EdPZw84eHj55AU8ZKgZgdhu3sXcHnFgjzskfDvZdTaAFHYNCbKqrurFo9onSaT7zGT1i3u3j7LKhVZF5sJA39WPN/86'/1'/0'/0/*)#40hv8z77
+```
+
+Now, we will generate 10 addresses using `bitcoin-cli` and thereafter `bdk-cli` using this above descriptor.
+Notice how both of them output the same set of addresses.
+
+```bash
+# Generation via bdk-cli
+repeat 10 { bdk-cli -n regtest wallet --descriptor $EX_DESC -w mywallet get_new_address | jq -r ".address" }
+bcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp
+bcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur
+bcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez
+bcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99
+bcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv
+bcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy
+bcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j
+bcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp
+bcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67
+bcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz
+
+# Generation via bitcoin-cli
+repeat 10 { bitcoin-cli -rpcwallet="mywallet" getnewaddress }
+bcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp
+bcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur
+bcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez
+bcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99
+bcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv
+bcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy
+bcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j
+bcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp
+bcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67
+bcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz
+```
+
+Notes:
+- The `repeat n {}` syntax will only work in `zsh`, you can use other loops for your shell, or just manually repeat the code 10 times.
+- In case you get different outputs in either of the cases, try deleting `~/.bdk-bitcoin` and retrying (thanks [@Steve](https://twitter.com/notmandatory) for this tip!)
+
+Note that both `bdk-cli` and `bitcoin-cli` produced the exact same addresses. So now we have definitive proof that descriptors can make wallets portable. That single string will be able to make any wallet generate the same set of addresses and hence they can sync and broadcast transactions in the same manner!
+
+#### Making a MultiSig Descriptor for Funds
+
+In the real-life, most of us hold two kinds of savings accounts - one to store huge funds saved throughout our lifetime *(probably without internet banking functionalities)* 
+and another for regular expenses.
+
+In the Bitcoin world, to store huge funds, most people prefer to use a Multisig descriptor with a `2-of-3` or `3-of-4` setup. 
+They can have one key stored in their PC, one key stored in a hardware wallet, one key stored in writing in a secure vault and another key learnt by heart.
+In case of a mishap like a house burning on fire or permanent memory loss, they would still be able to recover their funds by using the other keys.
+
+Here's how a secure `2-of-3` descriptor generation would look like:
+
+```bash
+# xprv generation
+K1_XPRV=$(bdk-cli key generate | jq -r ".xprv")
+K2_XPRV=$(bdk-cli key generate | jq -r ".xprv")
+K3_XPRV=$(bdk-cli key generate | jq -r ".xprv")
+
+# xpub generation
+K1_XPUB=$(bdk-cli key derive --xprv $K1_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+K2_XPUB=$(bdk-cli key derive --xprv $K2_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+K3_XPUB=$(bdk-cli key derive --xprv $K3_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+
+# Descriptors for each key - Since we used BIP-84 generation paths for xpubs,
+# we need to append the same to the xprvs so that our wallet can understand 
+# which path to generate addresses and xpubs from
+K1_DESC="wsh(multi(2,$K1_XPRV/84'/1'/0'/0/*,$K2_XPUB,$K3_XPUB))"
+K2_DESC="wsh(multi(2,$K1_XPUB,$K2_XPRV/84'/1'/0'/0/*,$K3_XPUB))"
+K3_DESC="wsh(multi(2,$K1_XPUB,$K2_XPUB,$K3_XPRV/84'/1'/0'/0/*))"
+```
+
+Lets create three bdk wallets aliases with above descriptors for easy future use
+and do initial sync to create the wallet files
+```bash
+alias k1wallet='bdk-cli -n regtest wallet -w K1 -d $K1_DESC'
+alias k2wallet='bdk-cli -n regtest wallet -w K2 -d $K2_DESC'
+alias k3wallet='bdk-cli -n regtest wallet -w K3 -d $K3_DESC'
+
+k1wallet sync
+{}
+k2wallet sync
+{}
+k3wallet sync
+{}
+```
+
+Now, let us send some funds to an address generated by `k1wallet`.
+
+```
+# ask regtest to generate 101 blocks, so we get 50 regtest coins to play with.
+# because coinbase amounts are only spendable after 100 blocks, we generate
+# 101 blocks, to use the first block's coinbase amount.
+CORE_ADDR=$(bitcoin-cli getnewaddress)
+bitcoin-cli generatetoaddress 101 $CORE_ADDR
+bitcoin-cli getbalance
+50.00000000
+
+# And then send 10 btc to an address generated by `K1` descriptor
+BDK_ADDR=$(k1wallet get_new_address | jq -r ".address")
+bitcoin-cli -rpcwallet=mywallet sendtoaddress $BDK_ADDR 10
+
+# Confirm the transaction by creating one more block
+bitcoin-cli generatetoaddress 1 $CORE_ADDR
+```
+
+Now sync the wallets and check balances in each
+```bash
+k1wallet sync
+{}
+k1wallet get_balance
+{
+  "satoshi": 1000000000
+}
+
+k2wallet sync
+{}
+k2wallet get_balance
+{
+  "satoshi": 1000000000
+}
+
+k3wallet sync
+{}
+k3wallet get_balance
+{
+  "satoshi": 1000000000
+}
+```
+
+Everyone has the same amount of balance. 
+This happened because it was a multisig wallet.
+Now, let's try to spend some balance.
+We will give back some balance to the wallet maintained by `bitcoin-cli`.
+But remember, this is a `2-of-3` multisig wallet.
+That's why we will need at least two keys to sign to make a transaction.
+
+Here's where we will require to use a [PSBT](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) or a *partially signed bitcoin transaction*. 
+Bitcoin uses PSBTs as the standard protocol to create a transaction and add one or more signatures to it before broadcasting the same to 
+the network which finally can become a proper valid *transaction*.
+
+We will aks `k2wallet` to create and sign the transaction then `k1wallet` and `k3wallet` will co-sign it.
+Note that `k2wallet` even if it creates the transaction, doesn't need to sign it, because its a `2-of-3` multisig!
+```bash
+# create the transaction, can be started by anyone
+PSBT=$(k2wallet create_tx --to "$CORE_ADDR:100000000" | jq -r ".psbt")
+
+# Sign the transaction by K1 and look at the output
+# it should say the psbt is not finalized since only one party has signed
+k1wallet sign --psbt $PSBT
+{
+   "is_finalized": false,
+   "psbt": "[...]"
+}
+
+# Saving the PSBT signed by K1
+K1_SIGNED_PSBT=$(k1wallet sign --psbt $PSBT | jq -r ".psbt")
+
+# Sign by K3 - should be finalized this time
+# Notice that this time, the input psbt was the signed PSBT of K1
+k3wallet sign --psbt $K1_SIGNED_PSBT
+{
+   "is_finalized": true,
+   "psbt": "[...]"
+}
+
+# Saving the PSBT signed by K3
+SIGNED_PSBT=$(k3wallet sign --psbt $K1_SIGNED_PSBT | jq -r ".psbt")
+
+# Broadcast the transaction, again doesn't really matter who broadcasts
+k2wallet broadcast --psbt $SIGNED_PSBT
+{
+   "txid": "49e2706fc73c49605692bf1b9ce58baf1eb0307ea39b3118628994fd56c9b642"
+}
+
+# Confirm the transaction by generating one block
+bitcoin-cli generatetoaddress 1 $CORE_ADDR
+
+# Sync and check balance - it should have gone down by 100000000 + tx fees
+k1wallet sync
+k1wallet get_balance
+{
+  "satoshi": 899999810
+}
+# Check similarly for `k2wallet` and `k3wallet` and they should all have same balance
+```
+
+So this proves we can definitely do transactions with multisig wallets with complicated descriptors.
+Since for Bitcoin, having keys equal having access to the accounts, we need to keep our keys safe.
+For legacy single key wallets, we used to keep backups of the mnemonic codes in multiple places.
+It was pretty insecure because in case any one of those backups leaks, our entire account would be compromised.
+Complicated multisig wallet descriptors are definitely a step forward - just in case a single key leak or are lost, no one would be able to take charge of the funds we hold.
+
+Another problem with multisig was syncing between wallets to always create consistent addresses. How would
+one wallet know whats the next address to create without talking to other wallets? The answer is `descriptors + PSBT`.
+If all the wallet shares the correct descriptor string they will always create the exact sequence of addresses and
+by passing around PSBTs they would know how to sign them, without talking to each other. This solves a major problem of multisig interoperability. And BDK makes this process as seamless as possible.
+
+### Retention Bonus - Smart Contract with Bitcoin
+
+Let us consider that a company wants to give its employees a retention bonus for two months.
+If an employee stays with that company for over 2 months, the employee would get 1 BTC as a reward.
+This would be a smart contract between the company and an employee.
+The employee should be able to see that he would get his funds after two months.
+The company would require confidence that the employee would not be able to withdraw the reward before two months have passed.
+
+The Miniscript policy for this contract would be as follows:
+```
+or(99@and(pk(E),older(8640)),pk(C))
+```
+where `E` is the employee and `C` is the company.
+
+I should emphasize over here that this policy will let the company still transfer funds after the designated 2 months.
+It's not possible to block them after the lock time has passed, atleast not in a single policy.
+
+Surely, after two months, the funds can be unlocked by the employee but before that, the company can revoke the funds.
+Let us compile this policy down to a descriptor. And this time we will ask help from the `miniscript` program.
+
+```bash
+# The Descriptor will be on the log, the E and C are placeholders
+miniscriptc "or(99@and(pk(E),older(8640)),pk(C))" sh-wsh
+[2021-08-05T12:25:40Z INFO  miniscriptc] Compiling policy: or(99@and(pk(E),older(8640)),pk(C))
+[2021-08-05T12:25:40Z INFO  miniscriptc] ... Descriptor: sh(wsh(andor(pk(E),older(8640),pk(C))))#55wzucxa
+Error: Descriptor(Miniscript(Unexpected("Key too short (<66 char), doesn't match any format")))
+```
+
+So the compiled descriptor is
+```
+sh(wsh(andor(pk(E),older(8640),pk(C))))
+```
+
+Let's make the keys, generate addresses using the above descriptor and fund it.
+```bash
+# xprvs
+E_XPRV=$(bdk-cli key generate | jq -r ".xprv")
+C_XPRV=$(bdk-cli key generate | jq -r ".xprv")
+
+# xpubs
+E_XPUB=$(bdk-cli key derive --xprv $E_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+C_XPUB=$(bdk-cli key derive --xprv $C_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+
+# descriptors using the compiled miniscript
+# please note in case company or the employee was using a complicated multisig descriptor,
+# it may as well have been added here like we did in the example before
+E_DESC="sh(wsh(andor(pk($E_XPRV/84'/1'/0'/0/*),older(8640),pk($C_XPUB))))"
+C_DESC="sh(wsh(andor(pk($E_XPUB),older(8640),pk($C_XPRV/84'/1'/0'/0/*))))"
+
+# Create wallet aliases for easy access and sync the wallet to create initial wallet files
+alias Cwallet='bdk-cli -n regtest wallet -w C -d $C_DESC'
+alias Ewallet='bdk-cli -n regtest wallet -w E -d $E_DESC'
+
+Cwallet sync
+{}
+Ewallet sync
+{}
+
+# get some funds in  Cwallet's address
+C_ADDR=$(Cwallet get_new_address | jq -r ".address")
+bitcoin-cli -rpcwallet=mywallet sendtoaddress $C_ADDR 10
+
+# Confirm the transaction
+bitcoin-cli generatetoaddress 1 $CORE_ADDR
+
+# Sync and check balance
+Cwallet sync
+{}
+Cwallet get_balance
+{
+  "satoshi": 1000000000
+}
+
+# Just as before, the employe can also see the fund in their wallet
+Ewallet sync
+{}
+Ewallet get_balance
+{
+  "satoshi": 1000000000
+}
+```
+
+According to the spending policy, for `E` has to wait for 8640 blocks before he can spend the coins.
+But let's check what happens if `E` tries to transact before the designated 2 months anyway.
+
+```bash
+# address to send the transaction to
+E_ADDR=$(Ewallet getnewaddress | jq -r ".address")
+
+# get external_policy id - this identifies which policy the wallet will try to sign against
+POLICY_ID=$(Ewallet policies | jq -r ".external | .id")
+
+# create the tx (external_policy id from last step in my case is j7ncy3au
+PSBT=$(Ewallet create_tx --to "$E_ADDR:100000000" --external_policy "{\"$POLICY_ID\":[0]}" | jq -r ".psbt")
+
+# sign and save the signed psbt
+SIGNED_PSBT=$(Ewallet sign --psbt $PSBT | jq -r ".psbt")
+
+# now let's try to broadcast - and see it failing
+Ewallet broadcast --psbt $SIGNED_PSBT
+[2021-08-05T17:48:45Z ERROR bdk_cli] Electrum(Protocol(Object({"code": Number(2), "message": String("sendrawtransaction RPC error: {\"code\":-26,\"message\":\"non-BIP68-final\"}")})))
+```
+
+We get an error saying the transaction we sent is **Not BIP68 Final**.
+[BIP68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) is a relative lock-time specification that ensures consensus when a signed transaction is sent which is invalid at a given time because the lock time isn't passed.
+So that's an expected error.
+
+Now let's simulate two months passing and retry.
+
+```bash
+# simulate two months
+# this will take around 1 mins to complete
+bitcoin-cli generatetoaddress 8640 $CORE_ADDR
+
+# create, sign and broadcast tx
+PSBT=$(Ewallet create_tx --to $E_ADDR:100000000 --external_policy "{\"$POLICY_ID\":[0]}" | jq -r ".psbt")
+SIGNED_PSBT=$(Ewallet sign --psbt $PSBT | jq -r ".psbt")
+Ewallet broadcast --psbt $SIGNED_PSBT
+{
+  "txid": "2a0919bb3ce6e26018698ad1169965301a9ceab6d3da2a3dcb41343dc48e0dba"
+}
+
+# Confirm the transaction
+bitcoin-cli generatetoaddress 1 $CORE_ADDR
+
+# Sync and check balances
+Cwallet sync
+{}
+Cwallet get_balance
+{
+  "satoshi": 999999810
+}
+
+Ewallet sync
+{}
+Ewallet get_balance
+{
+  "satoshi": 999999810
+}
+```
+
+So this time it worked, because we have simulated 2 months passing by generating 8640 blocks. And both the Company
+and Employe wallet gets updated.
+Hence, we saw that we can generate some smart contracts using Bitcoin.
+
+### Inspirations
+
+1. [Descriptors from Bitcoin Core](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md)
+1. [Miniscript](http://bitcoin.sipa.be/miniscript)
+1. [Output Script Descriptors](https://bitcoinops.org/en/topics/output-script-descriptors)
+1. [Descriptors in Bitcoin Dev Kit](https://bitcoindevkit.org/descriptors)
+1. [Role of Descriptors](https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/#the-role-of-descriptors)
+1. [Making a Taproot Descriptor Wallet using bitcoin-cli](https://gist.github.com/notmandatory/483c7edd098550c235da75d5babcf255)
+1. [Miniscripts SBC '19 - Video](https://www.youtube.com/watch?v=XM1lzN4Zfks)
+1. [Rethinking Wallet Architecture: Native Descriptor Wallets - Video](https://www.youtube.com/watch?v=xC25NzIjzog)
+
+Special thanks to my mentor [Steve Myers](https://twitter.com/notmandatory) for the constant motivation and support he gave me and for clearing so many doubts!
+Immense thanks to [Raj](https://github.com/rajarshimaitra) for reviewing this blog and giving such detailed suggestions.
+Many of the lines added here are his.
+Also, thanks to the folks at the `#miniscript` IRC channel to help me out with the Retention Bonus policy.
+
+This blog was written during [Summer of Bitcoin 2021](https://summerofbitcoin.org) by [Sandipan Dey](https://twitter.com/@sandipndev).
\ No newline at end of file
diff --git a/docs/tutorials/spending_policy_demo.md b/docs/tutorials/spending_policy_demo.md
new file mode 100644 (file)
index 0000000..344afd5
--- /dev/null
@@ -0,0 +1,441 @@
+---
+title: "Spending Policy Demo"
+description: "Demonstrate how to use a descriptor wallet with different spending policies"
+authors:
+    - Steve Myers
+    - thunderbiscuit
+date: "2021-02-23"
+tags: ["guide", "descriptor"]
+permalink: "/blog/2021/02/spending-policy-demo/"
+---
+
+In this post we will use the [bdk-cli](https://github.com/bitcoindevkit/bdk-cli) tool to demonstrate how to use the [bdk](https://github.com/bitcoindevkit/bdk) library to:
+
+1. generate *testnet* public and private keys
+2. create [PSBT](https://bitcoinops.org/en/topics/psbt/)s that can be spent based on different [miniscript spending policies](http://bitcoin.sipa.be/miniscript/)
+3. cooperatively sign and finalize the resulting PSBTs
+4. broadcast and confirm spending transactions
+
+The scenario we will simulate is a wallet with two spending policies:
+
+A. **three** out of **three** signers must sign spending transaction input [UTXO](https://developer.bitcoin.org/glossary.html)s, **OR**
+
+B. **two** out of **three** signers must sign **AND** the input UTXOs must be a relative number of blocks older than the spending transaction's block
+
+In a real-world wallet a longer relative time-lock would probably be used, but we chose a two block time-lock to make testing easier.
+
+*Note: If you repeat these instructions on your own your extended keys, addresses, and other values will be different than shown in this post, but the end results should be the same.*
+
+## Initial Setup
+
+### Step 0: Install a recent version `bdk-cli`
+
+```bash
+cargo install bdk-cli --features electrum
+
+# confirm bdk-cli is installed
+bdk-cli --version
+BDK CLI 0.4.0
+
+# bdk-cli usage can be explored with the `help` sub-command
+bdk-cli help
+```
+
+### Step 1: Generate private extended keys
+
+Generate new extended private keys for each of our wallet participants:
+
+```bash
+bdk-cli key generate | tee alice-key.json
+{
+  "fingerprint": "5adb4683",
+  "mnemonic": "witness poverty pulse crush era item game rose bargain quantum spawn sure way behave also basket journey worry stem entry toddler floor way bone",
+  "xprv": "tprv8ZgxMBicQKsPeAuGznXJZwfWHgWo86dFuufRBZN7ZT44UzoNG2cYmZLNLrnsm7eXhGSeccRU2nTtxunT11UkpqrRhJQefBnFJeHBddF68bg"
+}
+
+bdk-cli key generate | tee bob-key.json
+{
+  "fingerprint": "5fdec309",
+  "mnemonic": "shiver atom february jealous spy gallery upset height captain snake tooth master ugly orbit amazing nice parrot elevator own olympic great relief ozone violin",
+  "xprv": "tprv8ZgxMBicQKsPei56wJPNt9u2132Ynncp2qXdfSHszobnyjaGjQwxQBGASUidc1unmEmpyMQ9XzLgvbN36MDW7LNziVFdXVGMrx6ckMHuRmd"
+}
+
+bdk-cli key generate | tee carol-key.json
+{
+  "fingerprint": "de41e56d",
+  "mnemonic": "upon bridge side tool style lounge need faculty middle nation armed corn valve that undo ribbon rent digital adapt capable embody zero shiver carpet",
+  "xprv": "tprv8ZgxMBicQKsPf2edJLnXsF2AKwkCshCy2Z7fQD6FxiNVGsbkvpLRfxM8FSKrLqqpLFzLzVUBwgE9F5MQASrbedKCrGk1NG8oJgqYtmTLQEU"
+}
+```
+
+### Step 2: Extract private extended keys
+
+Here we use the `jq` Unix command to parse the json output of the `bdk-cli` commands.
+
+```bash
+export ALICE_XPRV=$(cat alice-key.json | jq -r '.xprv')
+
+export BOB_XPRV=$(cat bob-key.json | jq -r '.xprv')
+
+export CAROL_XPRV=$(cat carol-key.json | jq -r '.xprv')
+```
+
+### Step 3: Derive public extended keys
+
+For this example we are using the [BIP-84](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki) key path: `m/84h/1h/0h/0/*` to derive extended public keys to share with other wallet participants.
+
+Note that the `key derive` sub-command will generate a tpub for the last hardened node in the given derivation path. You'll also notice that `bdk-cli` will returns our tpub with the key origin (fingerprint/path) added to it (the metadata part that looks like `[5adb4683/84'/1'/0']` right before the tpub). This key origin information is not necessary in order to use a tpub and generate addresses, but it's good practice to include it because some signers require it.
+
+```bash
+export ALICE_XPUB=$(bdk-cli key derive --xprv $ALICE_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+echo \"$ALICE_XPUB\"
+"[5adb4683/84'/1'/0']tpubDCyRBuncqwyAjSNiw1GWLmwQsWyhgPMEBpx3ZNpnCwZwf3HXerspTpaneN81KRxkwj8vjqH9pNWEPgNhen7dfE212SHfxBBbsCywxQGxvvu/0/*"
+
+export BOB_XPUB=$(bdk-cli key derive --xprv $BOB_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+echo \"$BOB_XPUB\"
+"[5fdec309/84'/1'/0']tpubDDQcUeBH9JFtgZEsHZBhmRu8AuZ8ceJY1umnipPVEg1had2coGMCWdFBXNnZWKoCPic3EMgDZTdmkAVNoakwNZu2ESSW36rQvts6VXGx4bU/0/*"
+
+export CAROL_XPUB=$(bdk-cli key derive --xprv $CAROL_XPRV --path "m/84'/1'/0'/0" | jq -r ".xpub")
+echo \"$CAROL_XPUB\"
+"[de41e56d/84'/1'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/0/*"
+```
+
+### Step 4: Create wallet descriptors for each participant
+
+We used the [BDK Playground Policy Compiler](https://bitcoindevkit.org/bdk-cli/playground/) to compile the [miniscript](http://bitcoin.sipa.be/miniscript/) policy:
+
+`thresh(3,pk(Alice),pk(Bob),pk(Carol),older(2))`
+
+To the [output descriptor](https://bitcoindevkit.org/descriptors/):
+
+`wsh(thresh(3,pk(Alice),s:pk(Bob),s:pk(Carol),sdv:older(2)))`
+
+This descriptor requires spending transaction inputs must be signed by all three signers, or by two signers and the spent UTXOs must be older than two blocks.
+
+Each participant's descriptor only uses their own XPRV key plus the XPUB keys of the other participants.
+
+```bash
+export ALICE_DESCRIPTOR="wsh(thresh(3,pk($ALICE_XPRV/84'/1'/0'/0/*),s:pk($BOB_XPUB),s:pk($CAROL_XPUB),sdv:older(2)))"
+
+export BOB_DESCRIPTOR="wsh(thresh(3,pk($ALICE_XPUB),s:pk($BOB_XPRV/84'/1'/0'/0/*),s:pk($CAROL_XPUB),sdv:older(2)))"
+
+export CAROL_DESCRIPTOR="wsh(thresh(3,pk($ALICE_XPUB),s:pk($BOB_XPUB),s:pk($CAROL_XPRV/84'/1'/0'/0/*),sdv:older(2)))"
+```
+
+## Policy A. Three signatures
+
+### Step 1a: Create a testnet [segwit0](https://en.bitcoin.it/wiki/Segregated_Witness) receive address
+
+This step can be done independently by Alice, Bob, or Carol.
+
+```bash
+bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR get_new_address
+{
+  "address": "tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e"
+}
+```
+
+### Step 2a: Send testnet bitcoin from a faucet to receive address
+
+After a faucet payment is sent, use a testnet block explorer to confirm the transaction was included in a block.
+
+[https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e](https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e)
+
+### Step 3a: Sync participant wallets and confirm balance
+
+This step must be done by Alice, Bob, and Carol so their individual descriptor wallets know about the faucet transaction they will later be spending the output of.
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
+{}
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
+{
+  "satoshi": 10000
+}
+
+bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sync
+{}
+bdk-cli wallet -w bob -d $BOB_DESCRIPTOR get_balance
+{
+  "satoshi": 10000
+}
+
+bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR sync
+{}
+bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR get_balance
+{
+  "satoshi": 10000
+}
+```
+
+### Step 4a: View wallet spending policies
+
+This can also be done by any wallet participant, as long as they have the same descriptor and extended public keys from the other particpants..
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR policies
+{
+  "external": {
+    "contribution": {
+      "conditions": {
+        "0": [
+          {}
+        ],
+        "3": [
+          {
+            "csv": 2
+          }
+        ]
+      },
+      "items": [
+        0,
+        3
+      ],
+      "m": 3,
+      "n": 4,
+      "type": "PARTIAL"
+    },
+    "id": "ydtnup84",
+    "items": [
+      {
+        "contribution": {
+          "condition": {},
+          "type": "COMPLETE"
+        },
+        "fingerprint": "5adb4683",
+        "id": "uyxvyzqt",
+        "satisfaction": {
+          "type": "NONE"
+        },
+        "type": "SIGNATURE"
+      },
+      {
+        "contribution": {
+          "type": "NONE"
+        },
+        "fingerprint": "5fdec309",
+        "id": "dzkmxcgu",
+        "satisfaction": {
+          "type": "NONE"
+        },
+        "type": "SIGNATURE"
+      },
+      {
+        "contribution": {
+          "type": "NONE"
+        },
+        "fingerprint": "de41e56d",
+        "id": "ekfu5uaw",
+        "satisfaction": {
+          "type": "NONE"
+        },
+        "type": "SIGNATURE"
+      },
+      {
+        "contribution": {
+          "condition": {
+            "csv": 2
+          },
+          "type": "COMPLETE"
+        },
+        "id": "8kel7sdw",
+        "satisfaction": {
+          "type": "NONE"
+        },
+        "type": "RELATIVETIMELOCK",
+        "value": 2
+      }
+    ],
+    "satisfaction": {
+      "type": "NONE"
+    },
+    "threshold": 3,
+    "type": "THRESH"
+  },
+  "internal": null
+}
+```
+
+### Step 5a: Create spending transaction
+
+The transaction can also be created by Alice, Bob, or Carol, or even an untrusted coordinator that only has all three tpubs.
+
+Note that the argument provided to the --external_policy flag contains the id retrieved from the `policies` subcommand in the above step, in this case `ydtnup84`.
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,2]}"
+{
+  "details": {
+    "fees": 169,
+    "height": null,
+    "received": 0,
+    "sent": 10000,
+    "timestamp": 1614058791,
+    "transaction": null,
+    "txid": "3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"
+  },
+  "psbt": "cHNidP8BAFIBAAAAAYx7T0cL7EoUYBEU0mSL6+DS4VQafUzJgAf0Ftlbkya5AQAAAAD/////AWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgCBH16JNfSPhmjJR75EdDB+gSCEF7tStNOLqw/k3BvA0BBXchA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxrHwhA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mrJN8IQIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOKyTfHZjUrJpaJNThyIGAi82No/6bA0LQO2BoHoQ0H8M8+VtQNHr41nhLDTvSPM4DO66tnIAAAAAAAAAACIGA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxGFrbRoNUAACAAQAAgAAAAIAAAAAAAAAAACIGA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mDEMxpeYAAAAAAAAAAAAA"
+}
+
+export UNSIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,2]}" | jq -r ".psbt")
+```
+
+### Step 6a: Sign and finalize PSBTs
+
+```bash
+# ALICE SIGNS
+export ALICE_SIGNED_PSBT=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sign --psbt $UNSIGNED_PSBT | jq -r ".psbt")
+
+# BOB SIGNS
+export ALICE_BOB_SIGNED_PSBT=$(bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sign --psbt $ALICE_SIGNED_PSBT | jq -r ".psbt")
+
+# CAROL SIGNS
+export FINAL_PSBT=$(bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR sign --psbt $ALICE_BOB_SIGNED_PSBT | jq -r ".psbt")
+
+## PSBT is finalized
+bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR sign --psbt $ALICE_BOB_SIGNED_PSBT
+{
+  "is_finalized": true,
+  "psbt": "cHNidP8BAFIBAAAAAYx7T0cL7EoUYBEU0mSL6+DS4VQafUzJgAf0Ftlbkya5AQAAAAD/////AWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgCBH16JNfSPhmjJR75EdDB+gSCEF7tStNOLqw/k3BvA0iAgIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOEcwRAIgRPXSwFLfzD1YQzw5FGYA0TgiQ+D88hSOVDbvyUZDiPUCIAbguaSGgCbBAXo5sIxpZ4c1dcGkYyrrqnDjc1jcdJ1CASICA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxSDBFAiEA0kdkvlA+k5kUBWVUM8SkR4Ua9pnXF66ECVwIM1l0doACIF0aMiORVC35+M3GHF2Vl8Q7t455mebrr1HuLaAyxBOYASICA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mRzBEAiBPJlQEnuVDHgfgOdTZNlIcRZz2iqHoMWfDmLMFqJSOQAIgCuOcTKp/VaaqwIjnYfMKO3eQ1k9pOygSWt6teT1o13QBAQV3IQN3NQJNpHBjszoenkVxSn6Z6cz9Zc33FyGIcRRmRudZsax8IQO+WA10Swy7fnl+VLBNN5iBlErED9jKyfZZte3Blw8NpqyTfCECLzY2j/psDQtA7YGgehDQfwzz5W1A0evjWeEsNO9I8zisk3x2Y1KyaWiTU4ciBgIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOBjeQeVtVAAAgAEAAIAAAACAAAAAAAAAAAAiBgN3NQJNpHBjszoenkVxSn6Z6cz9Zc33FyGIcRRmRudZsQwpbm6KAAAAAAAAAAAiBgO+WA10Swy7fnl+VLBNN5iBlErED9jKyfZZte3Blw8NpgxDMaXmAAAAAAAAAAABBwABCP1TAQUARzBEAiBE9dLAUt/MPVhDPDkUZgDROCJD4PzyFI5UNu/JRkOI9QIgBuC5pIaAJsEBejmwjGlnhzV1waRjKuuqcONzWNx0nUIBRzBEAiBPJlQEnuVDHgfgOdTZNlIcRZz2iqHoMWfDmLMFqJSOQAIgCuOcTKp/VaaqwIjnYfMKO3eQ1k9pOygSWt6teT1o13QBSDBFAiEA0kdkvlA+k5kUBWVUM8SkR4Ua9pnXF66ECVwIM1l0doACIF0aMiORVC35+M3GHF2Vl8Q7t455mebrr1HuLaAyxBOYAXchA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxrHwhA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mrJN8IQIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOKyTfHZjUrJpaJNThwAA"
+```
+
+### Step 7a: Broadcast finalized PSBT
+
+```bash
+bdk-cli wallet -w carol -d $CAROL_DESCRIPTOR broadcast --psbt $FINAL_PSBT
+{
+  "txid": "3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"
+}
+```
+
+### Step 8a: Confirm transaction included in a testnet block
+
+[https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e](https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e)
+
+And new wallet balance is now zero.
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
+{}
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
+{
+  "satoshi": 0
+}
+```
+
+### DONE!
+
+## Policy B. Two signatures after a relative time lock
+
+Now we will use the same extended private and public keys, and the same descriptors to receive and spend testnet bitcoin using only two of our participants signatures after the transaction input's relative time-lock has expired.
+
+### Step 1b: Create a new testnet receive address
+
+The receive address can still be generated by Alice, Bob, or Carol.
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_new_address
+{
+  "address": "tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9"
+}
+```
+
+### Step 2b: Fund new address from testnet faucet
+
+After the faucet payment is sent, confirm using a testnet block explorer to verify the transaction was included in a block.
+
+[https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9](https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9)
+
+### Step 3b: Sync wallet and confirm wallet balance
+
+This step must be done by Alice and Bob so their individual descriptor wallets know about the faucet transaction they will later be spending the output of.
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
+{}
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
+{
+  "satoshi": 10000
+}
+
+bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sync
+{}
+bdk-cli wallet -w bob -d $BOB_DESCRIPTOR get_balance
+{
+  "satoshi": 10000
+}
+
+# NO CAROL SHE LOST HER KEY!
+```
+
+### Step 4b: Create spending transaction
+
+This spending transaction uses Alice and Bob's keys plus a two block relative time-lock, see above [Step 4a](#step-4a-view-wallet-spending-policies) for the policy id. The transaction can be created by Alice or Bob.
+
+A time based relative time-lock can be used instead of one based on blocks but is slightly more complicated to calculate. See
+[BIP-68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#specification) for the details.
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,3]}"
+{
+  "details": {
+    "fees": 169,
+    "height": null,
+    "received": 0,
+    "sent": 10000,
+    "timestamp": 1614059434,
+    "transaction": null,
+    "txid": "6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"
+  },
+  "psbt": "cHNidP8BAFICAAAAAYmc6mhj4Cf4pcJyBvxSbCd9IB1yDGs+plzb95t7++v0AAAAAAACAAAAAWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgOfTlC2vtnGDNEC2n4j++Wxusqryh4QyqDCqEOQZ5mm4BBXchAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCpprHwhAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFrJN8IQOrU70B/wo/oUUCKFQ2cIsBxx6SysE7uVwxyu0ozM4zYqyTfHZjUrJpaJNThyIGAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCppGFrbRoNUAACAAQAAgAAAAIAAAAAAAQAAACIGAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFDEMxpeYAAAAAAQAAACIGA6tTvQH/Cj+hRQIoVDZwiwHHHpLKwTu5XDHK7SjMzjNiDO66tnIAAAAAAQAAAAAA"
+}
+
+export UNSIGNED_PSBT2=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR create_tx -a --to tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 --external_policy "{\"ydtnup84\": [0,1,3]}" | jq -r ".psbt")
+```
+
+### Step 5b: Sign and finalize PSBTs
+
+```bash
+# ALICE SIGNS
+export ALICE_SIGNED_PSBT2=$(bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sign --psbt $UNSIGNED_PSBT2 | jq -r ".psbt")
+
+# BOB SIGNS
+export FINAL_PSBT2=$(bdk-cli wallet -w bob -d $BOB_DESCRIPTOR sign --psbt $ALICE_SIGNED_PSBT2 | jq -r ".psbt")
+
+# CAROL DOES *NOT* SIGN
+```
+
+### Step 6b: Broadcast finalized PSBT
+
+```bash
+bdk-cli wallet -w bob -d $BOB_DESCRIPTOR broadcast --psbt $FINAL_PSBT2
+thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Electrum(Protocol(String("sendrawtransaction RPC error: {\"code\":-26,\"message\":\"non-BIP68-final\"}")))', src/bdk_cli.rs:168:50
+
+# Oops we didn't wait long enough for the relative time lock to expire
+
+# Try again in ~20 mins and it is successfully broadcast
+
+bdk-cli wallet -w bob -d $BOB_DESCRIPTOR broadcast --psbt $FINAL_PSBT2
+{
+  "txid": "6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"
+}
+```
+
+### Step 7b: View confirmed transaction
+
+[https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28](https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28)
+
+And wallet balance is again zero
+
+```bash
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR sync
+{}
+bdk-cli wallet -w alice -d $ALICE_DESCRIPTOR get_balance
+{
+  "satoshi": 0
+}
+```
+
+### Done again!
+
+In this demo we showed how to receive and spend bitcoin using two different descriptor wallet policies using the `bdk` library and `bdk-cli` wallet tool.