From e63ba97e7de23b71531782e26c3b8e45efae33bb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 21 Nov 2024 16:51:05 +0000 Subject: [PATCH] deploy: c4fa0fb08f2da554b57c3792b29f07c39c0951b4 --- 404.html | 6 +++--- adoption/all/index.html | 4 ++-- adoption/custodial/index.html | 4 ++-- adoption/desktop/index.html | 4 ++-- adoption/exchange/index.html | 4 ++-- adoption/hardware/index.html | 4 ++-- adoption/infrastructure/index.html | 4 ++-- adoption/mobile/index.html | 4 ++-- adoption/web/index.html | 4 ++-- assets/js/{19.13924d29.js => 19.fc7dec75.js} | 2 +- assets/js/{21.87c145fc.js => 21.d529cde5.js} | 2 +- assets/js/{31.f9273387.js => 31.c4152f8b.js} | 2 +- assets/js/{34.842dbe3a.js => 34.40447606.js} | 2 +- assets/js/{39.f8b5da6d.js => 39.3261ad3c.js} | 2 +- assets/js/{40.5f4c9ecf.js => 40.4ab0673d.js} | 2 +- assets/js/{41.017da959.js => 41.01e60973.js} | 2 +- assets/js/{42.c35335fc.js => 42.bf416f89.js} | 2 +- assets/js/{46.8a620891.js => 46.c88b1de0.js} | 2 +- assets/js/{47.1e361a05.js => 47.70dc63ea.js} | 2 +- assets/js/{48.6c8fd04b.js => 48.1c4bedef.js} | 2 +- assets/js/{49.5320af3f.js => 49.3295c4d3.js} | 2 +- assets/js/{50.b7380ea9.js => 50.cf7b9b4d.js} | 2 +- assets/js/{51.d80754c0.js => 51.8de4cf97.js} | 2 +- assets/js/{53.08f20b3c.js => 53.185fde0b.js} | 2 +- assets/js/{54.018c80a1.js => 54.c56c2eff.js} | 2 +- assets/js/{55.06a752f4.js => 55.fc6f0c87.js} | 2 +- assets/js/{58.b6598903.js => 58.10758a4f.js} | 2 +- assets/js/{59.9b9541ac.js => 59.1c408bd0.js} | 2 +- assets/js/{60.48c95147.js => 60.3b526e17.js} | 2 +- assets/js/{61.f6ea4853.js => 61.588e1148.js} | 2 +- assets/js/{65.a538fc82.js => 65.728ab52c.js} | 2 +- assets/js/{66.a99413d8.js => 66.6ebad210.js} | 2 +- assets/js/{69.c92f69ce.js => 69.3d319207.js} | 2 +- assets/js/{70.4663d7b0.js => 70.3bb83c63.js} | 2 +- assets/js/{71.2a8871be.js => 71.0e559a1c.js} | 2 +- assets/js/{72.d0343ad9.js => 72.1d7ffcda.js} | 2 +- assets/js/{73.a5e67ee7.js => 73.5decc786.js} | 2 +- assets/js/{78.f8907212.js => 78.4514085a.js} | 2 +- assets/js/{79.0f18b068.js => 79.61fe8f96.js} | 2 +- assets/js/{80.1e8a3836.js => 80.00db3e80.js} | 2 +- assets/js/{85.944e7baf.js => 85.bee02999.js} | 2 +- assets/js/{86.5eefdee5.js => 86.ac423664.js} | 2 +- assets/js/{94.bff8e7bd.js => 94.78a1ba7f.js} | 2 +- assets/js/{95.8216e261.js => 95.ef892223.js} | 2 +- assets/js/{96.1fc7dd90.js => 96.68e5ddd3.js} | 2 +- assets/js/{app.b7fe13ec.js => app.f3740f7e.js} | 4 ++-- bdk-cli/compiler/index.html | 6 +++--- bdk-cli/concept/index.html | 6 +++--- bdk-cli/installation/index.html | 6 +++--- bdk-cli/interface/index.html | 6 +++--- bdk-cli/introduction/index.html | 6 +++--- bdk-cli/playground/index.html | 6 +++--- bdk-cli/regtest/index.html | 6 +++--- blog/2020/12/hello-world/index.html | 6 +++--- blog/2020/12/release-v0.2.0/index.html | 6 +++--- .../fee-estimation-for-light-clients-part-1/index.html | 6 +++--- .../fee-estimation-for-light-clients-part-2/index.html | 6 +++--- .../fee-estimation-for-light-clients-part-3/index.html | 6 +++--- blog/2021/01/release-v0.3.0/index.html | 6 +++--- blog/2021/02/release-v0.4.0/index.html | 6 +++--- blog/2021/03/release-v0.5.0/index.html | 6 +++--- blog/2021/04/release-v0.6.0/index.html | 6 +++--- blog/2021/05/release-v0.7.0/index.html | 6 +++--- blog/2021/06/release-v0.8.0/index.html | 6 +++--- blog/2021/07/release-v0.9.0/index.html | 6 +++--- .../index.html | 6 +++--- .../index.html | 6 +++--- blog/_2023-q4-update/index.html | 6 +++--- blog/_2024-q1-update/index.html | 6 +++--- blog/_2024-q2-update/index.html | 6 +++--- blog/_2024-q3-rfp-rust-maintainer/index.html | 6 +++--- blog/_2024-q3-update/index.html | 6 +++--- blog/author/Alekos Filini/index.html | 4 ++-- blog/author/Alekos Filini/page/2/index.html | 4 ++-- blog/author/Bitcoin Zavior/index.html | 4 ++-- "blog/author/C\303\251sar Alvarez Vallero/index.html" | 4 ++-- blog/author/Daniela Brozzoni/index.html | 4 ++-- blog/author/Gabriele Domenichini/index.html | 4 ++-- blog/author/Lloyd Fournier/index.html | 4 ++-- blog/author/Rajarshi Maitra/index.html | 4 ++-- blog/author/Riccardo Casatta/index.html | 10 +++++----- blog/author/Sandipan Dey/index.html | 4 ++-- blog/author/Steve Myers/index.html | 4 ++-- blog/author/Wszdexdrf/index.html | 4 ++-- blog/author/index.html | 6 +++--- blog/author/rorp/index.html | 4 ++-- blog/author/thunderbiscuit/index.html | 4 ++-- blog/author/waterst0ne/index.html | 4 ++-- blog/bdk-cli-basics-multisig-2of3/index.html | 6 +++--- blog/bdk-cli-basics/index.html | 6 +++--- blog/bdk-core-pt1/index.html | 6 +++--- blog/bdk-rn-making-of/index.html | 6 +++--- blog/bdk-with-tor/index.html | 6 +++--- blog/bindings-scope/index.html | 6 +++--- blog/bitcoin-core-rpc-demo/index.html | 6 +++--- blog/compact-filters-demo/index.html | 6 +++--- blog/descriptor-based-paper-wallet/index.html | 6 +++--- blog/descriptors-in-the-wild/index.html | 6 +++--- blog/exploring-bdk-flutter/index.html | 6 +++--- blog/exploring-bdk-rn/index.html | 6 +++--- blog/getting-started-with-rust-hwi/index.html | 6 +++--- blog/hidden-power-of-bitcoin/index.html | 6 +++--- blog/improving-coin-selection-in-bdk/index.html | 6 +++--- blog/index.html | 4 ++-- blog/miniscript-vulnerability/index.html | 6 +++--- blog/page/2/index.html | 4 ++-- blog/page/3/index.html | 4 ++-- blog/page/4/index.html | 10 +++++----- blog/road-to-bdk-1/index.html | 6 +++--- blog/spending-policy-demo/index.html | 6 +++--- blog/tags/Android/index.html | 4 ++-- blog/tags/Architecture/index.html | 4 ++-- blog/tags/BDK-RN/index.html | 4 ++-- blog/tags/BDK/index.html | 4 ++-- blog/tags/BDK/page/2/index.html | 4 ++-- blog/tags/BIP157/index.html | 4 ++-- blog/tags/Bitcoin Core/index.html | 4 ++-- blog/tags/Development/index.html | 4 ++-- blog/tags/Flutter/index.html | 4 ++-- blog/tags/Hardware Wallets/index.html | 4 ++-- blog/tags/Neutrino/index.html | 4 ++-- blog/tags/RPC/index.html | 4 ++-- blog/tags/React Native/index.html | 4 ++-- blog/tags/Wallet/index.html | 4 ++-- blog/tags/architecture/index.html | 4 ++-- blog/tags/basics/index.html | 4 ++-- blog/tags/bdk-cli/index.html | 4 ++-- blog/tags/bdk-rn/index.html | 4 ++-- blog/tags/bdk/index.html | 4 ++-- blog/tags/bindings/index.html | 4 ++-- blog/tags/bitcoin-cli/index.html | 4 ++-- blog/tags/bitcoin/index.html | 4 ++-- blog/tags/blockchain/index.html | 4 ++-- blog/tags/coin selection/index.html | 4 ++-- blog/tags/compact_filters/index.html | 4 ++-- blog/tags/descriptor/index.html | 4 ++-- blog/tags/development/index.html | 4 ++-- blog/tags/fee/index.html | 10 +++++----- blog/tags/getting started/index.html | 4 ++-- blog/tags/grants/index.html | 4 ++-- blog/tags/guide/index.html | 4 ++-- blog/tags/iOS/index.html | 4 ++-- blog/tags/index.html | 6 +++--- blog/tags/machine learning/index.html | 10 +++++----- blog/tags/miniscript/index.html | 4 ++-- blog/tags/mobile/index.html | 4 ++-- blog/tags/multi-sig/index.html | 4 ++-- blog/tags/novice/index.html | 4 ++-- blog/tags/paper wallets/index.html | 4 ++-- blog/tags/project/index.html | 4 ++-- blog/tags/release/index.html | 4 ++-- blog/tags/rust/index.html | 4 ++-- blog/tags/security/index.html | 4 ++-- blog/tags/summer of bitcoin/index.html | 4 ++-- blog/tags/taproot/index.html | 4 ++-- blog/tags/tor/index.html | 4 ++-- blog/tags/tutorial/index.html | 4 ++-- blog/tags/wallet/index.html | 4 ++-- blog/using-bdk-with-hardware-wallets/index.html | 6 +++--- blog/why-bindings/index.html | 6 +++--- case-studies/index.html | 4 ++-- descriptors/index.html | 6 +++--- examples/index.html | 6 +++--- foundation/about/index.html | 4 ++-- foundation/become-a-member/index.html | 4 ++-- foundation/grantees/index.html | 4 ++-- foundation/grants/index.html | 4 ++-- foundation/index.html | 4 ++-- foundation/members/index.html | 4 ++-- foundation/supporters/index.html | 4 ++-- getting-started/index.html | 6 +++--- index.html | 4 ++-- sitemap.xml | 2 +- 173 files changed, 373 insertions(+), 373 deletions(-) rename assets/js/{19.13924d29.js => 19.fc7dec75.js} (99%) rename assets/js/{21.87c145fc.js => 21.d529cde5.js} (98%) rename assets/js/{31.f9273387.js => 31.c4152f8b.js} (99%) rename assets/js/{34.842dbe3a.js => 34.40447606.js} (99%) rename assets/js/{39.f8b5da6d.js => 39.3261ad3c.js} (88%) rename assets/js/{40.5f4c9ecf.js => 40.4ab0673d.js} (89%) rename assets/js/{41.017da959.js => 41.01e60973.js} (98%) rename assets/js/{42.c35335fc.js => 42.bf416f89.js} (91%) rename assets/js/{46.8a620891.js => 46.c88b1de0.js} (99%) rename assets/js/{47.1e361a05.js => 47.70dc63ea.js} (98%) rename assets/js/{48.6c8fd04b.js => 48.1c4bedef.js} (99%) rename assets/js/{49.5320af3f.js => 49.3295c4d3.js} (98%) rename assets/js/{50.b7380ea9.js => 50.cf7b9b4d.js} (86%) rename assets/js/{51.d80754c0.js => 51.8de4cf97.js} (99%) rename assets/js/{53.08f20b3c.js => 53.185fde0b.js} (99%) rename assets/js/{54.018c80a1.js => 54.c56c2eff.js} (99%) rename assets/js/{55.06a752f4.js => 55.fc6f0c87.js} (99%) rename assets/js/{58.b6598903.js => 58.10758a4f.js} (99%) rename assets/js/{59.9b9541ac.js => 59.1c408bd0.js} (99%) rename assets/js/{60.48c95147.js => 60.3b526e17.js} (99%) rename assets/js/{61.f6ea4853.js => 61.588e1148.js} (99%) rename assets/js/{65.a538fc82.js => 65.728ab52c.js} (99%) rename assets/js/{66.a99413d8.js => 66.6ebad210.js} (99%) rename assets/js/{69.c92f69ce.js => 69.3d319207.js} (99%) rename assets/js/{70.4663d7b0.js => 70.3bb83c63.js} (99%) rename assets/js/{71.2a8871be.js => 71.0e559a1c.js} (99%) rename assets/js/{72.d0343ad9.js => 72.1d7ffcda.js} (98%) rename assets/js/{73.a5e67ee7.js => 73.5decc786.js} (99%) rename assets/js/{78.f8907212.js => 78.4514085a.js} (99%) rename assets/js/{79.0f18b068.js => 79.61fe8f96.js} (99%) rename assets/js/{80.1e8a3836.js => 80.00db3e80.js} (98%) rename assets/js/{85.944e7baf.js => 85.bee02999.js} (96%) rename assets/js/{86.5eefdee5.js => 86.ac423664.js} (88%) rename assets/js/{94.bff8e7bd.js => 94.78a1ba7f.js} (98%) rename assets/js/{95.8216e261.js => 95.ef892223.js} (90%) rename assets/js/{96.1fc7dd90.js => 96.68e5ddd3.js} (96%) rename assets/js/{app.b7fe13ec.js => app.f3740f7e.js} (73%) diff --git a/404.html b/404.html index a6d560111b..a16d51f86e 100644 --- a/404.html +++ b/404.html @@ -15,7 +15,7 @@ - + @@ -39,7 +39,7 @@ Blog GitHub - (opens new window)

404 - Not Found

There's nothing here.
+ (opens new window)

404 - Not Found

How did we get here?
Take me home.
- + diff --git a/adoption/all/index.html b/adoption/all/index.html index 7732f33106..22edad91c9 100644 --- a/adoption/all/index.html +++ b/adoption/all/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/custodial/index.html b/adoption/custodial/index.html index e228c51b4d..be3906f51a 100644 --- a/adoption/custodial/index.html +++ b/adoption/custodial/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/desktop/index.html b/adoption/desktop/index.html index a13208b914..e1f78a8906 100644 --- a/adoption/desktop/index.html +++ b/adoption/desktop/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/exchange/index.html b/adoption/exchange/index.html index 0e791921b6..031cbb15f6 100644 --- a/adoption/exchange/index.html +++ b/adoption/exchange/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/hardware/index.html b/adoption/hardware/index.html index acfd5d8f5a..c4a6dcd57c 100644 --- a/adoption/hardware/index.html +++ b/adoption/hardware/index.html @@ -29,7 +29,7 @@ - + @@ -84,6 +84,6 @@
BDK Foundation
- + diff --git a/adoption/infrastructure/index.html b/adoption/infrastructure/index.html index a6fedd0cce..39b5ea10fb 100644 --- a/adoption/infrastructure/index.html +++ b/adoption/infrastructure/index.html @@ -29,7 +29,7 @@ - + @@ -78,6 +78,6 @@
BDK Foundation
- + diff --git a/adoption/mobile/index.html b/adoption/mobile/index.html index 68dc6907a9..f4aacac11e 100644 --- a/adoption/mobile/index.html +++ b/adoption/mobile/index.html @@ -29,7 +29,7 @@ - + @@ -84,6 +84,6 @@
BDK Foundation
- + diff --git a/adoption/web/index.html b/adoption/web/index.html index 9ac44a43a5..9860784c14 100644 --- a/adoption/web/index.html +++ b/adoption/web/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/assets/js/19.13924d29.js b/assets/js/19.fc7dec75.js similarity index 99% rename from assets/js/19.13924d29.js rename to assets/js/19.fc7dec75.js index 11c1b11ccc..06da6fc4fe 100644 --- a/assets/js/19.13924d29.js +++ b/assets/js/19.fc7dec75.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{354:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_complete_app.c74da859.png"},355:function(t,a,s){t.exports=s.p+"assets/img/default_flutter_app.31b31721.png"},356:function(t,a,s){t.exports=s.p+"assets/img/assets_section.b43d75e9.png"},357:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.b2750bd6.png"},358:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_title.e4e3484a.png"},359:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_mnemonic.df703b77.png"},360:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_createwallet.3b052736.png"},361:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_balance.bfdf9ced.png"},362:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_address.5db2e3cc.png"},363:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_restore.db8e7e55.png"},364:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_send.1688372b.png"},413:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-flutter")]),t._v(" is similar to using any other Flutter module. Just do "),a("code",[t._v("flutter pub add bdk_flutter")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-flutter")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. There will also be a "),a("strong",[a("code",[t._v("bdk-flutter")])]),t._v(" focused Livestream on "),a("a",{attrs:{href:"https://www.twitch.tv/bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitch"),a("OutboundLink")],1),t._v(" on the Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" so make sure to subscribe.")]),t._v(" "),a("p",[t._v("This tutorial will explore "),a("code",[t._v("bdk-flutter")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin concepts and "),a("code",[t._v("bdk-flutter")]),t._v(" API. So it will gloss over Flutter and Dart. If you are interested in learning more about Flutter and Dart please refer to the Flutter "),a("a",{attrs:{href:"https://flutter.dev/learn",target:"_blank",rel:"noopener noreferrer"}},[t._v("learning portal"),a("OutboundLink")],1),t._v(". The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(354)}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("To use "),a("code",[t._v("bdk-flutter")]),t._v(" in a Flutter App, a Flutter development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-flutter"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-flutter")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library for building Bitcoin apps in "),a("strong",[t._v("Flutter")]),t._v(".\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a Flutter context. To use BDK in Flutter apps only the "),a("code",[t._v("bdk-flutter")]),t._v(" module is required. "),a("code",[t._v("bdk-flutter")]),t._v(" can be used like any other Flutter library and is available on "),a("a",{attrs:{href:"https://pub.dev/packages/bdk_flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into Flutter we will focus more on bitcoin and "),a("code",[t._v("bdk-flutter")]),t._v(", however, some rudimentary Flutter setup is required, especially a basic Flutter app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new Flutter project.")]),t._v(" "),a("p",[a("code",[t._v("flutter create bdk-flutter-quickstart")])]),t._v(" "),a("p",[t._v("Once done let's "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic Flutter app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-flutter-quickstart\nflutter run\n")])])]),a("p",[t._v("This should start building the app and then launch the app in a simulator. So far we have created a basic Flutter project if this doesn't work then refer to the Flutter development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(355),alt:"BDK Flutter Quick Start"}}),t._v(" "),a("h2",{attrs:{id:"setting-up-flutter-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-flutter-app-structure"}},[t._v("#")]),t._v(" Setting up Flutter app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure. Let's create an "),a("code",[t._v("assets")]),t._v(" folder in the project root and then add new folders "),a("code",[t._v("widgets")]),t._v(", "),a("code",[t._v("screens")]),t._v(", and "),a("code",[t._v("styles")]),t._v(" inside the existing "),a("code",[t._v("lib")]),t._v(" folder.")]),t._v(" "),a("p",[t._v("Paste the following code in your "),a("code",[t._v("pubspec.yaml")]),t._v(" file, assets section.")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",[a("code",[t._v("- assets/\n")])])]),a("p",[t._v("Please make sure your assets section looks like the screenshot below.\n"),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"60%"},attrs:{src:s(356),alt:"BDK Flutter Quick Start"}})]),t._v(" "),a("p",[t._v("Once done let's run a "),a("code",[t._v("get")]),t._v(" command from the pub tool commands, this will get all the required dependencies for our project.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub get\n")])])]),a("p",[t._v("To make this quick you can download the theme, styled widgets and images used in the tutorial from the repository. The "),a("code",[t._v("theme.dart")]),t._v(" file has the theme we will use and this can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/styles/theme.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the styles folder. The "),a("code",[t._v("widgets.dart")]),t._v(" file has the styled widgets we will use and these can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/widgets/widgets.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the widgets folder. The image assets can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/tree/master/assets",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" Alternatively, you can write your theme, widgets and use your images if you intend to style the app differently.")]),t._v(" "),a("p",[t._v("In addition to the the theme, widgets and assets. We also need to create a "),a("code",[t._v("screens")]),t._v(" folder and create a "),a("code",[t._v("home.dart")]),t._v(" file inside it, this will be where most of the code will be added.")]),t._v(" "),a("p",[t._v("Once done the file structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"60%"},attrs:{src:s(357)}}),t._v(" "),a("p",[a("br"),t._v("Locate "),a("code",[t._v("main.dart")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("flutter create")]),t._v(", let's delete all contents of "),a("code",[t._v("main.dart")]),t._v(" and replace it with the following code to use "),a("code",[t._v("home.dart")]),t._v(" as our main screen. This will probably crash the app but that's fine, it will be up and running once we add code to "),a("code",[t._v("home.dart")]),t._v(" in the next few steps")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// main.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/screens/home.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/styles/theme.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("runApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatelessWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This widget is the root of your application.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MaterialApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n debugShowCheckedModeBanner"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n title"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'BDK-FLUTTER TUTORIAL'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n theme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"installing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-flutter"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("With the Flutter project in place, we can now add "),a("code",[t._v("bdk-flutter")]),t._v(" using "),a("code",[t._v("flutter pub add")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk_flutter\n")])])]),a("p",[t._v("This will add a line like this to your package's "),a("code",[t._v("pubspec.yaml")]),t._v(" and this will also run an implicit flutter pub get to download "),a("code",[t._v("bdk-flutter")]),t._v(" from "),a("code",[t._v("pub.dev")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("dependencies:\n bdk_flutter: ^0.28.2\n")])])]),a("h2",{attrs:{id:"configuring"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#configuring"}},[t._v("#")]),t._v(" Configuring")]),t._v(" "),a("p",[t._v("Make sure your app meets the following requirements for using "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[a("strong",[t._v("Android")])]),t._v(" "),a("p",[t._v("MinSdkVersion : API 23 or higher.")]),t._v(" "),a("p",[a("strong",[t._v("IOS")])]),t._v(" "),a("p",[t._v("Deployment target: iOS 12.0 or greater.")]),t._v(" "),a("p",[t._v("Locate your Podfile in the ios folder of your project and paste the following code at the beginning")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("platform :ios, '12.0'\n")])])]),a("p",[t._v("After changing the deployment target in your project's "),a("code",[t._v("PodFile")]),t._v(", let's use the following "),a("code",[t._v("command")]),t._v(" to install pod dependencies for iOS.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Once done, bdk-flutter is installed and configured and ready to be used in our "),a("strong",[t._v("bdk-flutter-quickstart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-flutter"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.dart")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-flutter")]),t._v(" at the top of the file. Create a stateful widget called "),a("code",[t._v("Home")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-flutter")]),t._v(" let's add some additional imports and also import styles, to create a basic layout to build our home screen")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/widgets/widgets.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/cupertino.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* AppBar */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(358)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-flutter-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-flutter-methods"}},[t._v("#")]),t._v(" Calling bdk-flutter methods")]),t._v(" "),a("p",[t._v("To call all methods properly from the "),a("code",[t._v("bdk-flutter")]),t._v(" package, first, we need to create state variables to store "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" objects.")]),t._v(" "),a("p",[t._v("Here we use the late keyword to declare both "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(". These are non-nullable variables that are initialized after the declaration.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" provides a "),a("code",[t._v("Mnemonic")]),t._v(" class to create a "),a("code",[t._v("Mnemonic")]),t._v(". The "),a("code",[t._v("create")]),t._v(" method is a named constructor and can be used to create a mnemonic, it takes "),a("code",[t._v("WordCount")]),t._v(" as its required parameter.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can generate a mnemonic of longer length by passing in a wordCount argument of required length.")]),t._v(" "),a("p",[t._v("To create a mnemonic with a "),a("code",[t._v("WordCount")]),t._v(" of 18 words, we can use "),a("code",[t._v("(WordCount.Words18)")]),t._v("\nRefer to the API docs on "),a("a",{attrs:{href:"https://pub.dev/documentation/bdk_flutter/latest/bdk_flutter/bdk_flutter-library.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words18")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here response is saved as a 'Mnemonic' object")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our Flutter app, we want a button that will generate a mnemonic when clicked, and a text input box to show the generated mnemonic. Let's first create a "),a("code",[t._v("TextEditingController")]),t._v(" for the "),a("code",[t._v("mnemonic")]),t._v(" textfield to store the mnemonic, and an internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method which can be called on button click. We will also need a button that will call the internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Generate Mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("multiline"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n maxLines"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter your mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction Buttons */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a "),a("code",[t._v("displayText")]),t._v(" variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnemonicHandler method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("/* Result */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"No Response"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v('We should now have a working "Generate Mnemonic" button that displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(359)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to call a click handler ("),a("code",[t._v("generateMnemonicHandler")]),t._v(") which calls "),a("code",[t._v("generateMnemonic")]),t._v(" API of "),a("code",[t._v("bdk-flutter")]),t._v(". The click handler also sets the state for the app and also updates the "),a("code",[t._v("displayText")]),t._v(" variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display component to display it. We will also be creating a receive address for the wallet so a state variable will be required for the address as well.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" state variables, let's add one for "),a("code",[t._v("balance")]),t._v(" and one for "),a("code",[t._v("address")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Just below "),a("code",[t._v("/* Balance */")]),t._v(" and above "),a("code",[t._v("/* Result */")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a null-aware operator "),a("code",[t._v("??")]),t._v(" for a quick "),a("code",[t._v("null")]),t._v(" check and use "),a("code",[t._v("0")]),t._v(" in case of a "),a("code",[t._v("null")]),t._v(" value.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BalanceContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"${balance ?? "')])]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"} Sats"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n")])])]),a("p",[a("code",[t._v("bdk_flutter")]),t._v(" creates a wallet using output descriptors which define the derivation path to derive addresses and sign transactions. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Before creating the "),a("code",[t._v("Wallet")]),t._v(" we need to create a "),a("code",[t._v("descriptor")]),t._v(" object which will be used to generate receive addresses and a "),a("code",[t._v("changeDescriptor")]),t._v(" object to to create change addresses to collect from outgoing transactions.")]),t._v(" "),a("p",[a("code",[t._v("bdk_flutter")]),t._v("'s "),a("code",[t._v("Descriptor")]),t._v(" class has a number of descriptor templates that will help you create a simple wallet.")]),t._v(" "),a("p",[t._v("Let's add some code to create a simple "),a("code",[t._v("wpkh")]),t._v(" descriptor object by using the "),a("code",[t._v("BIP84")]),t._v(" template. This template will create a descriptor in the format "),a("code",[t._v("wpkh(key/84'/{0,1}'/0'/{0,1}/*)")])]),t._v(" "),a("p",[t._v("This descriptor will create receive ("),a("code",[t._v("KeyChainKind.External")]),t._v(") and change descriptor ("),a("code",[t._v("KeyChainKind.Internal")]),t._v(") for a specified mnemonic.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" e "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.External")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.Internal")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" mnemonicObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptorSecretKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorSecretKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonicObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("newBip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n secretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptorSecretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n keychain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error : ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("rethrow")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Under the "),a("code",[t._v("address")]),t._v(" state variable, let's add a state variable called "),a("code",[t._v("wallet")]),t._v(" of the type "),a("code",[t._v("Wallet")]),t._v(" for saving the bitcoin wallet.")]),t._v(" "),a("p",[t._v("To create a wallet with "),a("code",[t._v("bdk-flutter")]),t._v(" call the "),a("code",[t._v("create")]),t._v(" constructor with "),a("code",[t._v("descriptor")]),t._v(", "),a("code",[t._v("changeDescriptor")]),t._v(" "),a("code",[t._v("network")]),t._v(", and the "),a("code",[t._v("databaseConfig")]),t._v(". For database, we can use memory as the database by specifying "),a("code",[t._v("DatabaseConfig.memory()")]),t._v("\nFollowing our pattern of a button, click handler and bdk-flutter API call, Let's add an internal method which will serve as the click handler for the \"Create Wallet\" button. We want to see the output of this call so let's use "),a("code",[t._v("setState()")]),t._v(" to set the "),a("code",[t._v("wallet")]),t._v(" object created and the "),a("code",[t._v("displayText")]),t._v(" variable with the wallet's first receive address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" password"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DatabaseConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("memory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" addressInfo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addressInfo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n wallet "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet Created: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("address")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to call "),a("code",[t._v("createOrRestoreWallet()")])]),t._v(" "),a("p",[t._v("Let's add a new button just below the mnemonic "),a("code",[t._v("TextFieldContainer")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Create Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("create()")]),t._v(" is a "),a("code",[t._v("Wallet")]),t._v(" object.")]),t._v(" "),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(360)}}),t._v(" "),a("p",[t._v("Before going forward, we need to create a "),a("code",[t._v("Blockchain")]),t._v(" object as well. The Blockchain object will encapsulate the bitcoin node configuration which the wallet will use for syncing blocks and broadcasting transactions.")]),t._v(" "),a("p",[t._v("Let's add an internal method to create and initialize the "),a("code",[t._v("Blockchain")]),t._v(" object.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("electrum")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n stopGap"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validateDomain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Here we are initializing the "),a("code",[t._v("late")]),t._v(" non-nullable "),a("code",[t._v("blockchain")]),t._v(" variable, by calling the named constructor "),a("code",[t._v("create")]),t._v(", which takes a "),a("code",[t._v("BlockchainConfig")]),t._v(" object.\nThe bitcoin node specified is an Electrum node and we are specifying the url for Blockstream's public Electrum Testnet servers over SSL.")]),t._v(" "),a("p",[t._v("After creating the "),a("code",[t._v("blockchainInit()")]),t._v(" method, call it from "),a("code",[t._v("createOrRestoreWallet()")]),t._v(", so the "),a("code",[t._v("blockchain")]),t._v(" variable gets initialized before the "),a("code",[t._v("wallet")]),t._v(" is created.")]),t._v(" "),a("p",[t._v("Include the following line of code inside "),a("code",[t._v("createOrRestoreWallet()")]),t._v(" just before calling Wallet.create().")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n")])])]),a("p",[a("strong",[t._v("blockChainConfig")]),t._v(": BlockchainConfig is an enum that has 3 values, "),a("code",[t._v("BlockchainConfig.electrum")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(" ,"),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(" and "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" .")]),t._v(" "),a("p",[a("code",[t._v("BlockchainConfig.electrum")]),t._v(", "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" & "),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" has "),a("code",[t._v("ElectrumConfig")]),t._v(" object, "),a("code",[t._v("RpcConfig")]),t._v(" object and "),a("code",[t._v("EsploraConfig")]),t._v(" object, respectively as its parameter.")]),t._v(" "),a("p",[a("strong",[t._v("ElectrumConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.electrum")]),t._v("'s config that takes a timeout, retry & url as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("EsploraConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.esplora")]),t._v("'s config that takes baseUrl & stopGap as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("RpcConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.rpc")]),t._v("'s config that takes url, network, & walletName as its required parameter. If "),a("code",[t._v("Rpc Blockchain")]),t._v(" has its authentication values inside a cookie file, please pass in cookie path as authCookie parameter, or you can pass in rpc username and password using "),a("code",[t._v("UserPass")]),t._v(" class.")]),t._v(" "),a("p",[t._v("Refer to the readme for a complete list of options for "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("createWallet()"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" created, we can now add methods to sync UTXOs and compute balance.")]),t._v(" "),a("p",[a("code",[t._v("Wallet")]),t._v(" has a "),a("code",[t._v("sync")]),t._v(" method to sync all UTXOs belonging to the wallet using the "),a("code",[t._v("Blockchain")]),t._v(" object. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have already added a variable for "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("sync")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button let's add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sync Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Balance"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("Let's add two internal functions for syncing UTXOs and compute balance.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" balanceObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Total Balance: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sync")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs, and get the balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(361)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's use the "),a("code",[t._v("address")]),t._v(" variable that was created before for this, we need to add a button for "),a("strong",[t._v("Get Address")]),t._v(" and an internal function to call "),a("code",[t._v("Wallet")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add a new "),a("code",[t._v("getNewAddress")]),t._v(" function below the "),a("code",[t._v("syncWallet()")]),t._v(" function:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("And a "),a("strong",[t._v("Get Address")]),t._v(" button below the existing "),a("strong",[t._v("Get Balance")]),t._v(" button:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Address"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and "),a("strong",[t._v("Get Address")]),t._v(" will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(362)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-a-wallet"}},[t._v("#")]),t._v(" Restoring a wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("create")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("This text field below the "),a("code",[t._v("Generate Mnemonic")]),t._v(" button will also display the mnemonic variable if we click Generate Mnemonic' button. The generated mnemonic will show up in the text field. We can overwrite it with our mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("We can now use our mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(363)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, now its time to add functionality to send a bitcoin transaction.")]),t._v(" "),a("p",[t._v("For making a successful bitcoin transaction "),a("code",[t._v("bdk-flutter")]),t._v(" utilizes a couple of methods. A new unsigned transaction can be created by using TxBuilder](https://github.com/LtbLightning/bdk-flutter#quicksend).")]),t._v(" "),a("p",[t._v("First, we have to initialize the "),a("code",[t._v("TxBuilder")]),t._v(" object and call the "),a("code",[t._v("addRecipient()")]),t._v(" method.\n"),a("code",[t._v("addRecipient()")]),t._v(" takes a "),a("code",[t._v("Script")]),t._v(" object and the transaction "),a("code",[t._v("amount")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create the"),a("code",[t._v("Script")]),t._v(" object by using the "),a("code",[t._v("Address")]),t._v(" class, by specifying the recipient address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create a "),a("code",[t._v("psbt")]),t._v(" object by calling the "),a("code",[t._v("finish()")]),t._v(" method using the response object from "),a("code",[t._v("addRecipient()")]),t._v(" method.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" psbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This "),a("code",[t._v("psbt")]),t._v(" can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#signtx",target:"_blank",rel:"noopener noreferrer"}},[t._v("sign()"),a("OutboundLink")],1),t._v(" method from the "),a("code",[t._v("Wallet")]),t._v(" and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#broadcasttx",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcast()"),a("OutboundLink")],1),t._v(" from the "),a("code",[t._v("Blockchain")]),t._v(" .")]),t._v(" "),a("p",[t._v("We will need textfield controllers for the recipient address, amount, and for transaction, these can be added below our existing variable for "),a("code",[t._v("mnemonic")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" recipientAddress "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" amount "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's make an internal function to send a bitcoin transaction, using "),a("code",[t._v("Wallet")]),t._v(", "),a("code",[t._v("Blockchain")]),t._v(" and "),a("code",[t._v("TxBuilder")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" int amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilderResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" sbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txBuilderResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" tx "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" sbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("extractTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Successfully broadcast ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("amount")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v(" Sats to ")]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("addressStr")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need a "),a("code",[t._v("form")]),t._v(", a "),a("code",[t._v("TextFormField")]),t._v(" for the receiver address and a "),a("code",[t._v("TextFormField")]),t._v(" for the amount to send. We will also need a button to call the "),a("code",[t._v("sendTx")]),t._v(" function.")]),t._v(" "),a("p",[t._v("Before submitting the form we need to make sure all the input fields are valid, for that purpose, we need to initialize a "),a("a",{attrs:{href:"https://api.flutter.dev/flutter/widgets/GlobalKey-class.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GlobalKey")]),a("OutboundLink")],1),t._v(". This can be added above our "),a("code",[t._v("Scaffold")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" _formKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GlobalKey")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FormState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("/* Send Transaction */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Form")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" _formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter your address'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Address"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter the amount'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("number"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Amount"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Send Bit"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("currentState"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("validate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n int"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(364)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-flutter")]),t._v(" allowing us to focus on the product, functionality, and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-flutter")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of APIs with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-flutter")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-flutter")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following us on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter-quickstart GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup Flutter Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{364:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_complete_app.c74da859.png"},365:function(t,a,s){t.exports=s.p+"assets/img/default_flutter_app.31b31721.png"},366:function(t,a,s){t.exports=s.p+"assets/img/assets_section.b43d75e9.png"},367:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.b2750bd6.png"},368:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_title.e4e3484a.png"},369:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_mnemonic.df703b77.png"},370:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_createwallet.3b052736.png"},371:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_balance.bfdf9ced.png"},372:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_address.5db2e3cc.png"},373:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_restore.db8e7e55.png"},374:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_send.1688372b.png"},415:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-flutter")]),t._v(" is similar to using any other Flutter module. Just do "),a("code",[t._v("flutter pub add bdk_flutter")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-flutter")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. There will also be a "),a("strong",[a("code",[t._v("bdk-flutter")])]),t._v(" focused Livestream on "),a("a",{attrs:{href:"https://www.twitch.tv/bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitch"),a("OutboundLink")],1),t._v(" on the Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" so make sure to subscribe.")]),t._v(" "),a("p",[t._v("This tutorial will explore "),a("code",[t._v("bdk-flutter")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin concepts and "),a("code",[t._v("bdk-flutter")]),t._v(" API. So it will gloss over Flutter and Dart. If you are interested in learning more about Flutter and Dart please refer to the Flutter "),a("a",{attrs:{href:"https://flutter.dev/learn",target:"_blank",rel:"noopener noreferrer"}},[t._v("learning portal"),a("OutboundLink")],1),t._v(". The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(364)}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("To use "),a("code",[t._v("bdk-flutter")]),t._v(" in a Flutter App, a Flutter development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-flutter"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-flutter")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library for building Bitcoin apps in "),a("strong",[t._v("Flutter")]),t._v(".\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a Flutter context. To use BDK in Flutter apps only the "),a("code",[t._v("bdk-flutter")]),t._v(" module is required. "),a("code",[t._v("bdk-flutter")]),t._v(" can be used like any other Flutter library and is available on "),a("a",{attrs:{href:"https://pub.dev/packages/bdk_flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into Flutter we will focus more on bitcoin and "),a("code",[t._v("bdk-flutter")]),t._v(", however, some rudimentary Flutter setup is required, especially a basic Flutter app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new Flutter project.")]),t._v(" "),a("p",[a("code",[t._v("flutter create bdk-flutter-quickstart")])]),t._v(" "),a("p",[t._v("Once done let's "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic Flutter app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-flutter-quickstart\nflutter run\n")])])]),a("p",[t._v("This should start building the app and then launch the app in a simulator. So far we have created a basic Flutter project if this doesn't work then refer to the Flutter development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(365),alt:"BDK Flutter Quick Start"}}),t._v(" "),a("h2",{attrs:{id:"setting-up-flutter-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-flutter-app-structure"}},[t._v("#")]),t._v(" Setting up Flutter app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure. Let's create an "),a("code",[t._v("assets")]),t._v(" folder in the project root and then add new folders "),a("code",[t._v("widgets")]),t._v(", "),a("code",[t._v("screens")]),t._v(", and "),a("code",[t._v("styles")]),t._v(" inside the existing "),a("code",[t._v("lib")]),t._v(" folder.")]),t._v(" "),a("p",[t._v("Paste the following code in your "),a("code",[t._v("pubspec.yaml")]),t._v(" file, assets section.")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",[a("code",[t._v("- assets/\n")])])]),a("p",[t._v("Please make sure your assets section looks like the screenshot below.\n"),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"60%"},attrs:{src:s(366),alt:"BDK Flutter Quick Start"}})]),t._v(" "),a("p",[t._v("Once done let's run a "),a("code",[t._v("get")]),t._v(" command from the pub tool commands, this will get all the required dependencies for our project.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub get\n")])])]),a("p",[t._v("To make this quick you can download the theme, styled widgets and images used in the tutorial from the repository. The "),a("code",[t._v("theme.dart")]),t._v(" file has the theme we will use and this can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/styles/theme.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the styles folder. The "),a("code",[t._v("widgets.dart")]),t._v(" file has the styled widgets we will use and these can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/widgets/widgets.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the widgets folder. The image assets can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/tree/master/assets",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" Alternatively, you can write your theme, widgets and use your images if you intend to style the app differently.")]),t._v(" "),a("p",[t._v("In addition to the the theme, widgets and assets. We also need to create a "),a("code",[t._v("screens")]),t._v(" folder and create a "),a("code",[t._v("home.dart")]),t._v(" file inside it, this will be where most of the code will be added.")]),t._v(" "),a("p",[t._v("Once done the file structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"60%"},attrs:{src:s(367)}}),t._v(" "),a("p",[a("br"),t._v("Locate "),a("code",[t._v("main.dart")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("flutter create")]),t._v(", let's delete all contents of "),a("code",[t._v("main.dart")]),t._v(" and replace it with the following code to use "),a("code",[t._v("home.dart")]),t._v(" as our main screen. This will probably crash the app but that's fine, it will be up and running once we add code to "),a("code",[t._v("home.dart")]),t._v(" in the next few steps")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// main.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/screens/home.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/styles/theme.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("runApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatelessWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This widget is the root of your application.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MaterialApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n debugShowCheckedModeBanner"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n title"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'BDK-FLUTTER TUTORIAL'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n theme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"installing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-flutter"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("With the Flutter project in place, we can now add "),a("code",[t._v("bdk-flutter")]),t._v(" using "),a("code",[t._v("flutter pub add")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk_flutter\n")])])]),a("p",[t._v("This will add a line like this to your package's "),a("code",[t._v("pubspec.yaml")]),t._v(" and this will also run an implicit flutter pub get to download "),a("code",[t._v("bdk-flutter")]),t._v(" from "),a("code",[t._v("pub.dev")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("dependencies:\n bdk_flutter: ^0.28.2\n")])])]),a("h2",{attrs:{id:"configuring"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#configuring"}},[t._v("#")]),t._v(" Configuring")]),t._v(" "),a("p",[t._v("Make sure your app meets the following requirements for using "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[a("strong",[t._v("Android")])]),t._v(" "),a("p",[t._v("MinSdkVersion : API 23 or higher.")]),t._v(" "),a("p",[a("strong",[t._v("IOS")])]),t._v(" "),a("p",[t._v("Deployment target: iOS 12.0 or greater.")]),t._v(" "),a("p",[t._v("Locate your Podfile in the ios folder of your project and paste the following code at the beginning")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("platform :ios, '12.0'\n")])])]),a("p",[t._v("After changing the deployment target in your project's "),a("code",[t._v("PodFile")]),t._v(", let's use the following "),a("code",[t._v("command")]),t._v(" to install pod dependencies for iOS.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Once done, bdk-flutter is installed and configured and ready to be used in our "),a("strong",[t._v("bdk-flutter-quickstart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-flutter"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.dart")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-flutter")]),t._v(" at the top of the file. Create a stateful widget called "),a("code",[t._v("Home")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-flutter")]),t._v(" let's add some additional imports and also import styles, to create a basic layout to build our home screen")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/widgets/widgets.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/cupertino.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* AppBar */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(368)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-flutter-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-flutter-methods"}},[t._v("#")]),t._v(" Calling bdk-flutter methods")]),t._v(" "),a("p",[t._v("To call all methods properly from the "),a("code",[t._v("bdk-flutter")]),t._v(" package, first, we need to create state variables to store "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" objects.")]),t._v(" "),a("p",[t._v("Here we use the late keyword to declare both "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(". These are non-nullable variables that are initialized after the declaration.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" provides a "),a("code",[t._v("Mnemonic")]),t._v(" class to create a "),a("code",[t._v("Mnemonic")]),t._v(". The "),a("code",[t._v("create")]),t._v(" method is a named constructor and can be used to create a mnemonic, it takes "),a("code",[t._v("WordCount")]),t._v(" as its required parameter.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can generate a mnemonic of longer length by passing in a wordCount argument of required length.")]),t._v(" "),a("p",[t._v("To create a mnemonic with a "),a("code",[t._v("WordCount")]),t._v(" of 18 words, we can use "),a("code",[t._v("(WordCount.Words18)")]),t._v("\nRefer to the API docs on "),a("a",{attrs:{href:"https://pub.dev/documentation/bdk_flutter/latest/bdk_flutter/bdk_flutter-library.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words18")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here response is saved as a 'Mnemonic' object")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our Flutter app, we want a button that will generate a mnemonic when clicked, and a text input box to show the generated mnemonic. Let's first create a "),a("code",[t._v("TextEditingController")]),t._v(" for the "),a("code",[t._v("mnemonic")]),t._v(" textfield to store the mnemonic, and an internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method which can be called on button click. We will also need a button that will call the internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Generate Mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("multiline"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n maxLines"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter your mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction Buttons */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a "),a("code",[t._v("displayText")]),t._v(" variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnemonicHandler method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("/* Result */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"No Response"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v('We should now have a working "Generate Mnemonic" button that displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(369)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to call a click handler ("),a("code",[t._v("generateMnemonicHandler")]),t._v(") which calls "),a("code",[t._v("generateMnemonic")]),t._v(" API of "),a("code",[t._v("bdk-flutter")]),t._v(". The click handler also sets the state for the app and also updates the "),a("code",[t._v("displayText")]),t._v(" variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display component to display it. We will also be creating a receive address for the wallet so a state variable will be required for the address as well.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" state variables, let's add one for "),a("code",[t._v("balance")]),t._v(" and one for "),a("code",[t._v("address")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Just below "),a("code",[t._v("/* Balance */")]),t._v(" and above "),a("code",[t._v("/* Result */")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a null-aware operator "),a("code",[t._v("??")]),t._v(" for a quick "),a("code",[t._v("null")]),t._v(" check and use "),a("code",[t._v("0")]),t._v(" in case of a "),a("code",[t._v("null")]),t._v(" value.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BalanceContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"${balance ?? "')])]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"} Sats"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n")])])]),a("p",[a("code",[t._v("bdk_flutter")]),t._v(" creates a wallet using output descriptors which define the derivation path to derive addresses and sign transactions. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Before creating the "),a("code",[t._v("Wallet")]),t._v(" we need to create a "),a("code",[t._v("descriptor")]),t._v(" object which will be used to generate receive addresses and a "),a("code",[t._v("changeDescriptor")]),t._v(" object to to create change addresses to collect from outgoing transactions.")]),t._v(" "),a("p",[a("code",[t._v("bdk_flutter")]),t._v("'s "),a("code",[t._v("Descriptor")]),t._v(" class has a number of descriptor templates that will help you create a simple wallet.")]),t._v(" "),a("p",[t._v("Let's add some code to create a simple "),a("code",[t._v("wpkh")]),t._v(" descriptor object by using the "),a("code",[t._v("BIP84")]),t._v(" template. This template will create a descriptor in the format "),a("code",[t._v("wpkh(key/84'/{0,1}'/0'/{0,1}/*)")])]),t._v(" "),a("p",[t._v("This descriptor will create receive ("),a("code",[t._v("KeyChainKind.External")]),t._v(") and change descriptor ("),a("code",[t._v("KeyChainKind.Internal")]),t._v(") for a specified mnemonic.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" e "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.External")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.Internal")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" mnemonicObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptorSecretKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorSecretKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonicObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("newBip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n secretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptorSecretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n keychain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error : ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("rethrow")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Under the "),a("code",[t._v("address")]),t._v(" state variable, let's add a state variable called "),a("code",[t._v("wallet")]),t._v(" of the type "),a("code",[t._v("Wallet")]),t._v(" for saving the bitcoin wallet.")]),t._v(" "),a("p",[t._v("To create a wallet with "),a("code",[t._v("bdk-flutter")]),t._v(" call the "),a("code",[t._v("create")]),t._v(" constructor with "),a("code",[t._v("descriptor")]),t._v(", "),a("code",[t._v("changeDescriptor")]),t._v(" "),a("code",[t._v("network")]),t._v(", and the "),a("code",[t._v("databaseConfig")]),t._v(". For database, we can use memory as the database by specifying "),a("code",[t._v("DatabaseConfig.memory()")]),t._v("\nFollowing our pattern of a button, click handler and bdk-flutter API call, Let's add an internal method which will serve as the click handler for the \"Create Wallet\" button. We want to see the output of this call so let's use "),a("code",[t._v("setState()")]),t._v(" to set the "),a("code",[t._v("wallet")]),t._v(" object created and the "),a("code",[t._v("displayText")]),t._v(" variable with the wallet's first receive address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" password"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DatabaseConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("memory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" addressInfo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addressInfo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n wallet "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet Created: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("address")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to call "),a("code",[t._v("createOrRestoreWallet()")])]),t._v(" "),a("p",[t._v("Let's add a new button just below the mnemonic "),a("code",[t._v("TextFieldContainer")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Create Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("create()")]),t._v(" is a "),a("code",[t._v("Wallet")]),t._v(" object.")]),t._v(" "),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(370)}}),t._v(" "),a("p",[t._v("Before going forward, we need to create a "),a("code",[t._v("Blockchain")]),t._v(" object as well. The Blockchain object will encapsulate the bitcoin node configuration which the wallet will use for syncing blocks and broadcasting transactions.")]),t._v(" "),a("p",[t._v("Let's add an internal method to create and initialize the "),a("code",[t._v("Blockchain")]),t._v(" object.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("electrum")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n stopGap"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validateDomain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Here we are initializing the "),a("code",[t._v("late")]),t._v(" non-nullable "),a("code",[t._v("blockchain")]),t._v(" variable, by calling the named constructor "),a("code",[t._v("create")]),t._v(", which takes a "),a("code",[t._v("BlockchainConfig")]),t._v(" object.\nThe bitcoin node specified is an Electrum node and we are specifying the url for Blockstream's public Electrum Testnet servers over SSL.")]),t._v(" "),a("p",[t._v("After creating the "),a("code",[t._v("blockchainInit()")]),t._v(" method, call it from "),a("code",[t._v("createOrRestoreWallet()")]),t._v(", so the "),a("code",[t._v("blockchain")]),t._v(" variable gets initialized before the "),a("code",[t._v("wallet")]),t._v(" is created.")]),t._v(" "),a("p",[t._v("Include the following line of code inside "),a("code",[t._v("createOrRestoreWallet()")]),t._v(" just before calling Wallet.create().")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n")])])]),a("p",[a("strong",[t._v("blockChainConfig")]),t._v(": BlockchainConfig is an enum that has 3 values, "),a("code",[t._v("BlockchainConfig.electrum")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(" ,"),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(" and "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" .")]),t._v(" "),a("p",[a("code",[t._v("BlockchainConfig.electrum")]),t._v(", "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" & "),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" has "),a("code",[t._v("ElectrumConfig")]),t._v(" object, "),a("code",[t._v("RpcConfig")]),t._v(" object and "),a("code",[t._v("EsploraConfig")]),t._v(" object, respectively as its parameter.")]),t._v(" "),a("p",[a("strong",[t._v("ElectrumConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.electrum")]),t._v("'s config that takes a timeout, retry & url as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("EsploraConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.esplora")]),t._v("'s config that takes baseUrl & stopGap as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("RpcConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.rpc")]),t._v("'s config that takes url, network, & walletName as its required parameter. If "),a("code",[t._v("Rpc Blockchain")]),t._v(" has its authentication values inside a cookie file, please pass in cookie path as authCookie parameter, or you can pass in rpc username and password using "),a("code",[t._v("UserPass")]),t._v(" class.")]),t._v(" "),a("p",[t._v("Refer to the readme for a complete list of options for "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("createWallet()"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" created, we can now add methods to sync UTXOs and compute balance.")]),t._v(" "),a("p",[a("code",[t._v("Wallet")]),t._v(" has a "),a("code",[t._v("sync")]),t._v(" method to sync all UTXOs belonging to the wallet using the "),a("code",[t._v("Blockchain")]),t._v(" object. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have already added a variable for "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("sync")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button let's add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sync Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Balance"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("Let's add two internal functions for syncing UTXOs and compute balance.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" balanceObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Total Balance: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sync")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs, and get the balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(371)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's use the "),a("code",[t._v("address")]),t._v(" variable that was created before for this, we need to add a button for "),a("strong",[t._v("Get Address")]),t._v(" and an internal function to call "),a("code",[t._v("Wallet")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add a new "),a("code",[t._v("getNewAddress")]),t._v(" function below the "),a("code",[t._v("syncWallet()")]),t._v(" function:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("And a "),a("strong",[t._v("Get Address")]),t._v(" button below the existing "),a("strong",[t._v("Get Balance")]),t._v(" button:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Address"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and "),a("strong",[t._v("Get Address")]),t._v(" will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(372)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-a-wallet"}},[t._v("#")]),t._v(" Restoring a wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("create")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("This text field below the "),a("code",[t._v("Generate Mnemonic")]),t._v(" button will also display the mnemonic variable if we click Generate Mnemonic' button. The generated mnemonic will show up in the text field. We can overwrite it with our mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("We can now use our mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(373)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, now its time to add functionality to send a bitcoin transaction.")]),t._v(" "),a("p",[t._v("For making a successful bitcoin transaction "),a("code",[t._v("bdk-flutter")]),t._v(" utilizes a couple of methods. A new unsigned transaction can be created by using TxBuilder](https://github.com/LtbLightning/bdk-flutter#quicksend).")]),t._v(" "),a("p",[t._v("First, we have to initialize the "),a("code",[t._v("TxBuilder")]),t._v(" object and call the "),a("code",[t._v("addRecipient()")]),t._v(" method.\n"),a("code",[t._v("addRecipient()")]),t._v(" takes a "),a("code",[t._v("Script")]),t._v(" object and the transaction "),a("code",[t._v("amount")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create the"),a("code",[t._v("Script")]),t._v(" object by using the "),a("code",[t._v("Address")]),t._v(" class, by specifying the recipient address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create a "),a("code",[t._v("psbt")]),t._v(" object by calling the "),a("code",[t._v("finish()")]),t._v(" method using the response object from "),a("code",[t._v("addRecipient()")]),t._v(" method.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" psbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This "),a("code",[t._v("psbt")]),t._v(" can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#signtx",target:"_blank",rel:"noopener noreferrer"}},[t._v("sign()"),a("OutboundLink")],1),t._v(" method from the "),a("code",[t._v("Wallet")]),t._v(" and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#broadcasttx",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcast()"),a("OutboundLink")],1),t._v(" from the "),a("code",[t._v("Blockchain")]),t._v(" .")]),t._v(" "),a("p",[t._v("We will need textfield controllers for the recipient address, amount, and for transaction, these can be added below our existing variable for "),a("code",[t._v("mnemonic")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" recipientAddress "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" amount "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's make an internal function to send a bitcoin transaction, using "),a("code",[t._v("Wallet")]),t._v(", "),a("code",[t._v("Blockchain")]),t._v(" and "),a("code",[t._v("TxBuilder")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" int amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilderResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" sbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txBuilderResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" tx "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" sbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("extractTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Successfully broadcast ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("amount")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v(" Sats to ")]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("addressStr")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need a "),a("code",[t._v("form")]),t._v(", a "),a("code",[t._v("TextFormField")]),t._v(" for the receiver address and a "),a("code",[t._v("TextFormField")]),t._v(" for the amount to send. We will also need a button to call the "),a("code",[t._v("sendTx")]),t._v(" function.")]),t._v(" "),a("p",[t._v("Before submitting the form we need to make sure all the input fields are valid, for that purpose, we need to initialize a "),a("a",{attrs:{href:"https://api.flutter.dev/flutter/widgets/GlobalKey-class.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GlobalKey")]),a("OutboundLink")],1),t._v(". This can be added above our "),a("code",[t._v("Scaffold")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" _formKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GlobalKey")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FormState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("/* Send Transaction */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Form")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" _formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter your address'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Address"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter the amount'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("number"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Amount"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Send Bit"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("currentState"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("validate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n int"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(374)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-flutter")]),t._v(" allowing us to focus on the product, functionality, and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-flutter")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of APIs with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-flutter")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-flutter")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following us on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter-quickstart GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup Flutter Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/21.87c145fc.js b/assets/js/21.d529cde5.js similarity index 98% rename from assets/js/21.87c145fc.js rename to assets/js/21.d529cde5.js index baa9ea683d..cbcf354749 100644 --- a/assets/js/21.87c145fc.js +++ b/assets/js/21.d529cde5.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{365:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_complete_app.e382f61c.png"},366:function(t,a,s){t.exports=s.p+"assets/img/default_rn_app.9e60b4fb.png"},367:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.d1c95bd6.png"},368:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_title.289f266d.png"},369:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_mnemonic.9963c418.png"},370:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_createwallet.916f2610.png"},371:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_balance.75af17bf.png"},372:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_address.4f570fb2.png"},373:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_restore.134b3681.png"},374:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_send.4e9dbc4a.png"},414:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("React Native")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-rn")]),t._v(" does not require knowledge of the underlying bitcoin or BDK API. Using "),a("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. Just do "),a("code",[t._v("yarn add bdk-rn")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-rn")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior?ref_src=twsrc%5Etfw",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. In case you missed it, there is a recorded "),a("code",[t._v("bdk-rn")]),t._v(" focused Twitch Livestream available on the "),a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers"),a("OutboundLink")],1),t._v(" YouTube channel which covers most of this article, make sure to subscribe to Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" for more bitcoin development videos.")]),t._v(" "),a("p",[t._v("In this tutorial, we will explore "),a("code",[t._v("bdk-rn")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin and "),a("code",[t._v("bdk-rn")]),t._v(" concepts and API. So it will gloss over React Native aspects. The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(365),alt:"BDK RN Quick Start"}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("In order to use "),a("code",[t._v("bdk-rn")]),t._v(" in a React Native App, a React Native development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-rn"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-rn")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is a React Native library of Bitcoin Dev Kit(BDK) for building React Native Apps.\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a react native context. To use BDK in React Native(RN) apps only the "),a("code",[t._v("bdk-rn")]),t._v(" module is required. "),a("code",[t._v("Bdk-rn")]),t._v(" can be used like any other react native library and is available on "),a("a",{attrs:{href:"https://www.npmjs.com/package/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("public package managers(npm and yarn)"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into RN we will focus more on bitcoin and bdk-rn, however, some rudimentary RN setup is required, especially a basic RN app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new RN project.")]),t._v(" "),a("p",[a("code",[t._v("npx react-native init BdkRnQuickStart")])]),t._v(" "),a("p",[t._v("If this fails in an error on an M1/M2 Mac please use\n"),a("code",[t._v("arch -x86_64 pod install --repo-update")])]),t._v(" "),a("p",[t._v("Once done "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic RN app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" BdkRnQuickStart\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" ios\n")])])]),a("p",[t._v("This should start building the app and launch the app in a simulator. So far we have created a basic RN project if this doesn't work then refer to the React Native development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(366)}}),t._v(" "),a("h2",{attrs:{id:"setting-up-styles-and-rn-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-styles-and-rn-app-structure"}},[t._v("#")]),t._v(" Setting up styles and RN app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure and some RN scaffolding. Let's create an "),a("code",[t._v("src")]),t._v(" folder in the project root and inside it add new folders for "),a("code",[t._v("assets")]),t._v(", "),a("code",[t._v("elements")]),t._v(", "),a("code",[t._v("screens")]),t._v(" and "),a("code",[t._v("styles")])]),t._v(" "),a("p",[t._v("To make this quick you can download the styles and images used in the tutorial from the repository. The image assets, "),a("code",[t._v("Button.tsx")]),t._v(" and "),a("code",[t._v("styles.js")]),t._v(" can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart/tree/master/src",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the folders as shown. Alternatively, you can write your own styles and use your own images if you intend to style the app in a different way.")]),t._v(" "),a("p",[t._v("Create a "),a("code",[t._v("home.js")]),t._v(" file under "),a("code",[t._v("screens")]),t._v(" folder, this will be where we will be adding most of the code.")]),t._v(" "),a("p",[t._v("Once done the project structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"67%"},attrs:{src:s(367)}}),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("App.js")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("react-native init")]),t._v(", let's delete all contents of "),a("code",[t._v("App.js")]),t._v(" and replace it with code to import "),a("code",[t._v("home.js")]),t._v(" as our main screen.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// App.js ")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Home "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./src/screens/home'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("App")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Home "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This will probably crash your app in the simulator but that's fine, it will be fixed in the next step.")]),t._v(" "),a("h2",{attrs:{id:"installing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-rn"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("With the RN app project in place, we can now add "),a("code",[t._v("bdk-rn")]),t._v(" using either npm or yarn.")]),t._v(" "),a("p",[t._v("Using npm:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--save")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("Using yarn:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("[iOS Only] Install pods:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("npx pod-install\nor\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Verify that "),a("code",[t._v("bdk-rn")]),t._v(" has been added to "),a("code",[t._v("package.json")]),t._v(", once done "),a("code",[t._v("bdk-rn")]),t._v(" is installed and ready to be used in our "),a("strong",[t._v("BdkRnQuickStart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-rn"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.js")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-rn")]),t._v(" and also create an RN functional component.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-rn")]),t._v(" let's add some additional RN component imports, as well as import styles, a button and image assets to create a basic layout to build our home screen.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Fragment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useState "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ActivityIndicator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SafeAreaView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ScrollView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n StatusBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n TextInput"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n View"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Image"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react-native'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Button "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../elements/Button'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" styles "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../styles/styles'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bitcoinLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bitcoin_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bdkLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bdk_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(368)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-rn-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-rn-methods"}},[t._v("#")]),t._v(" Calling "),a("code",[t._v("bdk-rn")]),t._v(" methods")]),t._v(" "),a("p",[t._v("All "),a("code",[t._v("bdk-rn")]),t._v(" methods return a JSON response with data and error properties. All methods return a response as follows:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("Promise"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Response"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("error")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// success returns true else false.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" string "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" object "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" any"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output data for the method call.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" provides "),a("code",[t._v("generateMnemonic()")]),t._v(" method to create a default 12 word length mnemonic.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can specify a longer length or we can also specify the bits of entropy we need by passing the length or entropy arguments.")]),t._v(" "),a("p",[t._v("To create a mnemonic with an entropy of 256 bits, which will be a 24-word length mnemonic sentence, we can use "),a("code",[t._v("{ entropy: 256 }")]),t._v(".\nRefer to the readme file on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#generatemnemomic",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("entropy")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("256")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here data is destructured and saved as 'mnemonic'")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our RN app let's create a state variable to store the mnemonic and internal "),a("code",[t._v("generateMnemonic")]),t._v(" method which we can invoke when a button is clicked. We will also need a button which will invoke generateMnemonic when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// state variable to store and set mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// internal method to call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// save generated mnemonic to state variable")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Generate Mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a state variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnenomic method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("{/* method call result */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n Response:\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v('We should now have a working" Generate Mnemonic" button which displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(369)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to trigger a call to a method. We created a button click event handler to call bdk-rn. Set the display state variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to bdk-rn.")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display section to display it.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" variables, let's add one for "),a("code",[t._v("balance")]),t._v(" as well")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And we will shortly need a "),a("code",[t._v("wallet")]),t._v(" and "),a("code",[t._v("syncResponse")]),t._v(" as well so add these too.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need some "),a("code",[t._v("jsx")]),t._v(" code to display the balance.")]),t._v(" "),a("p",[t._v("Just below "),a("code",[t._v("{/* Balance */}")]),t._v(" and above "),a("code",[t._v("{*/ method call result */}")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a tertiary operator for a quick check.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Balance: '")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(" Sats")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We will next add code to create a wallet.")]),t._v(" "),a("p",[t._v("To create a wallet the simple approach is to call "),a("code",[t._v("createWallet()")]),t._v(" method with "),a("code",[t._v("mnemonic")]),t._v(" , "),a("code",[t._v("password")]),t._v(" and "),a("code",[t._v("network")]),t._v(".\nLet's add another click event handler below where we have the "),a("code",[t._v("getMnemonic()")]),t._v(" method\nWe want to see the response to this call so let's use "),a("code",[t._v("setDisplayText()")]),t._v(" to see the output")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("createWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mnemonic")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("password")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to trigger "),a("code",[t._v("createWallet")])]),t._v(" "),a("p",[t._v("Let's add a new button just above "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Create Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("createWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("createWallet")]),t._v(" is a new address for the created wallet.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"data"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"address"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1qxg8g8cdzgs09cttu3y7lc33udqc4wsesunjnhe"')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"error"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(370)}}),t._v(" "),a("p",[t._v("The wallet created is a HD wallet and the address displayed is the 0 index address for the wallet. The path used by default is 84'/1'/0'/0/* for addresses and 84'/1'/0'/1/* for change.")]),t._v(" "),a("p",[t._v("As we specified "),a("code",[t._v("testnet")]),t._v(" and did not specify "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" a default testnet server will be used as the bitcoin node, "),a("code",[t._v("ssl://electrum.blockstream.info")]),t._v(" is the default url used for testnet.")]),t._v(" "),a("p",[t._v("Using "),a("code",[t._v("mnemonic")]),t._v(" is a quick way to create a new wallet with "),a("code",[t._v("bdk-rn")]),t._v(". The "),a("code",[t._v("createWallet()")]),t._v(" method in "),a("code",[t._v("bdk-rn")]),t._v(" has many optional arguments to configure the wallet. In addition to mnemonic, a wallet can also be created with a descriptor. If a descriptor is passed as an argument the wallet will be created using the descriptor. When using a descriptor, arguments for network, password and mnemonic are not required. "),a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("createDescriptor()")]),t._v(" method to create a descriptor. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Refer to the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createdescriptor",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for all options available when creating output descriptors with "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using a descriptor to create wallet ")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("descriptor")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tprv8ZgxMBicQKsPd3G66kPkZEuJZgUK9QXJRYCwnCtYLJjEZmw8xFjCxGoyx533AL83XFcSQeuVmVeJbZai5RTBxDp71Abd2FPSyQumRL79BKw'")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Other arguments for "),a("code",[t._v("createWallet()")]),t._v(" are:")]),t._v(" "),a("p",[a("strong",[t._v("blockChainName")]),t._v(": Blockchain backend to use, like "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(", "),a("code",[t._v("compact-filters")]),t._v(" ("),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP157"),a("OutboundLink")],1),t._v(") and Bitcoin Core. "),a("code",[t._v("bdk-rn")]),t._v(" at the moment doesn't support compact-filters and Bitcoin Core, this will be added shortly in a future release.")]),t._v(" "),a("p",[a("strong",[t._v("blockChainConfigUrl")]),t._v(": This is the url of the specified bitcoin node this should match the chain and the type of blockchain specified as "),a("strong",[t._v("blockChainName")])]),t._v(" "),a("p",[t._v("Refer to "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for a complete list of options for "),a("code",[t._v("createWallet")])]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the wallet created, we can now add methods to sync UTXOs compute balance.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("syncWallet")]),t._v(" method to sync all UTXOs belonging to the wallet with the bitcoin network, the specified "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" is used to sync. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have aleady added state variables for"),a("code",[t._v("syncResponse")]),t._v("and "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("syncWallet")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button lets add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Sync Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("syncWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("And two click handlers below createWallet:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("syncWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSyncResponse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getBalance")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs and get balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(371)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's add a state variable for "),a("code",[t._v("address")]),t._v(", a button for "),a("strong",[t._v("Get Address")]),t._v(" and a click event handler to call "),a("code",[t._v("bdk-rn")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add "),a("code",[t._v("address")]),t._v(" and "),a("code",[t._v("setAddress")]),t._v(" state variables below balance and "),a("code",[t._v("setBalance")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new "),a("code",[t._v("getAddress")]),t._v(" click event handler below "),a("code",[t._v("getBalance")]),t._v(" click event handler:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getAddress")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And a Get Address button below the existing Get Balance button:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and Get Address will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(372)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-wallet"}},[t._v("#")]),t._v(" Restoring wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("createWallet")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", in order to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("Let's add an input box to enter our own "),a("code",[t._v("mnemonic")]),t._v(", we will use the "),a("code",[t._v("mnemonic")]),t._v(" entered in the input box to create a wallet.")]),t._v(" "),a("p",[t._v("Let's add an input box for "),a("code",[t._v("mnemonic")]),t._v(" below the Generate Mnemonic button.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("multiline")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("textAlignVertical")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("top"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("This code will also display the mnemonic state variable in the input box, if we click Generate Mnemonic the generated mnemonic will show up in the input box. We can overwrite it with our own mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("we are already using the mnemonic state variable in the "),a("code",[t._v("createWallet")]),t._v(" Method so no other changes are required.")]),t._v(" "),a("p",[t._v("We can now use our own mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(373)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, time to add functionality to send as well.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a number of transaction-related methods to enable varied use cases. A new send transaction can be created and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[t._v("quickSend()"),a("OutboundLink")],1),t._v(". If required an unsigned transaction can be created using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("createTransaction()"),a("OutboundLink")],1),t._v(" , this can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#signtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("signTransactioin()"),a("OutboundLink")],1),t._v(" method and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#broadcasttransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcastTransaction()"),a("OutboundLink")],1),t._v(". There are also methods to query transactions by pending or confirmed status and all transactions. Please refer to "),a("code",[t._v("bdk-rn")]),t._v(" "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn/blob/main/README.md#gettransactions",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for more details on all the methods.")]),t._v(" "),a("p",[t._v("We will need state variables for recipient address and amount as well as for transaction, these can be added below our existing variables for syncResponse and address")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setTransaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAmount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A click event handler for send button, we will use the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("quickSend()")]),a("OutboundLink")],1),t._v(" method to send specified amount in sats to address.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("sendTx")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("quickSend")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("address")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("amount")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setTransaction")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need an input box for the receiver address and an input box for the amount to send. We will also need a button to trigger the transaction.")]),t._v(" "),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sendSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Fragment")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Recipient Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Amount (in sats)"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAmount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parseInt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Send Transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("sendTx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(374)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-rn")]),t._v(" allowing us to focus on the product, functionality and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-rn")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of API with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-rn")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-rn")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of bdk-rn.")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-rn"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers YouTube"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("BdkRnQuickStart App GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup React Native Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{354:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_complete_app.e382f61c.png"},355:function(t,a,s){t.exports=s.p+"assets/img/default_rn_app.9e60b4fb.png"},356:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.d1c95bd6.png"},357:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_title.289f266d.png"},358:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_mnemonic.9963c418.png"},359:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_createwallet.916f2610.png"},360:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_balance.75af17bf.png"},361:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_address.4f570fb2.png"},362:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_restore.134b3681.png"},363:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_send.4e9dbc4a.png"},414:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("React Native")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-rn")]),t._v(" does not require knowledge of the underlying bitcoin or BDK API. Using "),a("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. Just do "),a("code",[t._v("yarn add bdk-rn")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-rn")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior?ref_src=twsrc%5Etfw",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. In case you missed it, there is a recorded "),a("code",[t._v("bdk-rn")]),t._v(" focused Twitch Livestream available on the "),a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers"),a("OutboundLink")],1),t._v(" YouTube channel which covers most of this article, make sure to subscribe to Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" for more bitcoin development videos.")]),t._v(" "),a("p",[t._v("In this tutorial, we will explore "),a("code",[t._v("bdk-rn")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin and "),a("code",[t._v("bdk-rn")]),t._v(" concepts and API. So it will gloss over React Native aspects. The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(354),alt:"BDK RN Quick Start"}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("In order to use "),a("code",[t._v("bdk-rn")]),t._v(" in a React Native App, a React Native development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-rn"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-rn")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is a React Native library of Bitcoin Dev Kit(BDK) for building React Native Apps.\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a react native context. To use BDK in React Native(RN) apps only the "),a("code",[t._v("bdk-rn")]),t._v(" module is required. "),a("code",[t._v("Bdk-rn")]),t._v(" can be used like any other react native library and is available on "),a("a",{attrs:{href:"https://www.npmjs.com/package/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("public package managers(npm and yarn)"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into RN we will focus more on bitcoin and bdk-rn, however, some rudimentary RN setup is required, especially a basic RN app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new RN project.")]),t._v(" "),a("p",[a("code",[t._v("npx react-native init BdkRnQuickStart")])]),t._v(" "),a("p",[t._v("If this fails in an error on an M1/M2 Mac please use\n"),a("code",[t._v("arch -x86_64 pod install --repo-update")])]),t._v(" "),a("p",[t._v("Once done "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic RN app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" BdkRnQuickStart\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" ios\n")])])]),a("p",[t._v("This should start building the app and launch the app in a simulator. So far we have created a basic RN project if this doesn't work then refer to the React Native development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(355)}}),t._v(" "),a("h2",{attrs:{id:"setting-up-styles-and-rn-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-styles-and-rn-app-structure"}},[t._v("#")]),t._v(" Setting up styles and RN app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure and some RN scaffolding. Let's create an "),a("code",[t._v("src")]),t._v(" folder in the project root and inside it add new folders for "),a("code",[t._v("assets")]),t._v(", "),a("code",[t._v("elements")]),t._v(", "),a("code",[t._v("screens")]),t._v(" and "),a("code",[t._v("styles")])]),t._v(" "),a("p",[t._v("To make this quick you can download the styles and images used in the tutorial from the repository. The image assets, "),a("code",[t._v("Button.tsx")]),t._v(" and "),a("code",[t._v("styles.js")]),t._v(" can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart/tree/master/src",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the folders as shown. Alternatively, you can write your own styles and use your own images if you intend to style the app in a different way.")]),t._v(" "),a("p",[t._v("Create a "),a("code",[t._v("home.js")]),t._v(" file under "),a("code",[t._v("screens")]),t._v(" folder, this will be where we will be adding most of the code.")]),t._v(" "),a("p",[t._v("Once done the project structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"67%"},attrs:{src:s(356)}}),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("App.js")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("react-native init")]),t._v(", let's delete all contents of "),a("code",[t._v("App.js")]),t._v(" and replace it with code to import "),a("code",[t._v("home.js")]),t._v(" as our main screen.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// App.js ")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Home "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./src/screens/home'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("App")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Home "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This will probably crash your app in the simulator but that's fine, it will be fixed in the next step.")]),t._v(" "),a("h2",{attrs:{id:"installing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-rn"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("With the RN app project in place, we can now add "),a("code",[t._v("bdk-rn")]),t._v(" using either npm or yarn.")]),t._v(" "),a("p",[t._v("Using npm:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--save")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("Using yarn:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("[iOS Only] Install pods:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("npx pod-install\nor\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Verify that "),a("code",[t._v("bdk-rn")]),t._v(" has been added to "),a("code",[t._v("package.json")]),t._v(", once done "),a("code",[t._v("bdk-rn")]),t._v(" is installed and ready to be used in our "),a("strong",[t._v("BdkRnQuickStart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-rn"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.js")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-rn")]),t._v(" and also create an RN functional component.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-rn")]),t._v(" let's add some additional RN component imports, as well as import styles, a button and image assets to create a basic layout to build our home screen.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Fragment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useState "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ActivityIndicator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SafeAreaView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ScrollView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n StatusBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n TextInput"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n View"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Image"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react-native'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Button "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../elements/Button'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" styles "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../styles/styles'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bitcoinLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bitcoin_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bdkLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bdk_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(357)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-rn-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-rn-methods"}},[t._v("#")]),t._v(" Calling "),a("code",[t._v("bdk-rn")]),t._v(" methods")]),t._v(" "),a("p",[t._v("All "),a("code",[t._v("bdk-rn")]),t._v(" methods return a JSON response with data and error properties. All methods return a response as follows:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("Promise"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Response"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("error")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// success returns true else false.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" string "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" object "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" any"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output data for the method call.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" provides "),a("code",[t._v("generateMnemonic()")]),t._v(" method to create a default 12 word length mnemonic.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can specify a longer length or we can also specify the bits of entropy we need by passing the length or entropy arguments.")]),t._v(" "),a("p",[t._v("To create a mnemonic with an entropy of 256 bits, which will be a 24-word length mnemonic sentence, we can use "),a("code",[t._v("{ entropy: 256 }")]),t._v(".\nRefer to the readme file on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#generatemnemomic",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("entropy")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("256")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here data is destructured and saved as 'mnemonic'")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our RN app let's create a state variable to store the mnemonic and internal "),a("code",[t._v("generateMnemonic")]),t._v(" method which we can invoke when a button is clicked. We will also need a button which will invoke generateMnemonic when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// state variable to store and set mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// internal method to call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// save generated mnemonic to state variable")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Generate Mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a state variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnenomic method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("{/* method call result */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n Response:\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v('We should now have a working" Generate Mnemonic" button which displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(358)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to trigger a call to a method. We created a button click event handler to call bdk-rn. Set the display state variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to bdk-rn.")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display section to display it.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" variables, let's add one for "),a("code",[t._v("balance")]),t._v(" as well")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And we will shortly need a "),a("code",[t._v("wallet")]),t._v(" and "),a("code",[t._v("syncResponse")]),t._v(" as well so add these too.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need some "),a("code",[t._v("jsx")]),t._v(" code to display the balance.")]),t._v(" "),a("p",[t._v("Just below "),a("code",[t._v("{/* Balance */}")]),t._v(" and above "),a("code",[t._v("{*/ method call result */}")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a tertiary operator for a quick check.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Balance: '")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(" Sats")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We will next add code to create a wallet.")]),t._v(" "),a("p",[t._v("To create a wallet the simple approach is to call "),a("code",[t._v("createWallet()")]),t._v(" method with "),a("code",[t._v("mnemonic")]),t._v(" , "),a("code",[t._v("password")]),t._v(" and "),a("code",[t._v("network")]),t._v(".\nLet's add another click event handler below where we have the "),a("code",[t._v("getMnemonic()")]),t._v(" method\nWe want to see the response to this call so let's use "),a("code",[t._v("setDisplayText()")]),t._v(" to see the output")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("createWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mnemonic")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("password")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to trigger "),a("code",[t._v("createWallet")])]),t._v(" "),a("p",[t._v("Let's add a new button just above "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Create Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("createWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("createWallet")]),t._v(" is a new address for the created wallet.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"data"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"address"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1qxg8g8cdzgs09cttu3y7lc33udqc4wsesunjnhe"')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"error"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(359)}}),t._v(" "),a("p",[t._v("The wallet created is a HD wallet and the address displayed is the 0 index address for the wallet. The path used by default is 84'/1'/0'/0/* for addresses and 84'/1'/0'/1/* for change.")]),t._v(" "),a("p",[t._v("As we specified "),a("code",[t._v("testnet")]),t._v(" and did not specify "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" a default testnet server will be used as the bitcoin node, "),a("code",[t._v("ssl://electrum.blockstream.info")]),t._v(" is the default url used for testnet.")]),t._v(" "),a("p",[t._v("Using "),a("code",[t._v("mnemonic")]),t._v(" is a quick way to create a new wallet with "),a("code",[t._v("bdk-rn")]),t._v(". The "),a("code",[t._v("createWallet()")]),t._v(" method in "),a("code",[t._v("bdk-rn")]),t._v(" has many optional arguments to configure the wallet. In addition to mnemonic, a wallet can also be created with a descriptor. If a descriptor is passed as an argument the wallet will be created using the descriptor. When using a descriptor, arguments for network, password and mnemonic are not required. "),a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("createDescriptor()")]),t._v(" method to create a descriptor. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Refer to the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createdescriptor",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for all options available when creating output descriptors with "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using a descriptor to create wallet ")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("descriptor")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tprv8ZgxMBicQKsPd3G66kPkZEuJZgUK9QXJRYCwnCtYLJjEZmw8xFjCxGoyx533AL83XFcSQeuVmVeJbZai5RTBxDp71Abd2FPSyQumRL79BKw'")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Other arguments for "),a("code",[t._v("createWallet()")]),t._v(" are:")]),t._v(" "),a("p",[a("strong",[t._v("blockChainName")]),t._v(": Blockchain backend to use, like "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(", "),a("code",[t._v("compact-filters")]),t._v(" ("),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP157"),a("OutboundLink")],1),t._v(") and Bitcoin Core. "),a("code",[t._v("bdk-rn")]),t._v(" at the moment doesn't support compact-filters and Bitcoin Core, this will be added shortly in a future release.")]),t._v(" "),a("p",[a("strong",[t._v("blockChainConfigUrl")]),t._v(": This is the url of the specified bitcoin node this should match the chain and the type of blockchain specified as "),a("strong",[t._v("blockChainName")])]),t._v(" "),a("p",[t._v("Refer to "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for a complete list of options for "),a("code",[t._v("createWallet")])]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the wallet created, we can now add methods to sync UTXOs compute balance.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("syncWallet")]),t._v(" method to sync all UTXOs belonging to the wallet with the bitcoin network, the specified "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" is used to sync. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have aleady added state variables for"),a("code",[t._v("syncResponse")]),t._v("and "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("syncWallet")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button lets add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Sync Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("syncWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("And two click handlers below createWallet:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("syncWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSyncResponse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getBalance")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs and get balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(360)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's add a state variable for "),a("code",[t._v("address")]),t._v(", a button for "),a("strong",[t._v("Get Address")]),t._v(" and a click event handler to call "),a("code",[t._v("bdk-rn")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add "),a("code",[t._v("address")]),t._v(" and "),a("code",[t._v("setAddress")]),t._v(" state variables below balance and "),a("code",[t._v("setBalance")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new "),a("code",[t._v("getAddress")]),t._v(" click event handler below "),a("code",[t._v("getBalance")]),t._v(" click event handler:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getAddress")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And a Get Address button below the existing Get Balance button:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and Get Address will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(361)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-wallet"}},[t._v("#")]),t._v(" Restoring wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("createWallet")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", in order to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("Let's add an input box to enter our own "),a("code",[t._v("mnemonic")]),t._v(", we will use the "),a("code",[t._v("mnemonic")]),t._v(" entered in the input box to create a wallet.")]),t._v(" "),a("p",[t._v("Let's add an input box for "),a("code",[t._v("mnemonic")]),t._v(" below the Generate Mnemonic button.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("multiline")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("textAlignVertical")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("top"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("This code will also display the mnemonic state variable in the input box, if we click Generate Mnemonic the generated mnemonic will show up in the input box. We can overwrite it with our own mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("we are already using the mnemonic state variable in the "),a("code",[t._v("createWallet")]),t._v(" Method so no other changes are required.")]),t._v(" "),a("p",[t._v("We can now use our own mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(362)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, time to add functionality to send as well.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a number of transaction-related methods to enable varied use cases. A new send transaction can be created and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[t._v("quickSend()"),a("OutboundLink")],1),t._v(". If required an unsigned transaction can be created using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("createTransaction()"),a("OutboundLink")],1),t._v(" , this can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#signtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("signTransactioin()"),a("OutboundLink")],1),t._v(" method and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#broadcasttransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcastTransaction()"),a("OutboundLink")],1),t._v(". There are also methods to query transactions by pending or confirmed status and all transactions. Please refer to "),a("code",[t._v("bdk-rn")]),t._v(" "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn/blob/main/README.md#gettransactions",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for more details on all the methods.")]),t._v(" "),a("p",[t._v("We will need state variables for recipient address and amount as well as for transaction, these can be added below our existing variables for syncResponse and address")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setTransaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAmount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A click event handler for send button, we will use the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("quickSend()")]),a("OutboundLink")],1),t._v(" method to send specified amount in sats to address.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("sendTx")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("quickSend")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("address")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("amount")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setTransaction")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need an input box for the receiver address and an input box for the amount to send. We will also need a button to trigger the transaction.")]),t._v(" "),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sendSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Fragment")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Recipient Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Amount (in sats)"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAmount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parseInt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Send Transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("sendTx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(363)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-rn")]),t._v(" allowing us to focus on the product, functionality and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-rn")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of API with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-rn")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-rn")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of bdk-rn.")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-rn"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers YouTube"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("BdkRnQuickStart App GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup React Native Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/31.f9273387.js b/assets/js/31.c4152f8b.js similarity index 99% rename from assets/js/31.f9273387.js rename to assets/js/31.c4152f8b.js index e3754cc85c..7cee13e4c2 100644 --- a/assets/js/31.f9273387.js +++ b/assets/js/31.c4152f8b.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{351:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN-Architecture.42fbc351.png"},352:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN.370f20c3.png"},353:function(t,e,a){t.exports=a.p+"assets/img/android_folder.0ff999be.png"},407:function(t,e,a){"use strict";a.r(e);var n=a(7),s=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("The "),e("strong",[t._v("BitcoinDevkit")]),t._v("'s "),e("strong",[t._v("React Native")]),t._v(" library ("),e("code",[t._v("bdk-rn")]),t._v(") makes it easy to develop bitcoin applications for both Android and iOS mobile platforms. Using "),e("code",[t._v("bdk-rn")]),t._v(", knowledge of the underlying bitcoin and BDK API is not required and using "),e("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. The goal is "),e("strong",[t._v("Rapid Bitcoin Application Development")]),t._v(" by doing the heavy lifting in advance and providing a reusable library for other developers to use. Developers simply install using "),e("code",[t._v("yarn add")]),t._v(" and start using it in a React Native Project. The native code, Rust lang implementation, configuration and other setup details are all taken care of by "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("p",[t._v("This article is "),e("strong",[t._v("NOT a guide on how to use bdk-rn")]),t._v(" to build a bitcoin application, rather this is an insight into how "),e("code",[t._v("bdk-rn")]),t._v(" was developed. For help on how to use "),e("code",[t._v("bdk-rn")]),t._v(" to develop a bitcoin wallet or application please refer to the user guide in the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),e("OutboundLink")],1),t._v(" on Github. There will be "),e("code",[t._v("how to guides")]),t._v(" published shortly on getting started with "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"react-native-architecture"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#react-native-architecture"}},[t._v("#")]),t._v(" React Native Architecture")]),t._v(" "),e("p",[t._v("At a high level, RN consists of the UI front which is essentially JavaScript which interacts with the native iOS and Android platforms over a bridge. When communicating over the bridge values from JS are converted to native and vice versa.")]),t._v(" "),e("p",[t._v("The native part of RN consists of Android as well as iOS modules and components. The Android and iOS sections are full fledged native projects which interact with the JS side over the native bridge. A RN project has all the build configuraiton required to build both Android and iOS projects.")]),t._v(" "),e("p",[t._v("For the purpose of making "),e("code",[t._v("bdk-rn")]),t._v(", "),e("code",[t._v("bdk-kotlin")]),t._v(" is used as the native Android module and "),e("code",[t._v("bdk-swift")]),t._v(" as the native iOS module. These are configured and wrapped in a RN Project as part of the platform specific native modules within the RN Project. This RN Project is then built to be a reusable React Native module.")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(351),alt:""}})]),t._v(" "),e("h2",{attrs:{id:"native-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#native-integration"}},[t._v("#")]),t._v(" Native Integration")]),t._v(" "),e("p",[t._v("In order to communicate to native modules on Android and iOS, React Native provides React Context API for Java/Kotlin as well as Swift. React Context API are used to build the interface to the native bridge allowing communication from JS to native modules.")]),t._v(" "),e("p",[t._v("bdk-rn uses React Context API plus some native code to wrap and enhance bdk-kotlin and bdk-swift APIs. The native code calls and interacts with the Android and iOS native modules which interface with the underlying mobile platform.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"20%"},attrs:{src:a(352)}}),t._v(" "),e("h2",{attrs:{id:"android-module"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#android-module"}},[t._v("#")]),t._v(" Android Module")]),t._v(" "),e("p",[t._v("We will go into the details of how the BDK Android Module is integrated, we wont cover iOS.")]),t._v(" "),e("p",[t._v("Starting off with a basic RN project. This project will be enhanced with bdk-kotlin and bdk-swift binaries and native code. For now lets go into the details for Android, iOS has similar steps to be done in Swift.")]),t._v(" "),e("p",[t._v("The Android native project is located under the root project folder.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"120%"},attrs:{src:a(353)}}),t._v(" "),e("p",[t._v("Here we need to add a dependency in "),e("code",[t._v("build.gradle")]),t._v(" for bdk-kotlin's android native binary. This will enable bdk-kotlin to be downloaded and available as one of the native modules.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: build.gradle")]),t._v("\n\nrepositories "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mavenCentral")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ndependencies "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//noinspection GradleDynamicVersion")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'com.facebook.react:react-native:+'")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// bitcoindevkit")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'org.bitcoindevkit:bdk-android:0.7.1'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We will create an Android native module which will interact with "),e("code",[t._v("bdk-android")]),t._v(".\nThis is done by adding a new Kotlin file "),e("code",[t._v("BdkRnModule.kt")]),t._v(" inside "),e("code",[t._v("android/app/src/main/java/com/bdkrn/")]),t._v(" folder")]),t._v(" "),e("p",[t._v("This will be part of the native code for bdk-rn module.Here a new class will be created to encapsulate the interaction with bitcoindevkit's android native binary.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SuppressLint\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Log\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Arguments\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Promise "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Result\n")])])]),e("p",[e("code",[t._v("org.bitcoindevkit")]),t._v(" will also need to be imported here")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bitcoindevkit"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Wallet "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" BdkWallet\n")])])]),e("p",[t._v("To use React Context API "),e("code",[t._v("com.facebook.react.bridge.*")]),t._v(" also needs to be imported")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("\n")])])]),e("p",[t._v("A new class needs to be defined here which will implement the React Context API")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\t"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ReactContextBaseJavaModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getName")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BdkRnModule"')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("With the base imports and class defined, we can start writing methods.\nThis will demonstrate how bdk native module will be called and how values will be returned to JS over the native bridge")]),t._v(" "),e("p",[t._v("Lets create a method that can be called from JaveScript, to do so we use the "),e("code",[t._v("@ReactMethod")]),t._v(" directive which is part of the React Context API. This will expose the method so that it can be called from JavaScript.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We need one more file to complete our native framework. A new Kotlin file, "),e("code",[t._v("BdkRnPackage.kt")]),t._v(" is required to package all our native code into a new android module, here we specify the name of the file we just crated as the module name("),e("code",[t._v("BdkRnModule")]),t._v("). This can be done by adding the following code:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnPackage.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactPackage\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("NativeModule\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactApplicationContext\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("uimanager"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ViewManager\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" BdkRnPackage "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactPackage "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNativeModules")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n MutableList"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("NativeModule"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutableListOf")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),e("p",[t._v("Now lets add code for creating a wallet in BdkRnModule.kt")]),t._v(" "),e("p",[t._v("The methods used here are for bdk-kotlin and available in the bdk-kotlin documentation.")]),t._v(" "),e("p",[t._v("We first create a key info object")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create key info with a new mnemonic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ExtendedKeyInfo "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateExtendedKey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n WordCount"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WORDS12"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n \n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// more code to follow...")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create descriptor and change descriptor")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create databaseConfig and blockchainconfig")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create wallet")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Then key info used to create a wallet descriptor and change descriptor:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" descriptor"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')])]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(' "'),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("84")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*)\"\n\nval changeDescriptor: String = descriptor.replace(\"/84'/1'/0'/0/*\",\"/84'/1'/0'/1/*\")\n")])])])]),e("p",[t._v("To create a wallet with bdk we need to specify wallet descriptor, network, a database config, blockchain config. We intend to use bitcoin testnet and want to use default memory for data. For bitcoin node we will use a public electrum server. We will need to define these parameters to create a wallet.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" network "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" `Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET`\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" databaseConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DatabaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Memory\nblockchainConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n BlockchainConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Electrum")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ElectrumConfig")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 5u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 10u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once done we can use these parameters to create a BDK wallet using the native android BDK library:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BdkWallet "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetwork")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n config\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once we have a wallet initialised, we can call methods on it to sync, generate a new address and to get balance")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[t._v("wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ProgressLog"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" maxAddress"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("To return a value from the native android code to React Native’s Javascript side over the JS Native bridge we will use "),e("code",[t._v("com.facebook.react.bridge.Promise")]),t._v(". To return balance information to JS, the following code can be used")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" balance"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresult"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("resolve")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("balance"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("At this point we have an Android native module and it can be invoked from JS by calling "),e("code",[t._v("createWallet")]),t._v(" and it will return the balance.")]),t._v(" "),e("p",[t._v("This project can be imported into any RN project to reuse the defined "),e("code",[t._v("createWallet")]),t._v(" method without the need to carry out the setup described above.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// any js file in React Native")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a wallet and retrieve current balance")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),e("p",[t._v("The actual "),e("code",[t._v("bdk-rn")]),t._v(" module has organised the native code into granular methods for different stages of creating a wallet and for different interactions and use cases for a bitcoin application, like generating, mnemonic, keys, creating wallet for different networks, creating descriptors, creating or restoring wallet, fetching balance, fetching transactions and many other methods. Please refer to the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("user guide in the readme"),e("OutboundLink")],1),t._v(" on Github for the complete API. The set of APIs available will grow in the near future as more APIs are added. This article can also be used as a guide to add new methods to the existing bdk-rn project.")]),t._v(" "),e("p",[t._v("The objective of "),e("code",[t._v("bdk-rn")]),t._v(" is to enable React Native developers to quickly start developing applications without the need to package BDK as described above.")]),t._v(" "),e("p",[t._v("Be on the lookout for user guides and tutorials on how to build bitcoin applications using "),e("code",[t._v("bdk-rn")]),t._v(" and "),e("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"references"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References")]),t._v(" "),e("p",[t._v("Creating native modules for Android and iOS: "),e("a",{attrs:{href:"https://reactnative.dev/docs/native-modules-intro",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://reactnative.dev/docs/native-modules-intro"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("React Native Architecture: "),e("a",{attrs:{href:"https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-Android API: "),e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-RN: "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/LtbLightning/bdk-rn"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"feedback"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#feedback"}},[t._v("#")]),t._v(" Feedback")]),t._v(" "),e("p",[t._v("The best way to give feedback on this would be to comment on the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoindevkit.org/pull/107",target:"_blank",rel:"noopener noreferrer"}},[t._v("pull request"),e("OutboundLink")],1),t._v(" for this blog post.\nThanks in advance.")])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{351:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN-Architecture.42fbc351.png"},352:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN.370f20c3.png"},353:function(t,e,a){t.exports=a.p+"assets/img/android_folder.0ff999be.png"},408:function(t,e,a){"use strict";a.r(e);var n=a(7),s=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("The "),e("strong",[t._v("BitcoinDevkit")]),t._v("'s "),e("strong",[t._v("React Native")]),t._v(" library ("),e("code",[t._v("bdk-rn")]),t._v(") makes it easy to develop bitcoin applications for both Android and iOS mobile platforms. Using "),e("code",[t._v("bdk-rn")]),t._v(", knowledge of the underlying bitcoin and BDK API is not required and using "),e("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. The goal is "),e("strong",[t._v("Rapid Bitcoin Application Development")]),t._v(" by doing the heavy lifting in advance and providing a reusable library for other developers to use. Developers simply install using "),e("code",[t._v("yarn add")]),t._v(" and start using it in a React Native Project. The native code, Rust lang implementation, configuration and other setup details are all taken care of by "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("p",[t._v("This article is "),e("strong",[t._v("NOT a guide on how to use bdk-rn")]),t._v(" to build a bitcoin application, rather this is an insight into how "),e("code",[t._v("bdk-rn")]),t._v(" was developed. For help on how to use "),e("code",[t._v("bdk-rn")]),t._v(" to develop a bitcoin wallet or application please refer to the user guide in the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),e("OutboundLink")],1),t._v(" on Github. There will be "),e("code",[t._v("how to guides")]),t._v(" published shortly on getting started with "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"react-native-architecture"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#react-native-architecture"}},[t._v("#")]),t._v(" React Native Architecture")]),t._v(" "),e("p",[t._v("At a high level, RN consists of the UI front which is essentially JavaScript which interacts with the native iOS and Android platforms over a bridge. When communicating over the bridge values from JS are converted to native and vice versa.")]),t._v(" "),e("p",[t._v("The native part of RN consists of Android as well as iOS modules and components. The Android and iOS sections are full fledged native projects which interact with the JS side over the native bridge. A RN project has all the build configuraiton required to build both Android and iOS projects.")]),t._v(" "),e("p",[t._v("For the purpose of making "),e("code",[t._v("bdk-rn")]),t._v(", "),e("code",[t._v("bdk-kotlin")]),t._v(" is used as the native Android module and "),e("code",[t._v("bdk-swift")]),t._v(" as the native iOS module. These are configured and wrapped in a RN Project as part of the platform specific native modules within the RN Project. This RN Project is then built to be a reusable React Native module.")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(351),alt:""}})]),t._v(" "),e("h2",{attrs:{id:"native-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#native-integration"}},[t._v("#")]),t._v(" Native Integration")]),t._v(" "),e("p",[t._v("In order to communicate to native modules on Android and iOS, React Native provides React Context API for Java/Kotlin as well as Swift. React Context API are used to build the interface to the native bridge allowing communication from JS to native modules.")]),t._v(" "),e("p",[t._v("bdk-rn uses React Context API plus some native code to wrap and enhance bdk-kotlin and bdk-swift APIs. The native code calls and interacts with the Android and iOS native modules which interface with the underlying mobile platform.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"20%"},attrs:{src:a(352)}}),t._v(" "),e("h2",{attrs:{id:"android-module"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#android-module"}},[t._v("#")]),t._v(" Android Module")]),t._v(" "),e("p",[t._v("We will go into the details of how the BDK Android Module is integrated, we wont cover iOS.")]),t._v(" "),e("p",[t._v("Starting off with a basic RN project. This project will be enhanced with bdk-kotlin and bdk-swift binaries and native code. For now lets go into the details for Android, iOS has similar steps to be done in Swift.")]),t._v(" "),e("p",[t._v("The Android native project is located under the root project folder.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"120%"},attrs:{src:a(353)}}),t._v(" "),e("p",[t._v("Here we need to add a dependency in "),e("code",[t._v("build.gradle")]),t._v(" for bdk-kotlin's android native binary. This will enable bdk-kotlin to be downloaded and available as one of the native modules.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: build.gradle")]),t._v("\n\nrepositories "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mavenCentral")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ndependencies "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//noinspection GradleDynamicVersion")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'com.facebook.react:react-native:+'")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// bitcoindevkit")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'org.bitcoindevkit:bdk-android:0.7.1'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We will create an Android native module which will interact with "),e("code",[t._v("bdk-android")]),t._v(".\nThis is done by adding a new Kotlin file "),e("code",[t._v("BdkRnModule.kt")]),t._v(" inside "),e("code",[t._v("android/app/src/main/java/com/bdkrn/")]),t._v(" folder")]),t._v(" "),e("p",[t._v("This will be part of the native code for bdk-rn module.Here a new class will be created to encapsulate the interaction with bitcoindevkit's android native binary.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SuppressLint\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Log\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Arguments\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Promise "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Result\n")])])]),e("p",[e("code",[t._v("org.bitcoindevkit")]),t._v(" will also need to be imported here")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bitcoindevkit"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Wallet "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" BdkWallet\n")])])]),e("p",[t._v("To use React Context API "),e("code",[t._v("com.facebook.react.bridge.*")]),t._v(" also needs to be imported")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("\n")])])]),e("p",[t._v("A new class needs to be defined here which will implement the React Context API")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\t"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ReactContextBaseJavaModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getName")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BdkRnModule"')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("With the base imports and class defined, we can start writing methods.\nThis will demonstrate how bdk native module will be called and how values will be returned to JS over the native bridge")]),t._v(" "),e("p",[t._v("Lets create a method that can be called from JaveScript, to do so we use the "),e("code",[t._v("@ReactMethod")]),t._v(" directive which is part of the React Context API. This will expose the method so that it can be called from JavaScript.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We need one more file to complete our native framework. A new Kotlin file, "),e("code",[t._v("BdkRnPackage.kt")]),t._v(" is required to package all our native code into a new android module, here we specify the name of the file we just crated as the module name("),e("code",[t._v("BdkRnModule")]),t._v("). This can be done by adding the following code:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnPackage.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactPackage\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("NativeModule\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactApplicationContext\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("uimanager"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ViewManager\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" BdkRnPackage "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactPackage "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNativeModules")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n MutableList"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("NativeModule"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutableListOf")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),e("p",[t._v("Now lets add code for creating a wallet in BdkRnModule.kt")]),t._v(" "),e("p",[t._v("The methods used here are for bdk-kotlin and available in the bdk-kotlin documentation.")]),t._v(" "),e("p",[t._v("We first create a key info object")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create key info with a new mnemonic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ExtendedKeyInfo "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateExtendedKey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n WordCount"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WORDS12"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n \n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// more code to follow...")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create descriptor and change descriptor")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create databaseConfig and blockchainconfig")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create wallet")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Then key info used to create a wallet descriptor and change descriptor:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" descriptor"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')])]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(' "'),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("84")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*)\"\n\nval changeDescriptor: String = descriptor.replace(\"/84'/1'/0'/0/*\",\"/84'/1'/0'/1/*\")\n")])])])]),e("p",[t._v("To create a wallet with bdk we need to specify wallet descriptor, network, a database config, blockchain config. We intend to use bitcoin testnet and want to use default memory for data. For bitcoin node we will use a public electrum server. We will need to define these parameters to create a wallet.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" network "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" `Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET`\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" databaseConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DatabaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Memory\nblockchainConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n BlockchainConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Electrum")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ElectrumConfig")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 5u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 10u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once done we can use these parameters to create a BDK wallet using the native android BDK library:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BdkWallet "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetwork")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n config\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once we have a wallet initialised, we can call methods on it to sync, generate a new address and to get balance")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[t._v("wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ProgressLog"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" maxAddress"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("To return a value from the native android code to React Native’s Javascript side over the JS Native bridge we will use "),e("code",[t._v("com.facebook.react.bridge.Promise")]),t._v(". To return balance information to JS, the following code can be used")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" balance"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresult"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("resolve")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("balance"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("At this point we have an Android native module and it can be invoked from JS by calling "),e("code",[t._v("createWallet")]),t._v(" and it will return the balance.")]),t._v(" "),e("p",[t._v("This project can be imported into any RN project to reuse the defined "),e("code",[t._v("createWallet")]),t._v(" method without the need to carry out the setup described above.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// any js file in React Native")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a wallet and retrieve current balance")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),e("p",[t._v("The actual "),e("code",[t._v("bdk-rn")]),t._v(" module has organised the native code into granular methods for different stages of creating a wallet and for different interactions and use cases for a bitcoin application, like generating, mnemonic, keys, creating wallet for different networks, creating descriptors, creating or restoring wallet, fetching balance, fetching transactions and many other methods. Please refer to the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("user guide in the readme"),e("OutboundLink")],1),t._v(" on Github for the complete API. The set of APIs available will grow in the near future as more APIs are added. This article can also be used as a guide to add new methods to the existing bdk-rn project.")]),t._v(" "),e("p",[t._v("The objective of "),e("code",[t._v("bdk-rn")]),t._v(" is to enable React Native developers to quickly start developing applications without the need to package BDK as described above.")]),t._v(" "),e("p",[t._v("Be on the lookout for user guides and tutorials on how to build bitcoin applications using "),e("code",[t._v("bdk-rn")]),t._v(" and "),e("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"references"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References")]),t._v(" "),e("p",[t._v("Creating native modules for Android and iOS: "),e("a",{attrs:{href:"https://reactnative.dev/docs/native-modules-intro",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://reactnative.dev/docs/native-modules-intro"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("React Native Architecture: "),e("a",{attrs:{href:"https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-Android API: "),e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-RN: "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/LtbLightning/bdk-rn"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"feedback"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#feedback"}},[t._v("#")]),t._v(" Feedback")]),t._v(" "),e("p",[t._v("The best way to give feedback on this would be to comment on the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoindevkit.org/pull/107",target:"_blank",rel:"noopener noreferrer"}},[t._v("pull request"),e("OutboundLink")],1),t._v(" for this blog post.\nThanks in advance.")])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/34.842dbe3a.js b/assets/js/34.40447606.js similarity index 99% rename from assets/js/34.842dbe3a.js rename to assets/js/34.40447606.js index e11a33e2f3..af078d2b8a 100644 --- a/assets/js/34.842dbe3a.js +++ b/assets/js/34.40447606.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{349:function(t,e,a){t.exports=a.p+"assets/img/descriptor-tracker.5942c853.jpg"},350:function(t,e,a){t.exports=a.p+"assets/img/checkpoints.a4179787.jpg"},406:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("The Bitcoin Devkit (BDK) lets you do a lot of useful things through convenient high level\nabstractions. It works great when these abstractions map nicely onto what you are trying to do. My\ngoal is to develop a new "),e("code",[t._v("bdk_core")]),t._v(" library for when they don't. I want "),e("code",[t._v("bdk_core")]),t._v(" to expose all the\nuseful "),e("em",[t._v("mechanisms")]),t._v(" that BDK has inside it without them being tied to any particular usage "),e("em",[t._v("policy")]),t._v("\nand with very minimal dependencies.")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("bdk_core")]),t._v(' idea is still "in the lab". We\'re not sure yet whether '),e("code",[t._v("bdk_core")]),t._v(" will just be what's\nleft of "),e("code",[t._v("bdk")]),t._v(" once we spin off all the components that have extra dependencies into their own crates\nand refine it a bit. In that case "),e("code",[t._v("bdk_core")]),t._v(" will just be called "),e("code",[t._v("bdk v1.0.0")]),t._v(" or something. Or it might\nbe that "),e("code",[t._v("bdk")]),t._v(" lives on with its current APIs and uses stuff "),e("code",[t._v("bdk_core")]),t._v(" to implement it internally.")]),t._v(" "),e("h2",{attrs:{id:"the-separation-of-policy-and-mechanism"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#the-separation-of-policy-and-mechanism"}},[t._v("#")]),t._v(" The separation of policy and mechanism")]),t._v(" "),e("p",[t._v("My guiding principle for "),e("code",[t._v("bdk_core")]),t._v(" is the "),e("em",[t._v("separation of policy and mechanism")]),t._v(". This is\nwhat I mean by these terms:")]),t._v(" "),e("ul",[e("li",[e("em",[t._v("mechanism")]),t._v(": How you do a particular thing. Mechanism code is functional and doesn't change much.")]),t._v(" "),e("li",[e("em",[t._v("policy")]),t._v(": What you want to do. Policy code composes mechanisms to achieve something in\nan application.")])]),t._v(" "),e("p",[t._v("Here's a nice passage about why the designers of the "),e("a",{attrs:{href:"https://en.wikipedia.org/wiki/X_Window_System",target:"_blank",rel:"noopener noreferrer"}},[t._v("X window system"),e("OutboundLink")],1),t._v(" applied this principle. X has\nbeen around since 1984 and doesn't look like it's going anywhere so it probably has a lot to teach us.\nFrom "),e("em",[e("a",{attrs:{href:"https://en.wikipedia.org/wiki/The_Art_of_Unix_Programming",target:"_blank",rel:"noopener noreferrer"}},[t._v("The Art of UNIX Programming"),e("OutboundLink")],1)]),t._v(":")]),t._v(" "),e("blockquote",[e("p",[t._v("...we observed that the designers of X made a basic decision to implement “mechanism, not policy”—to\nmake X a generic graphics engine and leave decisions about user-interface style to toolkits and\nother levels of the system. We justified this by pointing out that policy and mechanism tend to\nmutate on different timescales, with policy changing much faster than mechanism. Fashions in the\nlook and feel of GUI toolkits may come and go, but raster operations and compositing are forever.")])]),t._v(" "),e("blockquote",[e("p",[t._v("Thus, hardwiring policy and mechanism together has two bad effects: It makes policy rigid and\nharder to change in response to user requirements, and it means that trying to change policy has a\nstrong tendency to destabilize the mechanisms.")])]),t._v(" "),e("blockquote",[e("p",[t._v("On the other hand, by separating the two we make it\npossible to experiment with new policy without breaking mechanisms. We also make it much easier to\nwrite good tests for the mechanism (policy, because it ages so quickly, often does not justify the\ninvestment).")])]),t._v(" "),e("ul",[e("li",[t._v("[ ] > This design rule has wide application outside the GUI context. In general, it implies that we")])]),t._v(" "),e("blockquote",[e("p",[t._v("should look for ways to separate interfaces from engines.")])]),t._v(" "),e("p",[t._v("You'll notice we have a similar situation in Bitcoin engineering. We have mechanism code like\nsigning algorithms, key derivation, transaction construction logic, etc., that don't change much. But\nhow these compose together in applications changes quickly over time and between applications.")]),t._v(" "),e("p",[t._v("The main culprit of policy and mechanism conflation in "),e("code",[t._v("bdk")]),t._v(" is the main "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Wallet")]),e("OutboundLink")],1),t._v(" type.\nWallets do all of the following:")]),t._v(" "),e("ol",[e("li",[t._v("Store one or two descriptors (external and optional internal).")]),t._v(" "),e("li",[t._v("Keep track of which addresses you've given out so you only give out fresh ones from each descriptor.")]),t._v(" "),e("li",[t._v("Keep a list of transactions associated with the addresses in the wallet.")]),t._v(" "),e("li",[t._v("Given a source of blockchain data it can update its internal list of transactions.")]),t._v(" "),e("li",[t._v("Given some parameters it can build a PSBT from transaction outputs.")]),t._v(" "),e("li",[t._v("Given a PSBT it can sign it with its "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/signer/index.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Signers")]),e("OutboundLink")],1),t._v(".")])]),t._v(" "),e("p",[t._v("All of that is very useful but it is bound together with the particular policies and opinions of "),e("code",[t._v("Wallet")]),t._v(".\nIf "),e("code",[t._v("Wallet")]),t._v("'s policy is not your policy it's going to be tricky to get it to do what you want.\nHere are some examples:")]),t._v(" "),e("ol",[e("li",[t._v("In order to control how the "),e("code",[t._v("Wallet")]),t._v(" will select coins for a transaction internally you have to\npass in something implementing the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("CoinSelectionAlgorithm")]),e("OutboundLink")],1),t._v(" trait. A coin selection algorithm\nis clearly mechanism code but the policy of "),e("code",[t._v("Wallet")]),t._v(" restricts that mechanism's interface. We\nhave "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/281",target:"_blank",rel:"noopener noreferrer"}},[t._v("very old issues"),e("OutboundLink")],1),t._v(" related to what the\ninterface of this trait should be and we don't have a clear way forward. In "),e("code",[t._v("bdk_core")]),t._v(" I want to\npurely provide the coin selection mechanisms for figuring out whether you need to select more\nUTXOs or whether you need a change output etc. How you use that mechanism will be up to you.")]),t._v(" "),e("li",[t._v("Another trait that has a similar structure is the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/signer/index.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Signer")]),e("OutboundLink")],1),t._v(" trait. You have to pass in signers\nso your wallet can sign PSBTs but you have little control over how the wallet chooses which\nsigners to use in any given situation. Right now the wallet will just iterate through all the\nsigners and ask them to sign. This is not always appropriate. In "),e("code",[t._v("bdk_core")]),t._v(" I want to provide\nfunctions for populating PSBTs given something that can sign. You'll be in control of when they\nget called.")])]),t._v(" "),e("h2",{attrs:{id:"a-syncing-mechansim-without-the-policy"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-syncing-mechansim-without-the-policy"}},[t._v("#")]),t._v(" A syncing mechansim without the policy")]),t._v(" "),e("p",[t._v("Syncing in "),e("code",[t._v("bdk")]),t._v(" is the place where the design of "),e("code",[t._v("Wallet")]),t._v(" is most restrictive. The "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/trait.WalletSync.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("WalletSync")]),e("OutboundLink")],1),t._v("\ntrait forces you to sync all addresses in a wallet in one big batch. But this is not always what you\nwant to do. I spoke to a developer who wanted to sync his wallet slowly over time with each address\nbeing queried over a different Tor connection. It would be really difficult to implement\n"),e("code",[t._v("WalletSync")]),t._v(" with such a strategy. Another example where "),e("code",[t._v("WalletSync")]),t._v(" isn't the right fit is the\n"),e("a",{attrs:{href:"https://l2.technology/sensei",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sensei"),e("OutboundLink")],1),t._v(" project which uses BDK but incrementally updates the database whenever new information\ncomes in from the blockchain.")]),t._v(" "),e("p",[t._v("Even if syncing all addresses at the same time is roughly what you want to do "),e("code",[t._v("WalletSync")]),t._v(" still\ngets in the way since it defines whether you do it synchronously or asynchrononusly. Applications\ncan control this through "),e("code",[t._v("bdk")]),t._v("'s "),e("code",[t._v("async-interface")]),t._v(" feature flag which internally changes the trait\ndefinition through macros. Another annoyance is that when using "),e("code",[t._v("async-interface")]),t._v(" the future that\ngets returned from "),e("code",[t._v("WalletSync")]),t._v(" "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/165",target:"_blank",rel:"noopener noreferrer"}},[t._v("cannot be "),e("code",[t._v("Send")]),e("OutboundLink")],1),t._v("\nbecause of how "),e("code",[t._v("Wallet")]),t._v(" handles database mutability internally, meaning you can't spawn the future\ninto a new thread.")]),t._v(" "),e("h3",{attrs:{id:"a-general-syncing-mechanism"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-general-syncing-mechanism"}},[t._v("#")]),t._v(" A general syncing mechanism")]),t._v(" "),e("p",[t._v("So what is the most general syncing mechanism that solves these problems? These are the things I\nthink it has to do regardless of where the blockchain data comes from or how it's stored:")]),t._v(" "),e("ol",[e("li",[t._v("Generate and store addresses.")]),t._v(" "),e("li",[t._v("Index transaction data, e.g. transaction outputs we own, when/if they were spent, etc.")]),t._v(" "),e("li",[t._v("Keep track of which addresses have been given out and which have been used.")]),t._v(" "),e("li",[t._v('Be able to "roll back" our view of the above data if a reorg makes some of it stale.')]),t._v(" "),e("li",[t._v("Keep track of transactions related our addresses in our mempool.")])]),t._v(" "),e("p",[t._v("Let's talk about how to implement a mechanism that does all that.")]),t._v(" "),e("h3",{attrs:{id:"how-to-store-and-index-transactions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#how-to-store-and-index-transactions"}},[t._v("#")]),t._v(" How to store and index transactions")]),t._v(" "),e("p",[t._v("Different persistent storage backends have different APIs and their own indexing strategies. That's\nwhy the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/trait.Database.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Database")]),e("OutboundLink")],1),t._v(" trait exists in BDK, to make a clean API to the different storage engines. It's\nimportant to note that the database in BDK only holds public data that could always be retrieved\nfrom the chain. It's just a cache. Despite this we support different backends. Right now it is a\nlot of work to add a new index to the data since you have to add it to every backend and you might have\nto apply schema changes (we still "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/359",target:"_blank",rel:"noopener noreferrer"}},[t._v("don't have a standard approach to\nthis"),e("OutboundLink")],1),t._v(").")]),t._v(" "),e("p",[t._v("Thomas Eizinger "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/165#issuecomment-1047483895",target:"_blank",rel:"noopener noreferrer"}},[t._v("suggested"),e("OutboundLink")],1),t._v("\ndoing everything in memory and only writing to persistent storage when it was convenient. It took me\nsome time but I came around to this idea. It would allow us to get rid of the "),e("code",[t._v("Database")]),t._v(" trait (at\nleast at the "),e("code",[t._v("bdk_core")]),t._v(" level) and greatly simplify what the persistent storage layer has to do.\nWhenever the data is loaded from persistent storage we can just do the indexing in memory and\npresent it to the application.")]),t._v(" "),e("p",[e("em",[t._v("But wait! Wouldn't this mean we'd use way more memory than we need to?")]),t._v(" Yes but memory is cheap.\nConsider that if we say the average transaction size is 300 bytes then with all our indexes each\ntransaction might cost 1kb of memory (pessimistically). This means we could index one thousand\ntransactions in a single megabyte! My iPhone has 4gb of memory so it could index a million\ntransactions with plenty of memory to spare. "),e("em",[t._v("But what if some users can't afford an iPhone?")]),t._v(" Then\nthey also couldn't have afforded to have made a million Bitcoin transactions! "),e("em",[t._v("But what about memory\nconstrained devices like hardware wallets!?")]),t._v(" Those devices typically don't store and retrieve\ntransactions. They're usually just signing devices. Perhaps one day someone will build a memory\nconstrained device that needs to do this work but until then I think this is a fine approach to\ntake.")]),t._v(" "),e("p",[t._v("For now I'm calling this thing that does the in-memory indexing of transactions related to a single\ndescriptor a "),e("code",[t._v("DescriptorTracker")]),t._v(". Here's a diagram that communicates how I imagine it relates to the\nother components.")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(349),alt:""}})]),t._v(" "),e("h3",{attrs:{id:"rolling-back-rolling-forward-and-syncing-to-disk"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#rolling-back-rolling-forward-and-syncing-to-disk"}},[t._v("#")]),t._v(" Rolling back, rolling forward and syncing to disk")]),t._v(" "),e("p",[t._v("State changes in blockchains are clearly delineated. They all happen in blocks! Every view of the\nblockchain, whether you're getting it through compact block filters, an electrum server or something\nwacky like a utreexo bridge will have a concept of blocks and transactions in them. For a wallet we\nonly need a very sparse view of the blockchain that includes at which block a set of transactions\nexisted. That way, if a block disappears we know that all those transactions might disappear too.")]),t._v(" "),e("p",[t._v("With "),e("code",[t._v("bdk_core")]),t._v(" I want to introduce the concept of a "),e("em",[t._v("checkpoint")]),t._v(", which is a block height and hash and\na set of txids that were present at that height "),e("strong",[t._v("but not present in the previous checkpoint")]),t._v(". In\nthis way we create an append-only data structure that can easily be rolled back to a previous height\nif there is a reorg. After rolling back we can then roll forward and apply the new blocks.")]),t._v(" "),e("p",[t._v("Here's an example of how this idea works:")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(350),alt:""}})]),t._v(" "),e("p",[t._v("There are a few edge cases I'd like to cover:")]),t._v(" "),e("ol",[e("li",[t._v("What if when gathering new data from the chain to update a "),e("code",[t._v("DescriptorTracker")]),t._v(" we find an old transaction that belongs to an earlier checkpoint that we had missed form our earlier syncs?")]),t._v(" "),e("li",[t._v("What if when we go to write to persistent storage from a "),e("code",[t._v("DescriptorTracker")]),t._v(" we find that it has some transactions the tracker doesn't? Should we try and reconcile the two sets of transactions?")])]),t._v(" "),e("p",[t._v("I think the correct approach is to treat the chain data as the source of truth for the\n"),e("code",[t._v("DescriptorTracker")]),t._v(" and the "),e("code",[t._v("DescriptorTracker")]),t._v(" as the source of truth for persistent storage. That\nis in the case of (1) we should just rollback the "),e("code",[t._v("DescriptorTracker")]),t._v(" and insert the old but\nrecently discovered transaction in the right place. In the case of (2) we should roll back the\npersistent storage to the point where it differs and apply changes from there. This implies that you\nshould only keep one instance of a "),e("code",[t._v("DescriptorTracker")]),t._v(" for a descriptor in your application and only\nupdate persistent storage by first applying the changes to the tracker.")]),t._v(" "),e("h2",{attrs:{id:"examples"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[t._v("#")]),t._v(" Examples")]),t._v(" "),e("p",[t._v("Here are some examples of what I think this may end up looking like in code. Keep in mind that if\nthis looks complicated it will probably be more complicated in practice! This doesn't mean that we\ncan't create simplifying abstractions and tools around these primitives to cover common policies. I hope we can implement "),e("code",[t._v("Wallet")]),t._v(" with "),e("code",[t._v("DescriptorTracker")]),t._v("s internally.")]),t._v(" "),e("h3",{attrs:{id:"doing-an-initial-sync-of-a-descriptor-that-may-already-contain-coins"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#doing-an-initial-sync-of-a-descriptor-that-may-already-contain-coins"}},[t._v("#")]),t._v(" Doing an initial sync of a descriptor that may already contain coins")]),t._v(" "),e("p",[t._v("When we first sync a descriptor that may already contain coins we want to iterate over all the\nscripts of the wallet and then stop if there's a big enough gap (e.g. 20). In this example we use an\nstateless "),e("a",{attrs:{href:"https://mempool.space/docs/api/rest",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora-like API"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a descriptor tracker the external addresses of a BIP86 key")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tracker "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTracker")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)\"")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" esplora "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch_related_transactions")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// iterate over all addresses in a descriptor")]),t._v("\n scripts"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_scripts")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// stop if you find a gap of 20 unused addresses")]),t._v("\n stop_gap"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\ntracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// now we want to persist this disk")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n start_checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Note that the db_update type is the same as the `update` above.")]),t._v("\nmy_db"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("db_update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"doing-a-sync-of-a-wallet-after-you-already-have-syncd"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#doing-a-sync-of-a-wallet-after-you-already-have-syncd"}},[t._v("#")]),t._v(" Doing a sync of a wallet after you already have sync'd")]),t._v(" "),e("p",[t._v("Now imagine you just want to check if any UTXOs in your wallet have been spent. In this case we've\nalready sync'd before so we need to load that data into the tracker from disk first (rather than\ngoing straight to the blockchain). Then we just ask esplora for transactions related to these\ntransaction outputs.")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a descriptor tracker the external addresses of a BIP86 key")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tracker "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTracker")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)\"")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" init_update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" my_db"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get up to speed with what was on disk.")]),t._v("\ntracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("init_update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get the latest checkpoint")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" checkpoint "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_checkpoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" esplora "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch transactions spending any utxos we have")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch_related_transactions")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n tx_outs"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_unspent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" update "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// now we want to persist this disk")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this call could fail if tracker no longer has this checkpoint.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In this case we'd ask persistent_storage for an earlier checkpoint and try again.")]),t._v("\n start_checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" persistent_storage"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_checkpoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n persistent_storage"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("db_update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StaleCheckpoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here we should call fetch related transactions with an earlier checkpoint.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In practice this logic will be called in a loop")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h3",{attrs:{id:"updating-state-when-you-get-the-data-in-real-time"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#updating-state-when-you-get-the-data-in-real-time"}},[t._v("#")]),t._v(" Updating state when you get the data in real time")]),t._v(" "),e("p",[t._v("If you have an event based view of the blockchain that feeds you block connected or block\ndisconnected events then I imagine the API would look something like this.\nThere's quite a bit left out here but I hope you get the idea.")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a descriptor tracker the external addresses of a BIP86 key")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tracker "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTracker")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)\"")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain_events "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* get a Stream of blockchain block connected/disconnected events */")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("loop")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain_event "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" blockchain_events"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" blockchain_event "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockChainEvent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connected")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_block"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_block")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_block"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("modified"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" modified "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// update persistent storage from tracker")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ApplyBlockError")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutOfOrder")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// the block event we got was not the next block we expected.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// How to recover from this will depend on the application and block source")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockchainEvent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Disconnected")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("disconnected_height"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" disconnected_hash"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this might invalidate a checkpoint")]),t._v("\n tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("disconnect_block")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("disconnected_height"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" disconnected_hash"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Now apply to persistent storage")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h2",{attrs:{id:"feedback"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#feedback"}},[t._v("#")]),t._v(" Feedback")]),t._v(" "),e("p",[t._v("The best way to give feedback on this would be to comment on the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoindevkit.org/pull/100",target:"_blank",rel:"noopener noreferrer"}},[t._v("pull request"),e("OutboundLink")],1),t._v(" for this blog post.\nThanks in advance.")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{349:function(t,e,a){t.exports=a.p+"assets/img/descriptor-tracker.5942c853.jpg"},350:function(t,e,a){t.exports=a.p+"assets/img/checkpoints.a4179787.jpg"},407:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("The Bitcoin Devkit (BDK) lets you do a lot of useful things through convenient high level\nabstractions. It works great when these abstractions map nicely onto what you are trying to do. My\ngoal is to develop a new "),e("code",[t._v("bdk_core")]),t._v(" library for when they don't. I want "),e("code",[t._v("bdk_core")]),t._v(" to expose all the\nuseful "),e("em",[t._v("mechanisms")]),t._v(" that BDK has inside it without them being tied to any particular usage "),e("em",[t._v("policy")]),t._v("\nand with very minimal dependencies.")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("bdk_core")]),t._v(' idea is still "in the lab". We\'re not sure yet whether '),e("code",[t._v("bdk_core")]),t._v(" will just be what's\nleft of "),e("code",[t._v("bdk")]),t._v(" once we spin off all the components that have extra dependencies into their own crates\nand refine it a bit. In that case "),e("code",[t._v("bdk_core")]),t._v(" will just be called "),e("code",[t._v("bdk v1.0.0")]),t._v(" or something. Or it might\nbe that "),e("code",[t._v("bdk")]),t._v(" lives on with its current APIs and uses stuff "),e("code",[t._v("bdk_core")]),t._v(" to implement it internally.")]),t._v(" "),e("h2",{attrs:{id:"the-separation-of-policy-and-mechanism"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#the-separation-of-policy-and-mechanism"}},[t._v("#")]),t._v(" The separation of policy and mechanism")]),t._v(" "),e("p",[t._v("My guiding principle for "),e("code",[t._v("bdk_core")]),t._v(" is the "),e("em",[t._v("separation of policy and mechanism")]),t._v(". This is\nwhat I mean by these terms:")]),t._v(" "),e("ul",[e("li",[e("em",[t._v("mechanism")]),t._v(": How you do a particular thing. Mechanism code is functional and doesn't change much.")]),t._v(" "),e("li",[e("em",[t._v("policy")]),t._v(": What you want to do. Policy code composes mechanisms to achieve something in\nan application.")])]),t._v(" "),e("p",[t._v("Here's a nice passage about why the designers of the "),e("a",{attrs:{href:"https://en.wikipedia.org/wiki/X_Window_System",target:"_blank",rel:"noopener noreferrer"}},[t._v("X window system"),e("OutboundLink")],1),t._v(" applied this principle. X has\nbeen around since 1984 and doesn't look like it's going anywhere so it probably has a lot to teach us.\nFrom "),e("em",[e("a",{attrs:{href:"https://en.wikipedia.org/wiki/The_Art_of_Unix_Programming",target:"_blank",rel:"noopener noreferrer"}},[t._v("The Art of UNIX Programming"),e("OutboundLink")],1)]),t._v(":")]),t._v(" "),e("blockquote",[e("p",[t._v("...we observed that the designers of X made a basic decision to implement “mechanism, not policy”—to\nmake X a generic graphics engine and leave decisions about user-interface style to toolkits and\nother levels of the system. We justified this by pointing out that policy and mechanism tend to\nmutate on different timescales, with policy changing much faster than mechanism. Fashions in the\nlook and feel of GUI toolkits may come and go, but raster operations and compositing are forever.")])]),t._v(" "),e("blockquote",[e("p",[t._v("Thus, hardwiring policy and mechanism together has two bad effects: It makes policy rigid and\nharder to change in response to user requirements, and it means that trying to change policy has a\nstrong tendency to destabilize the mechanisms.")])]),t._v(" "),e("blockquote",[e("p",[t._v("On the other hand, by separating the two we make it\npossible to experiment with new policy without breaking mechanisms. We also make it much easier to\nwrite good tests for the mechanism (policy, because it ages so quickly, often does not justify the\ninvestment).")])]),t._v(" "),e("ul",[e("li",[t._v("[ ] > This design rule has wide application outside the GUI context. In general, it implies that we")])]),t._v(" "),e("blockquote",[e("p",[t._v("should look for ways to separate interfaces from engines.")])]),t._v(" "),e("p",[t._v("You'll notice we have a similar situation in Bitcoin engineering. We have mechanism code like\nsigning algorithms, key derivation, transaction construction logic, etc., that don't change much. But\nhow these compose together in applications changes quickly over time and between applications.")]),t._v(" "),e("p",[t._v("The main culprit of policy and mechanism conflation in "),e("code",[t._v("bdk")]),t._v(" is the main "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Wallet")]),e("OutboundLink")],1),t._v(" type.\nWallets do all of the following:")]),t._v(" "),e("ol",[e("li",[t._v("Store one or two descriptors (external and optional internal).")]),t._v(" "),e("li",[t._v("Keep track of which addresses you've given out so you only give out fresh ones from each descriptor.")]),t._v(" "),e("li",[t._v("Keep a list of transactions associated with the addresses in the wallet.")]),t._v(" "),e("li",[t._v("Given a source of blockchain data it can update its internal list of transactions.")]),t._v(" "),e("li",[t._v("Given some parameters it can build a PSBT from transaction outputs.")]),t._v(" "),e("li",[t._v("Given a PSBT it can sign it with its "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/signer/index.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Signers")]),e("OutboundLink")],1),t._v(".")])]),t._v(" "),e("p",[t._v("All of that is very useful but it is bound together with the particular policies and opinions of "),e("code",[t._v("Wallet")]),t._v(".\nIf "),e("code",[t._v("Wallet")]),t._v("'s policy is not your policy it's going to be tricky to get it to do what you want.\nHere are some examples:")]),t._v(" "),e("ol",[e("li",[t._v("In order to control how the "),e("code",[t._v("Wallet")]),t._v(" will select coins for a transaction internally you have to\npass in something implementing the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("CoinSelectionAlgorithm")]),e("OutboundLink")],1),t._v(" trait. A coin selection algorithm\nis clearly mechanism code but the policy of "),e("code",[t._v("Wallet")]),t._v(" restricts that mechanism's interface. We\nhave "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/281",target:"_blank",rel:"noopener noreferrer"}},[t._v("very old issues"),e("OutboundLink")],1),t._v(" related to what the\ninterface of this trait should be and we don't have a clear way forward. In "),e("code",[t._v("bdk_core")]),t._v(" I want to\npurely provide the coin selection mechanisms for figuring out whether you need to select more\nUTXOs or whether you need a change output etc. How you use that mechanism will be up to you.")]),t._v(" "),e("li",[t._v("Another trait that has a similar structure is the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/signer/index.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Signer")]),e("OutboundLink")],1),t._v(" trait. You have to pass in signers\nso your wallet can sign PSBTs but you have little control over how the wallet chooses which\nsigners to use in any given situation. Right now the wallet will just iterate through all the\nsigners and ask them to sign. This is not always appropriate. In "),e("code",[t._v("bdk_core")]),t._v(" I want to provide\nfunctions for populating PSBTs given something that can sign. You'll be in control of when they\nget called.")])]),t._v(" "),e("h2",{attrs:{id:"a-syncing-mechansim-without-the-policy"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-syncing-mechansim-without-the-policy"}},[t._v("#")]),t._v(" A syncing mechansim without the policy")]),t._v(" "),e("p",[t._v("Syncing in "),e("code",[t._v("bdk")]),t._v(" is the place where the design of "),e("code",[t._v("Wallet")]),t._v(" is most restrictive. The "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/trait.WalletSync.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("WalletSync")]),e("OutboundLink")],1),t._v("\ntrait forces you to sync all addresses in a wallet in one big batch. But this is not always what you\nwant to do. I spoke to a developer who wanted to sync his wallet slowly over time with each address\nbeing queried over a different Tor connection. It would be really difficult to implement\n"),e("code",[t._v("WalletSync")]),t._v(" with such a strategy. Another example where "),e("code",[t._v("WalletSync")]),t._v(" isn't the right fit is the\n"),e("a",{attrs:{href:"https://l2.technology/sensei",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sensei"),e("OutboundLink")],1),t._v(" project which uses BDK but incrementally updates the database whenever new information\ncomes in from the blockchain.")]),t._v(" "),e("p",[t._v("Even if syncing all addresses at the same time is roughly what you want to do "),e("code",[t._v("WalletSync")]),t._v(" still\ngets in the way since it defines whether you do it synchronously or asynchrononusly. Applications\ncan control this through "),e("code",[t._v("bdk")]),t._v("'s "),e("code",[t._v("async-interface")]),t._v(" feature flag which internally changes the trait\ndefinition through macros. Another annoyance is that when using "),e("code",[t._v("async-interface")]),t._v(" the future that\ngets returned from "),e("code",[t._v("WalletSync")]),t._v(" "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/165",target:"_blank",rel:"noopener noreferrer"}},[t._v("cannot be "),e("code",[t._v("Send")]),e("OutboundLink")],1),t._v("\nbecause of how "),e("code",[t._v("Wallet")]),t._v(" handles database mutability internally, meaning you can't spawn the future\ninto a new thread.")]),t._v(" "),e("h3",{attrs:{id:"a-general-syncing-mechanism"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-general-syncing-mechanism"}},[t._v("#")]),t._v(" A general syncing mechanism")]),t._v(" "),e("p",[t._v("So what is the most general syncing mechanism that solves these problems? These are the things I\nthink it has to do regardless of where the blockchain data comes from or how it's stored:")]),t._v(" "),e("ol",[e("li",[t._v("Generate and store addresses.")]),t._v(" "),e("li",[t._v("Index transaction data, e.g. transaction outputs we own, when/if they were spent, etc.")]),t._v(" "),e("li",[t._v("Keep track of which addresses have been given out and which have been used.")]),t._v(" "),e("li",[t._v('Be able to "roll back" our view of the above data if a reorg makes some of it stale.')]),t._v(" "),e("li",[t._v("Keep track of transactions related our addresses in our mempool.")])]),t._v(" "),e("p",[t._v("Let's talk about how to implement a mechanism that does all that.")]),t._v(" "),e("h3",{attrs:{id:"how-to-store-and-index-transactions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#how-to-store-and-index-transactions"}},[t._v("#")]),t._v(" How to store and index transactions")]),t._v(" "),e("p",[t._v("Different persistent storage backends have different APIs and their own indexing strategies. That's\nwhy the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/trait.Database.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("Database")]),e("OutboundLink")],1),t._v(" trait exists in BDK, to make a clean API to the different storage engines. It's\nimportant to note that the database in BDK only holds public data that could always be retrieved\nfrom the chain. It's just a cache. Despite this we support different backends. Right now it is a\nlot of work to add a new index to the data since you have to add it to every backend and you might have\nto apply schema changes (we still "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/359",target:"_blank",rel:"noopener noreferrer"}},[t._v("don't have a standard approach to\nthis"),e("OutboundLink")],1),t._v(").")]),t._v(" "),e("p",[t._v("Thomas Eizinger "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/165#issuecomment-1047483895",target:"_blank",rel:"noopener noreferrer"}},[t._v("suggested"),e("OutboundLink")],1),t._v("\ndoing everything in memory and only writing to persistent storage when it was convenient. It took me\nsome time but I came around to this idea. It would allow us to get rid of the "),e("code",[t._v("Database")]),t._v(" trait (at\nleast at the "),e("code",[t._v("bdk_core")]),t._v(" level) and greatly simplify what the persistent storage layer has to do.\nWhenever the data is loaded from persistent storage we can just do the indexing in memory and\npresent it to the application.")]),t._v(" "),e("p",[e("em",[t._v("But wait! Wouldn't this mean we'd use way more memory than we need to?")]),t._v(" Yes but memory is cheap.\nConsider that if we say the average transaction size is 300 bytes then with all our indexes each\ntransaction might cost 1kb of memory (pessimistically). This means we could index one thousand\ntransactions in a single megabyte! My iPhone has 4gb of memory so it could index a million\ntransactions with plenty of memory to spare. "),e("em",[t._v("But what if some users can't afford an iPhone?")]),t._v(" Then\nthey also couldn't have afforded to have made a million Bitcoin transactions! "),e("em",[t._v("But what about memory\nconstrained devices like hardware wallets!?")]),t._v(" Those devices typically don't store and retrieve\ntransactions. They're usually just signing devices. Perhaps one day someone will build a memory\nconstrained device that needs to do this work but until then I think this is a fine approach to\ntake.")]),t._v(" "),e("p",[t._v("For now I'm calling this thing that does the in-memory indexing of transactions related to a single\ndescriptor a "),e("code",[t._v("DescriptorTracker")]),t._v(". Here's a diagram that communicates how I imagine it relates to the\nother components.")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(349),alt:""}})]),t._v(" "),e("h3",{attrs:{id:"rolling-back-rolling-forward-and-syncing-to-disk"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#rolling-back-rolling-forward-and-syncing-to-disk"}},[t._v("#")]),t._v(" Rolling back, rolling forward and syncing to disk")]),t._v(" "),e("p",[t._v("State changes in blockchains are clearly delineated. They all happen in blocks! Every view of the\nblockchain, whether you're getting it through compact block filters, an electrum server or something\nwacky like a utreexo bridge will have a concept of blocks and transactions in them. For a wallet we\nonly need a very sparse view of the blockchain that includes at which block a set of transactions\nexisted. That way, if a block disappears we know that all those transactions might disappear too.")]),t._v(" "),e("p",[t._v("With "),e("code",[t._v("bdk_core")]),t._v(" I want to introduce the concept of a "),e("em",[t._v("checkpoint")]),t._v(", which is a block height and hash and\na set of txids that were present at that height "),e("strong",[t._v("but not present in the previous checkpoint")]),t._v(". In\nthis way we create an append-only data structure that can easily be rolled back to a previous height\nif there is a reorg. After rolling back we can then roll forward and apply the new blocks.")]),t._v(" "),e("p",[t._v("Here's an example of how this idea works:")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(350),alt:""}})]),t._v(" "),e("p",[t._v("There are a few edge cases I'd like to cover:")]),t._v(" "),e("ol",[e("li",[t._v("What if when gathering new data from the chain to update a "),e("code",[t._v("DescriptorTracker")]),t._v(" we find an old transaction that belongs to an earlier checkpoint that we had missed form our earlier syncs?")]),t._v(" "),e("li",[t._v("What if when we go to write to persistent storage from a "),e("code",[t._v("DescriptorTracker")]),t._v(" we find that it has some transactions the tracker doesn't? Should we try and reconcile the two sets of transactions?")])]),t._v(" "),e("p",[t._v("I think the correct approach is to treat the chain data as the source of truth for the\n"),e("code",[t._v("DescriptorTracker")]),t._v(" and the "),e("code",[t._v("DescriptorTracker")]),t._v(" as the source of truth for persistent storage. That\nis in the case of (1) we should just rollback the "),e("code",[t._v("DescriptorTracker")]),t._v(" and insert the old but\nrecently discovered transaction in the right place. In the case of (2) we should roll back the\npersistent storage to the point where it differs and apply changes from there. This implies that you\nshould only keep one instance of a "),e("code",[t._v("DescriptorTracker")]),t._v(" for a descriptor in your application and only\nupdate persistent storage by first applying the changes to the tracker.")]),t._v(" "),e("h2",{attrs:{id:"examples"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[t._v("#")]),t._v(" Examples")]),t._v(" "),e("p",[t._v("Here are some examples of what I think this may end up looking like in code. Keep in mind that if\nthis looks complicated it will probably be more complicated in practice! This doesn't mean that we\ncan't create simplifying abstractions and tools around these primitives to cover common policies. I hope we can implement "),e("code",[t._v("Wallet")]),t._v(" with "),e("code",[t._v("DescriptorTracker")]),t._v("s internally.")]),t._v(" "),e("h3",{attrs:{id:"doing-an-initial-sync-of-a-descriptor-that-may-already-contain-coins"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#doing-an-initial-sync-of-a-descriptor-that-may-already-contain-coins"}},[t._v("#")]),t._v(" Doing an initial sync of a descriptor that may already contain coins")]),t._v(" "),e("p",[t._v("When we first sync a descriptor that may already contain coins we want to iterate over all the\nscripts of the wallet and then stop if there's a big enough gap (e.g. 20). In this example we use an\nstateless "),e("a",{attrs:{href:"https://mempool.space/docs/api/rest",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora-like API"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a descriptor tracker the external addresses of a BIP86 key")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tracker "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTracker")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)\"")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" esplora "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch_related_transactions")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// iterate over all addresses in a descriptor")]),t._v("\n scripts"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_scripts")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// stop if you find a gap of 20 unused addresses")]),t._v("\n stop_gap"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\ntracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// now we want to persist this disk")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n start_checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Note that the db_update type is the same as the `update` above.")]),t._v("\nmy_db"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("db_update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"doing-a-sync-of-a-wallet-after-you-already-have-syncd"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#doing-a-sync-of-a-wallet-after-you-already-have-syncd"}},[t._v("#")]),t._v(" Doing a sync of a wallet after you already have sync'd")]),t._v(" "),e("p",[t._v("Now imagine you just want to check if any UTXOs in your wallet have been spent. In this case we've\nalready sync'd before so we need to load that data into the tracker from disk first (rather than\ngoing straight to the blockchain). Then we just ask esplora for transactions related to these\ntransaction outputs.")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a descriptor tracker the external addresses of a BIP86 key")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tracker "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTracker")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)\"")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" init_update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" my_db"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get up to speed with what was on disk.")]),t._v("\ntracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("init_update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get the latest checkpoint")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" checkpoint "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_checkpoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" esplora "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch transactions spending any utxos we have")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetch_related_transactions")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n tx_outs"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter_unspent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" update "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// now we want to persist this disk")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_update "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Params")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this call could fail if tracker no longer has this checkpoint.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In this case we'd ask persistent_storage for an earlier checkpoint and try again.")]),t._v("\n start_checkpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" persistent_storage"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_checkpoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n persistent_storage"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_update")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("db_update"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk_esplora"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StaleCheckpoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here we should call fetch related transactions with an earlier checkpoint.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// In practice this logic will be called in a loop")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h3",{attrs:{id:"updating-state-when-you-get-the-data-in-real-time"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#updating-state-when-you-get-the-data-in-real-time"}},[t._v("#")]),t._v(" Updating state when you get the data in real time")]),t._v(" "),e("p",[t._v("If you have an event based view of the blockchain that feeds you block connected or block\ndisconnected events then I imagine the API would look something like this.\nThere's quite a bit left out here but I hope you get the idea.")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a descriptor tracker the external addresses of a BIP86 key")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tracker "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTracker")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)\"")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain_events "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* get a Stream of blockchain block connected/disconnected events */")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("loop")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain_event "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" blockchain_events"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" blockchain_event "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockChainEvent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connected")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_block"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply_block")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_block"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("modified"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" modified "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// update persistent storage from tracker")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Err")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ApplyBlockError")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OutOfOrder")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// the block event we got was not the next block we expected.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// How to recover from this will depend on the application and block source")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockchainEvent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Disconnected")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("disconnected_height"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" disconnected_hash"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this might invalidate a checkpoint")]),t._v("\n tracker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("disconnect_block")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("disconnected_height"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" disconnected_hash"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Now apply to persistent storage")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h2",{attrs:{id:"feedback"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#feedback"}},[t._v("#")]),t._v(" Feedback")]),t._v(" "),e("p",[t._v("The best way to give feedback on this would be to comment on the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoindevkit.org/pull/100",target:"_blank",rel:"noopener noreferrer"}},[t._v("pull request"),e("OutboundLink")],1),t._v(" for this blog post.\nThanks in advance.")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/39.f8b5da6d.js b/assets/js/39.3261ad3c.js similarity index 88% rename from assets/js/39.f8b5da6d.js rename to assets/js/39.3261ad3c.js index 973612f8d4..a00e1d096f 100644 --- a/assets/js/39.f8b5da6d.js +++ b/assets/js/39.3261ad3c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{320:function(t,a,s){},379:function(t,a,s){"use strict";s(320)},442:function(t,a,s){"use strict";s.r(a);s(379);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"hardware"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#hardware"}},[t._v("#")]),t._v(" Hardware")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{323:function(t,a,s){},382:function(t,a,s){"use strict";s(323)},445:function(t,a,s){"use strict";s.r(a);s(382);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"hardware"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#hardware"}},[t._v("#")]),t._v(" Hardware")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/40.5f4c9ecf.js b/assets/js/40.4ab0673d.js similarity index 89% rename from assets/js/40.5f4c9ecf.js rename to assets/js/40.4ab0673d.js index 55fa07ac46..ee979845f7 100644 --- a/assets/js/40.5f4c9ecf.js +++ b/assets/js/40.4ab0673d.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{321:function(t,a,s){},380:function(t,a,s){"use strict";s(321)},443:function(t,a,s){"use strict";s.r(a);s(380);var r=s(7),i=Object(r.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"infrastructure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#infrastructure"}},[t._v("#")]),t._v(" Infrastructure")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),a("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[t._v("Galoy")])]),t._v(" "),a("p",[t._v("Bitcoin-native banking infrastructure for organizations.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://codeberg.org/ark-bitcoin/bark/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bark-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://codeberg.org/ark-bitcoin/bark/",target:"_blank"}},[t._v("Bark")])]),t._v(" "),a("p",[t._v("A Rust implementation of the Ark protocol on bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{320:function(t,a,s){},379:function(t,a,s){"use strict";s(320)},442:function(t,a,s){"use strict";s.r(a);s(379);var r=s(7),i=Object(r.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"infrastructure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#infrastructure"}},[t._v("#")]),t._v(" Infrastructure")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),a("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[t._v("Galoy")])]),t._v(" "),a("p",[t._v("Bitcoin-native banking infrastructure for organizations.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://codeberg.org/ark-bitcoin/bark/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bark-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://codeberg.org/ark-bitcoin/bark/",target:"_blank"}},[t._v("Bark")])]),t._v(" "),a("p",[t._v("A Rust implementation of the Ark protocol on bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/41.017da959.js b/assets/js/41.01e60973.js similarity index 98% rename from assets/js/41.017da959.js rename to assets/js/41.01e60973.js index 13876893ee..5ddd95de27 100644 --- a/assets/js/41.017da959.js +++ b/assets/js/41.01e60973.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{322:function(t,a,s){},381:function(t,a,s){"use strict";s(322)},444:function(t,a,s){"use strict";s.r(a);s(381);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"mobile"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mobile"}},[t._v("#")]),t._v(" Mobile")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://peachbitcoin.com/",target:"_blank"}},[t._v("Peach Bitcoin")])]),t._v(" "),a("p",[t._v("Connecting Bitcoin buyers and sellers directly together. Buy or sell bitcoin peer-to-peer anywhere, at anytime.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[t._v("Mutiny Wallet")])]),t._v(" "),a("p",[t._v("Mutiny is a self-custodial lightning wallet that runs in the browser.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bull-bitcoin-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[t._v("Bull Bitcoin")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin Wallet and Exchange app that lets users buy, sell, spend and get paid with Bitcoin. Bitcoins are automatically sent from the exchange to the user's wallet.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[t._v("Lava")])]),t._v(" "),a("p",[t._v("The Future of Finance Available Today. Functional, safe and simple.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/ldk-node-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[t._v("LDK Node")])]),t._v(" "),a("p",[t._v("A ready-to-go Lightning node library built using LDK and BDK.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/padawan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[t._v("Padawan Wallet")])]),t._v(" "),a("p",[t._v("Padawan is a testnet-only bitcoin wallet packed with tutorials to learn how to use bitcoin on mobile.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/smart-vaults-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[t._v("Smart Vaults")])]),t._v(" "),a("p",[t._v("Determine who, how, and when your Bitcoin can be accessed.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/iris-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[t._v("Iris Wallet")])]),t._v(" "),a("p",[t._v("Open-source wallet for Bitcoin and RGB assets.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),a("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[t._v("Lipa")])]),t._v(" "),a("p",[t._v("The Swiss app for cashless payments with Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[t._v("Lexe Wallet")])]),t._v(" "),a("p",[t._v("Lexe is a self-custodial Bitcoin and Lightning wallet that can receive payments 24/7.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[t._v("10101")])]),t._v(" "),a("p",[t._v("Decentralised finance. For real. BTC trading without counterparty risk in one easy and fast app.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[t._v("Liana")])]),t._v(" "),a("p",[t._v("Never lose your coins. Liana is a simple Bitcoin wallet with built-in loss protection and inheritance.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/utreexod-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[t._v("utreexod")])]),t._v(" "),a("p",[t._v("A fully validating Bitcoin node with Utreexo support.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/protonwallet-logo-transparent-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[t._v("Proton Wallet")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin wallet from the makers of Proton Mail.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/Zero-1729/volt",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/volt-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/Zero-1729/volt",target:"_blank"}},[t._v("Volt")])]),t._v(" "),a("p",[t._v("A modern descriptor-based Financial Freedom Bitcoin Wallet aimed at restoring sovereignty to Global Bitcoiners.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.satsails.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/satsails-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.satsails.com/",target:"_blank"}},[t._v("Satsails")])]),t._v(" "),a("p",[t._v("Satsails is a self self custodial bitcoin wallet with fiat integration for selected countries.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{321:function(t,a,s){},380:function(t,a,s){"use strict";s(321)},443:function(t,a,s){"use strict";s.r(a);s(380);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"mobile"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mobile"}},[t._v("#")]),t._v(" Mobile")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://peachbitcoin.com/",target:"_blank"}},[t._v("Peach Bitcoin")])]),t._v(" "),a("p",[t._v("Connecting Bitcoin buyers and sellers directly together. Buy or sell bitcoin peer-to-peer anywhere, at anytime.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[t._v("Mutiny Wallet")])]),t._v(" "),a("p",[t._v("Mutiny is a self-custodial lightning wallet that runs in the browser.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bull-bitcoin-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[t._v("Bull Bitcoin")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin Wallet and Exchange app that lets users buy, sell, spend and get paid with Bitcoin. Bitcoins are automatically sent from the exchange to the user's wallet.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[t._v("Lava")])]),t._v(" "),a("p",[t._v("The Future of Finance Available Today. Functional, safe and simple.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/ldk-node-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[t._v("LDK Node")])]),t._v(" "),a("p",[t._v("A ready-to-go Lightning node library built using LDK and BDK.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/padawan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[t._v("Padawan Wallet")])]),t._v(" "),a("p",[t._v("Padawan is a testnet-only bitcoin wallet packed with tutorials to learn how to use bitcoin on mobile.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/smart-vaults-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[t._v("Smart Vaults")])]),t._v(" "),a("p",[t._v("Determine who, how, and when your Bitcoin can be accessed.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/iris-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[t._v("Iris Wallet")])]),t._v(" "),a("p",[t._v("Open-source wallet for Bitcoin and RGB assets.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),a("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[t._v("Lipa")])]),t._v(" "),a("p",[t._v("The Swiss app for cashless payments with Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[t._v("Lexe Wallet")])]),t._v(" "),a("p",[t._v("Lexe is a self-custodial Bitcoin and Lightning wallet that can receive payments 24/7.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[t._v("10101")])]),t._v(" "),a("p",[t._v("Decentralised finance. For real. BTC trading without counterparty risk in one easy and fast app.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[t._v("Liana")])]),t._v(" "),a("p",[t._v("Never lose your coins. Liana is a simple Bitcoin wallet with built-in loss protection and inheritance.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/utreexod-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[t._v("utreexod")])]),t._v(" "),a("p",[t._v("A fully validating Bitcoin node with Utreexo support.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/protonwallet-logo-transparent-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[t._v("Proton Wallet")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin wallet from the makers of Proton Mail.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/Zero-1729/volt",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/volt-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/Zero-1729/volt",target:"_blank"}},[t._v("Volt")])]),t._v(" "),a("p",[t._v("A modern descriptor-based Financial Freedom Bitcoin Wallet aimed at restoring sovereignty to Global Bitcoiners.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.satsails.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/satsails-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.satsails.com/",target:"_blank"}},[t._v("Satsails")])]),t._v(" "),a("p",[t._v("Satsails is a self self custodial bitcoin wallet with fiat integration for selected countries.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/42.c35335fc.js b/assets/js/42.bf416f89.js similarity index 91% rename from assets/js/42.c35335fc.js rename to assets/js/42.bf416f89.js index aa871455b3..0b6e160bc2 100644 --- a/assets/js/42.c35335fc.js +++ b/assets/js/42.bf416f89.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{323:function(t,a,s){},382:function(t,a,s){"use strict";s(323)},445:function(t,a,s){"use strict";s.r(a);s(382);var e=s(7),o=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"web"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#web"}},[t._v("#")]),t._v(" Web")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[t._v("mempool.space")])]),t._v(" "),a("p",[t._v("Explore the full Bitcoin ecosystem.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.caravanmultisig.com/#/",target:"_blank"}},[t._v("Caravan")])]),t._v(" "),a("p",[t._v("Caravan is a multi-sig coordinator application, and an Unchained-sponsored open source project.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[t._v("BitMask Wallet")])]),t._v(" "),a("p",[t._v("Your Gateway to DeepWeb3 on Bitcoin. A browser extension for decentralized applications on Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/protonwallet-logo-transparent-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[t._v("Proton Wallet")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin wallet from the makers of Proton Mail.")])])])])}),[],!1,null,null,null);a.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{322:function(t,a,s){},381:function(t,a,s){"use strict";s(322)},444:function(t,a,s){"use strict";s.r(a);s(381);var e=s(7),o=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"web"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#web"}},[t._v("#")]),t._v(" Web")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[t._v("mempool.space")])]),t._v(" "),a("p",[t._v("Explore the full Bitcoin ecosystem.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.caravanmultisig.com/#/",target:"_blank"}},[t._v("Caravan")])]),t._v(" "),a("p",[t._v("Caravan is a multi-sig coordinator application, and an Unchained-sponsored open source project.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[t._v("BitMask Wallet")])]),t._v(" "),a("p",[t._v("Your Gateway to DeepWeb3 on Bitcoin. A browser extension for decentralized applications on Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/protonwallet-logo-transparent-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://proton.me/wallet",target:"_blank"}},[t._v("Proton Wallet")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin wallet from the makers of Proton Mail.")])])])])}),[],!1,null,null,null);a.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/46.8a620891.js b/assets/js/46.c88b1de0.js similarity index 99% rename from assets/js/46.8a620891.js rename to assets/js/46.c88b1de0.js index ec54614572..5ce1bfe02a 100644 --- a/assets/js/46.8a620891.js +++ b/assets/js/46.c88b1de0.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{400:function(e,t,r){"use strict";r.r(t);var n=r(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h3",{attrs:{id:"this-post"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#this-post"}},[e._v("#")]),e._v(" This Post")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://spiral.xyz",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(" team has graciously supported BDK financially (and spiritually) for the past four years and since early 2022 the BDK team has let folks know what we've been up to via the "),t("a",{attrs:{href:"https://spiral.xyz/blog/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral blog"),t("OutboundLink")],1),e._v(". As of last summer we are grateful to also have received a generous "),t("a",{attrs:{href:"https://opensats.org/blog/bitcoin-and-nostr-grants-august-2023",target:"_blank",rel:"noopener noreferrer"}},[e._v("OpenSats grant"),t("OutboundLink")],1),e._v(" supporting our project. To keep our current and future financial supporters, open source contributors, and downstream users updated on our progress, starting this year we will be publishing a quarterly BDK project updates here on our blog.")]),e._v(" "),t("h3",{attrs:{id:"end-of-year-review"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#end-of-year-review"}},[e._v("#")]),e._v(" End of Year Review")]),e._v(" "),t("p",[e._v("The BDK project is made up of a core suite of "),t("a",{attrs:{href:"https://www.rust-lang.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust"),t("OutboundLink")],1),e._v(" libraries ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk?tab=readme-ov-file#architecture",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-*"),t("OutboundLink")],1),e._v(") that work together to provide everything an application developer needs to incorporate on-chain bitcoin wallet functionality into their project. Wrapped around the BDK core libraries is our "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-ffi"),t("OutboundLink")],1),e._v(" bindings libraries that let Kotlin (desktop/android), Swift (desktop/iOS), and Python developers use BDK seamlessly in their projects. And wrapped around all of this software is documentation and examples. For over a year the BDK team has been working on a major "),t("a",{attrs:{href:"https://bitcoindevkit.org/blog/tags/architecture/",target:"_blank",rel:"noopener noreferrer"}},[e._v("re-architecture"),t("OutboundLink")],1),e._v(" of the BDK libraries to improve blockchain syncing, embedded device support ("),t("a",{attrs:{href:"https://docs.rust-embedded.org/book/intro/no-std.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("no-std"),t("OutboundLink")],1),e._v("), update key dependencies ("),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(") and finally to provide a stable 1.0 API that our users can rely on for their production applications.")]),e._v(" "),t("p",[e._v("The team is currently working on the 1.0.0-alpha release train. The purposed of these alpha releases is to give early adopters (including our own "),t("code",[e._v("bdk-ffi")]),e._v(" contributors) a chance to try-out new BDK features and updated APIs and provide feedback. Once we have a stable, feature complete 1.0.0 BDK that our alpha users love we'll begin publishing 1.0.0-beta releases. With our beta releases we will finish updating tutorials and examples and performance testing, and ask all BDK users to start migrating and testing their applications with BDK 1.0.0. When our key contributors and users are satisfied that we have shaken out any final 1.0.0-beta issues we'll publish our BDK 1.0.0 release. Once 1.0.0 is out subsequent releases will use "),t("a",{attrs:{href:"https://semver.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("semantic versioning"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("For those keeping score, we'd originally planned to have the BDK 1.0.0 release out last year, but (spoiler) that didn't happen. As I'm sure our kind readers understand making safe, feature rich, easy to use bitcoin software isn't easy, reviewing it is even harder, and we, like every project in the space are short-handed. But with every release, as we build the software we also on-board new contributors and build the team that will deliver BDK 1.0.0, 1.1.0, 2.0.0, and beyond.")]),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("For Q4 2023 we "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("merged 33 PRs"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("closed 32 issues"),t("OutboundLink")],1),e._v(", and completed two 1.0.0-alpha releases, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.2",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.2"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.3"),t("OutboundLink")],1),e._v(". The primary deliverable of these releases was to further stabilize the "),t("code",[e._v("bdk_chain")]),e._v(" crate which provides the central logic for tracking and updating wallet keychains and scripts to be tracked and manages all of the related blockchain and transaction data. Additional PRs started this quarter lay the groundwork for the next phase of development focused on improving how we sync data via blockchain clients and save that data to persistent storage. We also made one maintenance release "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v0.29.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.29.0"),t("OutboundLink")],1),e._v(" that upgraded our "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to release to 0.30.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("In Q4 the BDK-FFI bindings for Kotlin, Swift, and Python saw "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs merged"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("15 issues closed"),t("OutboundLink")],1),e._v(". One maintenance release was completed, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("v0.31.0"),t("OutboundLink")],1),e._v(", which updated the language bindings dependency to the latest rust "),t("code",[e._v("bdk")]),e._v(" maintenance release 0.29.0 and in doing so updated the BDK FFI "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to version 0.30. This quarter the team took on the major task of creating the first language bindings based on the "),t("code",[e._v("bdk")]),e._v(" 1.0.0-alpha API. The resulting "),t("code",[e._v("bdk-ffi")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.2a",target:"_blank",rel:"noopener noreferrer"}},[e._v("v1.0.0-alpha2a"),t("OutboundLink")],1),e._v(" release is only able to expose part of the full "),t("code",[e._v("bdk")]),e._v(" 1.0.0 API but prepares the project for full support in future releases. As part of this work the current Kotlin API docs were removed, but fear not they will return in future alpha releases and be better than ever with not only API docs for Kotlin but also Swift and Python.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/danielabrozzoni/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Daniela Brozzoni"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 3: Gave a "),t("a",{attrs:{href:"https://bolt.fun",target:"_blank",rel:"noopener noreferrer"}},[e._v("bolt.fun"),t("OutboundLink")],1),e._v(" talk on open source development, "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=P75nCR1owws",target:"_blank",rel:"noopener noreferrer"}},[e._v("YouTube"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("October 25-26: Joined a "),t("a",{attrs:{href:"https://planb.lugano.ch/contributing-to-free-and-open-source-projects/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Contributing to free and open source projects" panel'),t("OutboundLink")],1),e._v(" at "),t("a",{attrs:{href:"https://planb.lugano.ch/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Plan B"),t("OutboundLink")],1),e._v(" lugano.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 15: Worked with "),t("a",{attrs:{href:"https://wizardsardine.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("wizardsardine"),t("OutboundLink")],1),e._v(" team to "),t("a",{attrs:{href:"https://twitter.com/darosior/status/1724842410839093562",target:"_blank",rel:"noopener noreferrer"}},[e._v("extract and integrate BDK coin-selection into the Liana wallet"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 3: Spoke at the "),t("a",{attrs:{href:"https://twitter.com/TaiwanBitdevs/status/1726537941688967238",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Tech Summit Taipei"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 13: Gave a talk about Bitcoin and BDK at "),t("a",{attrs:{href:"https://twitter.com/JCBA_org/status/1735100779172856170",target:"_blank",rel:"noopener noreferrer"}},[e._v("Taipei Blockchain Week"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Thunderbiscuit"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 8: Created the educational "),t("a",{attrs:{href:"https://opcodeexplained.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Opcode Explained"),t("OutboundLink")],1),e._v(" website to help... explain bitcoin opcodes!")]),e._v(" "),t("p",[e._v("November 15: Joined the panel on the "),t("a",{attrs:{href:"https://bitcoin.review/podcast/episode-55/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Review Podcast Episode 55"),t("OutboundLink")],1),e._v(" to talked about his "),t("a",{attrs:{href:"https://github.com/thunderbiscuit/padawan-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("padawan-wallet"),t("OutboundLink")],1),e._v(" project.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/reez/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Matthew Ramsden"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("October 11: Spoke at the "),t("a",{attrs:{href:"https://www.meetup.com/bitcoinpark/events/291768716/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Park OpenHouse"),t("OutboundLink")],1),e._v(" on the topic "),t("a",{attrs:{href:"https://podcasts.apple.com/us/podcast/open-house-exploring-the-lightning-network-ldk/id1646515985?i=1000631904227",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Exploring the Lightning Network"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("November 8: Created a video for the "),t("a",{attrs:{href:"https://www.youtube.com/@bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Developers"),t("OutboundLink")],1),e._v(" channel on YouTube titled "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=rcU3LU6iZCs",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Lightning Development with Swift: Make Your First Lightning App with LDK Node Swift"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{399:function(e,t,r){"use strict";r.r(t);var n=r(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h3",{attrs:{id:"this-post"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#this-post"}},[e._v("#")]),e._v(" This Post")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://spiral.xyz",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(" team has graciously supported BDK financially (and spiritually) for the past four years and since early 2022 the BDK team has let folks know what we've been up to via the "),t("a",{attrs:{href:"https://spiral.xyz/blog/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral blog"),t("OutboundLink")],1),e._v(". As of last summer we are grateful to also have received a generous "),t("a",{attrs:{href:"https://opensats.org/blog/bitcoin-and-nostr-grants-august-2023",target:"_blank",rel:"noopener noreferrer"}},[e._v("OpenSats grant"),t("OutboundLink")],1),e._v(" supporting our project. To keep our current and future financial supporters, open source contributors, and downstream users updated on our progress, starting this year we will be publishing a quarterly BDK project updates here on our blog.")]),e._v(" "),t("h3",{attrs:{id:"end-of-year-review"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#end-of-year-review"}},[e._v("#")]),e._v(" End of Year Review")]),e._v(" "),t("p",[e._v("The BDK project is made up of a core suite of "),t("a",{attrs:{href:"https://www.rust-lang.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust"),t("OutboundLink")],1),e._v(" libraries ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk?tab=readme-ov-file#architecture",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-*"),t("OutboundLink")],1),e._v(") that work together to provide everything an application developer needs to incorporate on-chain bitcoin wallet functionality into their project. Wrapped around the BDK core libraries is our "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-ffi"),t("OutboundLink")],1),e._v(" bindings libraries that let Kotlin (desktop/android), Swift (desktop/iOS), and Python developers use BDK seamlessly in their projects. And wrapped around all of this software is documentation and examples. For over a year the BDK team has been working on a major "),t("a",{attrs:{href:"https://bitcoindevkit.org/blog/tags/architecture/",target:"_blank",rel:"noopener noreferrer"}},[e._v("re-architecture"),t("OutboundLink")],1),e._v(" of the BDK libraries to improve blockchain syncing, embedded device support ("),t("a",{attrs:{href:"https://docs.rust-embedded.org/book/intro/no-std.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("no-std"),t("OutboundLink")],1),e._v("), update key dependencies ("),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(") and finally to provide a stable 1.0 API that our users can rely on for their production applications.")]),e._v(" "),t("p",[e._v("The team is currently working on the 1.0.0-alpha release train. The purposed of these alpha releases is to give early adopters (including our own "),t("code",[e._v("bdk-ffi")]),e._v(" contributors) a chance to try-out new BDK features and updated APIs and provide feedback. Once we have a stable, feature complete 1.0.0 BDK that our alpha users love we'll begin publishing 1.0.0-beta releases. With our beta releases we will finish updating tutorials and examples and performance testing, and ask all BDK users to start migrating and testing their applications with BDK 1.0.0. When our key contributors and users are satisfied that we have shaken out any final 1.0.0-beta issues we'll publish our BDK 1.0.0 release. Once 1.0.0 is out subsequent releases will use "),t("a",{attrs:{href:"https://semver.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("semantic versioning"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("For those keeping score, we'd originally planned to have the BDK 1.0.0 release out last year, but (spoiler) that didn't happen. As I'm sure our kind readers understand making safe, feature rich, easy to use bitcoin software isn't easy, reviewing it is even harder, and we, like every project in the space are short-handed. But with every release, as we build the software we also on-board new contributors and build the team that will deliver BDK 1.0.0, 1.1.0, 2.0.0, and beyond.")]),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("For Q4 2023 we "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("merged 33 PRs"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("closed 32 issues"),t("OutboundLink")],1),e._v(", and completed two 1.0.0-alpha releases, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.2",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.2"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.3"),t("OutboundLink")],1),e._v(". The primary deliverable of these releases was to further stabilize the "),t("code",[e._v("bdk_chain")]),e._v(" crate which provides the central logic for tracking and updating wallet keychains and scripts to be tracked and manages all of the related blockchain and transaction data. Additional PRs started this quarter lay the groundwork for the next phase of development focused on improving how we sync data via blockchain clients and save that data to persistent storage. We also made one maintenance release "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v0.29.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.29.0"),t("OutboundLink")],1),e._v(" that upgraded our "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to release to 0.30.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("In Q4 the BDK-FFI bindings for Kotlin, Swift, and Python saw "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs merged"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("15 issues closed"),t("OutboundLink")],1),e._v(". One maintenance release was completed, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("v0.31.0"),t("OutboundLink")],1),e._v(", which updated the language bindings dependency to the latest rust "),t("code",[e._v("bdk")]),e._v(" maintenance release 0.29.0 and in doing so updated the BDK FFI "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to version 0.30. This quarter the team took on the major task of creating the first language bindings based on the "),t("code",[e._v("bdk")]),e._v(" 1.0.0-alpha API. The resulting "),t("code",[e._v("bdk-ffi")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.2a",target:"_blank",rel:"noopener noreferrer"}},[e._v("v1.0.0-alpha2a"),t("OutboundLink")],1),e._v(" release is only able to expose part of the full "),t("code",[e._v("bdk")]),e._v(" 1.0.0 API but prepares the project for full support in future releases. As part of this work the current Kotlin API docs were removed, but fear not they will return in future alpha releases and be better than ever with not only API docs for Kotlin but also Swift and Python.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/danielabrozzoni/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Daniela Brozzoni"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 3: Gave a "),t("a",{attrs:{href:"https://bolt.fun",target:"_blank",rel:"noopener noreferrer"}},[e._v("bolt.fun"),t("OutboundLink")],1),e._v(" talk on open source development, "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=P75nCR1owws",target:"_blank",rel:"noopener noreferrer"}},[e._v("YouTube"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("October 25-26: Joined a "),t("a",{attrs:{href:"https://planb.lugano.ch/contributing-to-free-and-open-source-projects/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Contributing to free and open source projects" panel'),t("OutboundLink")],1),e._v(" at "),t("a",{attrs:{href:"https://planb.lugano.ch/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Plan B"),t("OutboundLink")],1),e._v(" lugano.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 15: Worked with "),t("a",{attrs:{href:"https://wizardsardine.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("wizardsardine"),t("OutboundLink")],1),e._v(" team to "),t("a",{attrs:{href:"https://twitter.com/darosior/status/1724842410839093562",target:"_blank",rel:"noopener noreferrer"}},[e._v("extract and integrate BDK coin-selection into the Liana wallet"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 3: Spoke at the "),t("a",{attrs:{href:"https://twitter.com/TaiwanBitdevs/status/1726537941688967238",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Tech Summit Taipei"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 13: Gave a talk about Bitcoin and BDK at "),t("a",{attrs:{href:"https://twitter.com/JCBA_org/status/1735100779172856170",target:"_blank",rel:"noopener noreferrer"}},[e._v("Taipei Blockchain Week"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Thunderbiscuit"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 8: Created the educational "),t("a",{attrs:{href:"https://opcodeexplained.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Opcode Explained"),t("OutboundLink")],1),e._v(" website to help... explain bitcoin opcodes!")]),e._v(" "),t("p",[e._v("November 15: Joined the panel on the "),t("a",{attrs:{href:"https://bitcoin.review/podcast/episode-55/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Review Podcast Episode 55"),t("OutboundLink")],1),e._v(" to talked about his "),t("a",{attrs:{href:"https://github.com/thunderbiscuit/padawan-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("padawan-wallet"),t("OutboundLink")],1),e._v(" project.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/reez/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Matthew Ramsden"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("October 11: Spoke at the "),t("a",{attrs:{href:"https://www.meetup.com/bitcoinpark/events/291768716/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Park OpenHouse"),t("OutboundLink")],1),e._v(" on the topic "),t("a",{attrs:{href:"https://podcasts.apple.com/us/podcast/open-house-exploring-the-lightning-network-ldk/id1646515985?i=1000631904227",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Exploring the Lightning Network"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("November 8: Created a video for the "),t("a",{attrs:{href:"https://www.youtube.com/@bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Developers"),t("OutboundLink")],1),e._v(" channel on YouTube titled "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=rcU3LU6iZCs",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Lightning Development with Swift: Make Your First Lightning App with LDK Node Swift"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/47.1e361a05.js b/assets/js/47.70dc63ea.js similarity index 98% rename from assets/js/47.1e361a05.js rename to assets/js/47.70dc63ea.js index 235d95e7f4..c289322578 100644 --- a/assets/js/47.1e361a05.js +++ b/assets/js/47.70dc63ea.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{399:function(e,t,r){"use strict";r.r(t);var a=r(7),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("br"),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("The majority of BDK rust library work this quarter was towards finishing new and improved electrum, esplora and Bitcoin Core RPC (block-by-block) syncing APIs. Bug fixes and improvements were also completed for the transaction builder and other wallet APIs. Six bi-weekly 1.0.0-alpha releases were made ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.3"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.4",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.4"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.5",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.5"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.6",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.6"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.7"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.8",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.8"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("54 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("55 issues"),t("OutboundLink")],1),e._v(" were closed.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("For the language binding libraries (Kotlin, Swift, Python) the focus was on small bug fixes for the pre-1.0 releases ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.0"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.1",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.1"),t("OutboundLink")],1),e._v(") and creating the first 1.0.0-alpha bindings release ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.7"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("8 issues"),t("OutboundLink")],1),e._v(" closed.")]),e._v(" "),t("h3",{attrs:{id:"plans-for-next-quarter"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#plans-for-next-quarter"}},[e._v("#")]),e._v(" Plans for Next Quarter")]),e._v(" "),t("p",[e._v("The focus for Q2 development is completing our first 1.0.0 beta release and improving user docs and testing for it. The team will also work on updating all language bindings (Kotlin/Swift/Python) to use new rust lib 1.0.0 beta APIs.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("February 22: Gave a talk on "),t("a",{attrs:{href:"https://btcplusplus.dev/conf/ba24/talks",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK 1.0 at BTC++"),t("OutboundLink")],1),e._v(" in Buena Aires, Argentina.")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{400:function(e,t,r){"use strict";r.r(t);var a=r(7),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("br"),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("The majority of BDK rust library work this quarter was towards finishing new and improved electrum, esplora and Bitcoin Core RPC (block-by-block) syncing APIs. Bug fixes and improvements were also completed for the transaction builder and other wallet APIs. Six bi-weekly 1.0.0-alpha releases were made ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.3"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.4",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.4"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.5",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.5"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.6",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.6"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.7"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.8",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.8"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("54 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("55 issues"),t("OutboundLink")],1),e._v(" were closed.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("For the language binding libraries (Kotlin, Swift, Python) the focus was on small bug fixes for the pre-1.0 releases ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.0"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.1",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.1"),t("OutboundLink")],1),e._v(") and creating the first 1.0.0-alpha bindings release ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.7"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("8 issues"),t("OutboundLink")],1),e._v(" closed.")]),e._v(" "),t("h3",{attrs:{id:"plans-for-next-quarter"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#plans-for-next-quarter"}},[e._v("#")]),e._v(" Plans for Next Quarter")]),e._v(" "),t("p",[e._v("The focus for Q2 development is completing our first 1.0.0 beta release and improving user docs and testing for it. The team will also work on updating all language bindings (Kotlin/Swift/Python) to use new rust lib 1.0.0 beta APIs.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("February 22: Gave a talk on "),t("a",{attrs:{href:"https://btcplusplus.dev/conf/ba24/talks",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK 1.0 at BTC++"),t("OutboundLink")],1),e._v(" in Buena Aires, Argentina.")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/48.6c8fd04b.js b/assets/js/48.1c4bedef.js similarity index 99% rename from assets/js/48.6c8fd04b.js rename to assets/js/48.1c4bedef.js index 478fcc7f4c..edb49d7120 100644 --- a/assets/js/48.6c8fd04b.js +++ b/assets/js/48.1c4bedef.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{401:function(e,t,n){"use strict";n.r(t);var i=n(7),o=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("The bitcoindevkit team has been hard at work for Q2 in 2024, pushing to stabilize the API of its "),t("code",[e._v("bdk_wallet")]),e._v(" crate and releasing 4 new alpha versions (9, 10, 11, and 12!), and aiming to release a 1.0 beta in July. Here are some of the notable changes and upgrades to the software libraries we maintain:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Update "),t("code",[e._v("bdk_electrum")]),e._v(" to use merkle proofs.")]),e._v(" This PR is the first step in reworking "),t("code",[e._v("bdk_electrum")]),e._v(" to use merkle proofs. When we fetch a transaction, we now also obtain the merkle proof and block header for verification. We then confirm a transaction is in a block only after validating it's Merkle proof.")]),e._v(" "),t("li",[t("strong",[e._v("Upgrade of rust-bitcoin and rust-miniscript.")]),e._v(" We upgraded our dependencies on these crates to the latest "),t("code",[e._v("0.32.0")]),e._v(" and "),t("code",[e._v("0.12.0")]),e._v(" respectively.")]),e._v(" "),t("li",[t("strong",[e._v("Added examples.")]),e._v(" We added examples and cleaned up our current example crates to help builders stay up-to-date on the latest changes.")]),e._v(" "),t("li",[t("strong",[e._v("Use bitcoin::Amount in most public APIs.")]),e._v(" This change ensures type safety when requiring and providing bitcoin amount in our APIs, using the rust-bitcoin crate "),t("code",[e._v("Amount")]),e._v(" type.")]),e._v(" "),t("li",[t("strong",[e._v("Introduce Sync and FullScan related types.")]),e._v(" This change introduced universal structures that represent sync/full-scan requests/results for all SPK-based syncing clients.")]),e._v(" "),t("li",[t("strong",[e._v("Allow user provided RNG.")]),e._v(" This change makes the "),t("code",[e._v("rand")]),e._v(" dependency optional.")])]),e._v(" "),t("p",[e._v("The language bindings for iOS, Android, and Python have also seen some new alpha release and a ton of new features, in preparation for the beta release.")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Upgrade to the latest uniffi (0.28.0).")]),e._v(" This was a major upgrade that gave us a whole new set of functionalities: the ability to implement traits in the foreign languages, using the "),t("code",[e._v("Display")]),e._v(" trait to auto-generate the "),t("code",[e._v("toString()")]),e._v(" methods, enable API docs in the UDL file, and support for async!")]),e._v(" "),t("li",[t("strong",[e._v("Brand new iOS build workflow.")]),e._v(" This one is nerdy but a goodie. Anyone interested in how we build bindings should check out this major cleanup of our iOS library build workflow!")]),e._v(" "),t("li",[t("strong",[e._v("Starting the work on bitcoin-ffi.")]),e._v(" The team has started the work on a separate crate called "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin-ffi"),t("OutboundLink")],1),e._v(", effectively migrating the types we exposed from rust-bitcoin into a standalone crate that other projects building on uniffi can use.")])]),e._v(" "),t("h3",{attrs:{id:"our-grantees-in-action"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#our-grantees-in-action"}},[e._v("#")]),e._v(" Our Grantees in Action")]),e._v(" "),t("p",[e._v("In addition to our full-time grantees, the "),t("a",{attrs:{href:"https://bitcoindevkit.org/foundation/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK Foundation"),t("OutboundLink")],1),e._v(" provides part-time grants to folks on special projects. Q2 is funding 2 projects in particular:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Wei Chen.")]),e._v(" Wei has been contributing to BDK since late 2023 and was formerly a full stack Java developer based in Washington D.C. with ten years of experience. The focus of his contributions will be towards assisting with the restructuring of the electrum crate, reengineering of the TxGraph data components to simplify the tracking of lineal conflicts, as well as on performance optimization and the continued debugging of BDK.")]),e._v(" "),t("li",[t("strong",[e._v("Manuel Gatti.")]),e._v(" Manuel is a Project Manager at Wizard Sardine. He is involved in some educational projects related to bitcoin in Italy and hosts an Italian podcast about libertarian philosophy with episodes dedicated to bitcoin as a tool for freedom. He has been contributing to BDK since April 2023 mostly on the project management side (holding calls, helping with triage and prioritization, updating stakeholders). His project consists of conducting user interviews in order to get feedback on BDK usage and possible pain points with the aim to help the team with the definition and prioritization of the development activities.")])]),e._v(" "),t("p",[e._v("We've also been active at conferences!")]),e._v(" "),t("ul",[t("li",[e._v("Evan made his way to South Korea to host a workshop at the "),t("a",{attrs:{href:"https://www.bitcoinseoul.kr/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Seoul"),t("OutboundLink")],1),e._v(" conference.")]),e._v(" "),t("li",[e._v("Evan and ValuedMammal also made their way to the "),t("a",{attrs:{href:"https://btcplusplus.dev/conf/ba24",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin++ conference in Buenos Aires"),t("OutboundLink")],1),e._v(" to talk about BDK.")]),e._v(" "),t("li",[e._v("thunderbiscuit was in Montreal for the "),t("a",{attrs:{href:"https://canadianbitcoinconf.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("Canadian Bitcoin Conference"),t("OutboundLink")],1),e._v(" again this year. A fantastic event with many users of BDK present!")])]),e._v(" "),t("h3",{attrs:{id:"bdk-in-the-wild"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-in-the-wild"}},[e._v("#")]),e._v(" BDK in the Wild")]),e._v(" "),t("ul",[t("li",[e._v("In Q2, "),t("a",{attrs:{href:"https://bitkey.world/en-US",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitkey"),t("OutboundLink")],1),e._v(" open sourced their app, making it one of the biggest users of BDK on mobile.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bull Bitcoin"),t("OutboundLink")],1),e._v(" released their "),t("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.bullbitcoin.mobile",target:"_blank",rel:"noopener noreferrer"}},[e._v("Android app"),t("OutboundLink")],1),e._v(" based on the bdk-flutter library at the Canadian Bitcoin Conference in Montreal!")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{402:function(e,t,n){"use strict";n.r(t);var i=n(7),o=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("The bitcoindevkit team has been hard at work for Q2 in 2024, pushing to stabilize the API of its "),t("code",[e._v("bdk_wallet")]),e._v(" crate and releasing 4 new alpha versions (9, 10, 11, and 12!), and aiming to release a 1.0 beta in July. Here are some of the notable changes and upgrades to the software libraries we maintain:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Update "),t("code",[e._v("bdk_electrum")]),e._v(" to use merkle proofs.")]),e._v(" This PR is the first step in reworking "),t("code",[e._v("bdk_electrum")]),e._v(" to use merkle proofs. When we fetch a transaction, we now also obtain the merkle proof and block header for verification. We then confirm a transaction is in a block only after validating it's Merkle proof.")]),e._v(" "),t("li",[t("strong",[e._v("Upgrade of rust-bitcoin and rust-miniscript.")]),e._v(" We upgraded our dependencies on these crates to the latest "),t("code",[e._v("0.32.0")]),e._v(" and "),t("code",[e._v("0.12.0")]),e._v(" respectively.")]),e._v(" "),t("li",[t("strong",[e._v("Added examples.")]),e._v(" We added examples and cleaned up our current example crates to help builders stay up-to-date on the latest changes.")]),e._v(" "),t("li",[t("strong",[e._v("Use bitcoin::Amount in most public APIs.")]),e._v(" This change ensures type safety when requiring and providing bitcoin amount in our APIs, using the rust-bitcoin crate "),t("code",[e._v("Amount")]),e._v(" type.")]),e._v(" "),t("li",[t("strong",[e._v("Introduce Sync and FullScan related types.")]),e._v(" This change introduced universal structures that represent sync/full-scan requests/results for all SPK-based syncing clients.")]),e._v(" "),t("li",[t("strong",[e._v("Allow user provided RNG.")]),e._v(" This change makes the "),t("code",[e._v("rand")]),e._v(" dependency optional.")])]),e._v(" "),t("p",[e._v("The language bindings for iOS, Android, and Python have also seen some new alpha release and a ton of new features, in preparation for the beta release.")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Upgrade to the latest uniffi (0.28.0).")]),e._v(" This was a major upgrade that gave us a whole new set of functionalities: the ability to implement traits in the foreign languages, using the "),t("code",[e._v("Display")]),e._v(" trait to auto-generate the "),t("code",[e._v("toString()")]),e._v(" methods, enable API docs in the UDL file, and support for async!")]),e._v(" "),t("li",[t("strong",[e._v("Brand new iOS build workflow.")]),e._v(" This one is nerdy but a goodie. Anyone interested in how we build bindings should check out this major cleanup of our iOS library build workflow!")]),e._v(" "),t("li",[t("strong",[e._v("Starting the work on bitcoin-ffi.")]),e._v(" The team has started the work on a separate crate called "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin-ffi"),t("OutboundLink")],1),e._v(", effectively migrating the types we exposed from rust-bitcoin into a standalone crate that other projects building on uniffi can use.")])]),e._v(" "),t("h3",{attrs:{id:"our-grantees-in-action"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#our-grantees-in-action"}},[e._v("#")]),e._v(" Our Grantees in Action")]),e._v(" "),t("p",[e._v("In addition to our full-time grantees, the "),t("a",{attrs:{href:"https://bitcoindevkit.org/foundation/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK Foundation"),t("OutboundLink")],1),e._v(" provides part-time grants to folks on special projects. Q2 is funding 2 projects in particular:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Wei Chen.")]),e._v(" Wei has been contributing to BDK since late 2023 and was formerly a full stack Java developer based in Washington D.C. with ten years of experience. The focus of his contributions will be towards assisting with the restructuring of the electrum crate, reengineering of the TxGraph data components to simplify the tracking of lineal conflicts, as well as on performance optimization and the continued debugging of BDK.")]),e._v(" "),t("li",[t("strong",[e._v("Manuel Gatti.")]),e._v(" Manuel is a Project Manager at Wizard Sardine. He is involved in some educational projects related to bitcoin in Italy and hosts an Italian podcast about libertarian philosophy with episodes dedicated to bitcoin as a tool for freedom. He has been contributing to BDK since April 2023 mostly on the project management side (holding calls, helping with triage and prioritization, updating stakeholders). His project consists of conducting user interviews in order to get feedback on BDK usage and possible pain points with the aim to help the team with the definition and prioritization of the development activities.")])]),e._v(" "),t("p",[e._v("We've also been active at conferences!")]),e._v(" "),t("ul",[t("li",[e._v("Evan made his way to South Korea to host a workshop at the "),t("a",{attrs:{href:"https://www.bitcoinseoul.kr/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Seoul"),t("OutboundLink")],1),e._v(" conference.")]),e._v(" "),t("li",[e._v("Evan and ValuedMammal also made their way to the "),t("a",{attrs:{href:"https://btcplusplus.dev/conf/ba24",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin++ conference in Buenos Aires"),t("OutboundLink")],1),e._v(" to talk about BDK.")]),e._v(" "),t("li",[e._v("thunderbiscuit was in Montreal for the "),t("a",{attrs:{href:"https://canadianbitcoinconf.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("Canadian Bitcoin Conference"),t("OutboundLink")],1),e._v(" again this year. A fantastic event with many users of BDK present!")])]),e._v(" "),t("h3",{attrs:{id:"bdk-in-the-wild"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-in-the-wild"}},[e._v("#")]),e._v(" BDK in the Wild")]),e._v(" "),t("ul",[t("li",[e._v("In Q2, "),t("a",{attrs:{href:"https://bitkey.world/en-US",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitkey"),t("OutboundLink")],1),e._v(" open sourced their app, making it one of the biggest users of BDK on mobile.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bull Bitcoin"),t("OutboundLink")],1),e._v(" released their "),t("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.bullbitcoin.mobile",target:"_blank",rel:"noopener noreferrer"}},[e._v("Android app"),t("OutboundLink")],1),e._v(" based on the bdk-flutter library at the Canadian Bitcoin Conference in Montreal!")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/49.5320af3f.js b/assets/js/49.3295c4d3.js similarity index 98% rename from assets/js/49.5320af3f.js rename to assets/js/49.3295c4d3.js index 697065556b..ca31ba948a 100644 --- a/assets/js/49.5320af3f.js +++ b/assets/js/49.3295c4d3.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{402:function(i,e,t){"use strict";t.r(e);var o=t(7),n=Object(o.a)({},(function(){var i=this,e=i._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":i.$parent.slotKey}},[e("p",[i._v("The Bitcoin Dev Kit (BDK) Foundation is seeking proposals for a full-time Rust maintainer to support the ongoing development and maintenance of the BDK suite of open source software. We invite qualified individuals to submit grant applications for this critical role.")]),i._v(" "),e("h2",{attrs:{id:"grant-overview"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grant-overview"}},[i._v("#")]),i._v(" Grant Overview")]),i._v(" "),e("p",[i._v("Position: Open source Rust library maintainer"),e("br"),i._v("\nDuration: Minimum 1-2 years, full-time commitment"),e("br"),i._v("\nFocus: Maintaining and improving the BDK Rust codebase")]),i._v(" "),e("h2",{attrs:{id:"key-requirements"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#key-requirements"}},[i._v("#")]),i._v(" Key Requirements")]),i._v(" "),e("ul",[e("li",[i._v("Strong Rust development skills with experience in API design and usage")]),i._v(" "),e("li",[i._v("Demonstrated ability to contribute to open source projects, particularly in the Bitcoin ecosystem")]),i._v(" "),e("li",[i._v("Solid understanding of Bitcoin on-chain protocols and technology")]),i._v(" "),e("li",[i._v("Excellent communication skills and ability to work effectively in a team")]),i._v(" "),e("li",[i._v("Commitment to mentoring and supporting other developers in the BDK and Bitcoin community")]),i._v(" "),e("li",[i._v("Willingness to contribute to non-coding aspects of the project (e.g., documentation, CI, release management)")])]),i._v(" "),e("h2",{attrs:{id:"desired-qualifications"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#desired-qualifications"}},[i._v("#")]),i._v(" Desired Qualifications")]),i._v(" "),e("ul",[e("li",[i._v("Vision for maintaining and improving the overall BDK Rust codebase")]),i._v(" "),e("li",[i._v("Specific proposals for new or existing BDK Rust features or modules to improve and maintain")]),i._v(" "),e("li",[i._v("Engagement with upstream projects (e.g., rust-bitcoin, rust-miniscript, uniffi-rs)")]),i._v(" "),e("li",[i._v("Involvement with downstream projects utilizing BDK")]),i._v(" "),e("li",[i._v("Understanding of or experience with related protocols (e.g., Lightning, e-cash)")]),i._v(" "),e("li",[i._v("Active participation in your local Bitcoin community")]),i._v(" "),e("li",[i._v("Potential to start or work for a project/company using BDK in the future")])]),i._v(" "),e("h2",{attrs:{id:"proposal-guidelines"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#proposal-guidelines"}},[i._v("#")]),i._v(" Proposal Guidelines")]),i._v(" "),e("p",[i._v("Your grant proposal should include:")]),i._v(" "),e("ul",[e("li",[i._v("Your background and relevant experience in Rust and Bitcoin development")]),i._v(" "),e("li",[i._v("Examples of your contributions to open source projects, particularly in the Bitcoin ecosystem")]),i._v(" "),e("li",[i._v("Your vision for maintaining and improving the BDK Rust codebase")]),i._v(" "),e("li",[i._v("Specific ideas or proposals for features or modules you want to work on")]),i._v(" "),e("li",[i._v("How you plan to engage with the broader BDK and Bitcoin developer community")]),i._v(" "),e("li",[i._v("Any additional skills or experiences that align with the BDK Foundation's mission and goals")])]),i._v(" "),e("h2",{attrs:{id:"evaluation-criteria"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#evaluation-criteria"}},[i._v("#")]),i._v(" Evaluation Criteria")]),i._v(" "),e("p",[i._v("Proposals will be evaluated based on the applicant's technical skills, open source contribution history, alignment with the BDK Foundation's mission, and potential impact on the BDK ecosystem.")]),i._v(" "),e("h2",{attrs:{id:"submission-process"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#submission-process"}},[i._v("#")]),i._v(" Submission Process")]),i._v(" "),e("p",[i._v("Please send your detailed grant proposal to "),e("a",{attrs:{href:"mailto:grants@bitcoindevkit.org"}},[i._v("grants@bitcoindevkit.org")]),i._v('. Include "Full-Time Rust Maintainer Grant Proposal" in the subject line.')]),i._v(" "),e("p",[i._v("The BDK Foundation is committed to supporting diverse voices in the Bitcoin development community. We encourage applications from all backgrounds to apply.")]),i._v(" "),e("p",[i._v("For more information about the BDK Foundation and our grants program, please visit our "),e("a",{attrs:{href:"https://bitcoindevkit.org",target:"_blank",rel:"noopener noreferrer"}},[i._v("website"),e("OutboundLink")],1),i._v(". We look forward to reviewing your proposals and welcoming a new member to our team of open source developers working to improve Bitcoin application security, privacy, and usability.")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{401:function(i,e,t){"use strict";t.r(e);var o=t(7),n=Object(o.a)({},(function(){var i=this,e=i._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":i.$parent.slotKey}},[e("p",[i._v("The Bitcoin Dev Kit (BDK) Foundation is seeking proposals for a full-time Rust maintainer to support the ongoing development and maintenance of the BDK suite of open source software. We invite qualified individuals to submit grant applications for this critical role.")]),i._v(" "),e("h2",{attrs:{id:"grant-overview"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grant-overview"}},[i._v("#")]),i._v(" Grant Overview")]),i._v(" "),e("p",[i._v("Position: Open source Rust library maintainer"),e("br"),i._v("\nDuration: Minimum 1-2 years, full-time commitment"),e("br"),i._v("\nFocus: Maintaining and improving the BDK Rust codebase")]),i._v(" "),e("h2",{attrs:{id:"key-requirements"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#key-requirements"}},[i._v("#")]),i._v(" Key Requirements")]),i._v(" "),e("ul",[e("li",[i._v("Strong Rust development skills with experience in API design and usage")]),i._v(" "),e("li",[i._v("Demonstrated ability to contribute to open source projects, particularly in the Bitcoin ecosystem")]),i._v(" "),e("li",[i._v("Solid understanding of Bitcoin on-chain protocols and technology")]),i._v(" "),e("li",[i._v("Excellent communication skills and ability to work effectively in a team")]),i._v(" "),e("li",[i._v("Commitment to mentoring and supporting other developers in the BDK and Bitcoin community")]),i._v(" "),e("li",[i._v("Willingness to contribute to non-coding aspects of the project (e.g., documentation, CI, release management)")])]),i._v(" "),e("h2",{attrs:{id:"desired-qualifications"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#desired-qualifications"}},[i._v("#")]),i._v(" Desired Qualifications")]),i._v(" "),e("ul",[e("li",[i._v("Vision for maintaining and improving the overall BDK Rust codebase")]),i._v(" "),e("li",[i._v("Specific proposals for new or existing BDK Rust features or modules to improve and maintain")]),i._v(" "),e("li",[i._v("Engagement with upstream projects (e.g., rust-bitcoin, rust-miniscript, uniffi-rs)")]),i._v(" "),e("li",[i._v("Involvement with downstream projects utilizing BDK")]),i._v(" "),e("li",[i._v("Understanding of or experience with related protocols (e.g., Lightning, e-cash)")]),i._v(" "),e("li",[i._v("Active participation in your local Bitcoin community")]),i._v(" "),e("li",[i._v("Potential to start or work for a project/company using BDK in the future")])]),i._v(" "),e("h2",{attrs:{id:"proposal-guidelines"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#proposal-guidelines"}},[i._v("#")]),i._v(" Proposal Guidelines")]),i._v(" "),e("p",[i._v("Your grant proposal should include:")]),i._v(" "),e("ul",[e("li",[i._v("Your background and relevant experience in Rust and Bitcoin development")]),i._v(" "),e("li",[i._v("Examples of your contributions to open source projects, particularly in the Bitcoin ecosystem")]),i._v(" "),e("li",[i._v("Your vision for maintaining and improving the BDK Rust codebase")]),i._v(" "),e("li",[i._v("Specific ideas or proposals for features or modules you want to work on")]),i._v(" "),e("li",[i._v("How you plan to engage with the broader BDK and Bitcoin developer community")]),i._v(" "),e("li",[i._v("Any additional skills or experiences that align with the BDK Foundation's mission and goals")])]),i._v(" "),e("h2",{attrs:{id:"evaluation-criteria"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#evaluation-criteria"}},[i._v("#")]),i._v(" Evaluation Criteria")]),i._v(" "),e("p",[i._v("Proposals will be evaluated based on the applicant's technical skills, open source contribution history, alignment with the BDK Foundation's mission, and potential impact on the BDK ecosystem.")]),i._v(" "),e("h2",{attrs:{id:"submission-process"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#submission-process"}},[i._v("#")]),i._v(" Submission Process")]),i._v(" "),e("p",[i._v("Please send your detailed grant proposal to "),e("a",{attrs:{href:"mailto:grants@bitcoindevkit.org"}},[i._v("grants@bitcoindevkit.org")]),i._v('. Include "Full-Time Rust Maintainer Grant Proposal" in the subject line.')]),i._v(" "),e("p",[i._v("The BDK Foundation is committed to supporting diverse voices in the Bitcoin development community. We encourage applications from all backgrounds to apply.")]),i._v(" "),e("p",[i._v("For more information about the BDK Foundation and our grants program, please visit our "),e("a",{attrs:{href:"https://bitcoindevkit.org",target:"_blank",rel:"noopener noreferrer"}},[i._v("website"),e("OutboundLink")],1),i._v(". We look forward to reviewing your proposals and welcoming a new member to our team of open source developers working to improve Bitcoin application security, privacy, and usability.")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/50.b7380ea9.js b/assets/js/50.cf7b9b4d.js similarity index 86% rename from assets/js/50.b7380ea9.js rename to assets/js/50.cf7b9b4d.js index 9bd36562c1..dc17f23bca 100644 --- a/assets/js/50.b7380ea9.js +++ b/assets/js/50.cf7b9b4d.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{403:function(e,t,a){"use strict";a.r(t);var n=a(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("The bitcoindevkit team has been hard at work for Q3 in 2024, polishing the API of our "),t("code",[e._v("bdk_wallet")]),e._v(" crate and releasing 4 new beta versions (1, 2, 3, and 4!), and aiming to release a final 1.0 release by the end of 2024. Here are some of the notable changes and upgrades to the software libraries we maintain:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("RBF by default on TxBuilder.")]),e._v(" The transaction builder in BDK will now signal RBF by default.")]),e._v(" "),t("li",[t("strong",[e._v("New wallet builder API.")]),e._v(" The new wallet builder offers flexibility and ease-of-development for future features. We've also been listening to user feedback, and brought back support for single-descriptor wallets.")]),e._v(" "),t("li",[t("strong",[e._v("MVP of the Book of BDK.")]),e._v(" We are working on a high-level documentation website for BDK libraries called the Book of BDK. The MVP website is live at "),t("a",{attrs:{href:"https://bookofbdk.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bookofbdk.com"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("li",[t("strong",[e._v("Bug chasing and optimizations.")]),e._v(" As feedback from early testers comes in, we are keeping a close eye on reported bugs and questions, and have been fixing a ton of smaller but very important snags!")]),e._v(" "),t("li",[t("strong",[e._v("Development of a CBF client crate and related bindings.")]),e._v(" Work is ongoing on a crate to allow BDK users to interoperate with a new CBF library called "),t("a",{attrs:{href:"https://github.com/rustaceanrob/kyoto",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kyoto"),t("OutboundLink")],1),e._v(". Work has been done to integrate this with the language bindings for mobile users, and the preliminary integrations have been very positive.")])]),e._v(" "),t("p",[e._v("The language bindings for iOS, Android, and Python have also seen some new beta releases and a ton of new features, in preparation for the 1.0 final release.")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Exposing a much larger number of Wallet APIs.")]),e._v(" The Wallet type in the language bindings now exposes most of what users will need for a 1.0 release.")]),e._v(" "),t("li",[t("strong",[e._v("Rework of the Kotlin and Swift build systems.")]),e._v(" We have migrated the build workflows for bdk-jvm and bdk-android from Gradle scripts to shell scripts, making them easier to parse and consume for contributors and other libraries wanting to leverage our approach to bindings. We have also made it much easier to build the Swift package for iOS users.")]),e._v(" "),t("li",[t("strong",[e._v("Testing of Compact Block Filters for both Android and iOS.")]),e._v(" Both our wallet examples have full examples of using the new "),t("a",{attrs:{href:"https://github.com/rustaceanrob/kyoto",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kyoto"),t("OutboundLink")],1),e._v(" client on mobile phones. Once the PR for the new client lands, users will have access to clear examples on how to leverage the new client!")]),e._v(" "),t("li",[t("strong",[e._v("Building bitcoin-ffi.")]),e._v(" The team has been working on a crate called "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin-ffi"),t("OutboundLink")],1),e._v(", migrating the types we exposed from rust-bitcoin into a standalone crate that other projects building on uniffi can use. We have been stress-testing this in production and are finding new ways to leverage this approach.")])]),e._v(" "),t("h3",{attrs:{id:"our-grantees-in-action"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#our-grantees-in-action"}},[e._v("#")]),e._v(" Our Grantees in Action")]),e._v(" "),t("p",[e._v("Full-time grants changes:")]),e._v(" "),t("ul",[t("li",[e._v("Our lead Rust developer Evan is moving to a part-time grant while he goes and works for a company that leverages BDK!\nIn addition to our full-time grantees, the "),t("a",{attrs:{href:"https://bitcoindevkit.org/foundation/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK Foundation"),t("OutboundLink")],1),e._v(" provides part-time grants to folks on special projects. Q3 is funding 2 projects in particular:")]),e._v(" "),t("li",[t("strong",[e._v("Leonardo.")]),e._v(" "),t("a",{attrs:{href:""}},[e._v("Leo")]),e._v("'s been working on our integration of the Tor Rust client into the Electrum and Esplora crates.")]),e._v(" "),t("li",[t("strong",[e._v("Rob.")]),e._v(" "),t("a",{attrs:{href:""}},[e._v("Rob")]),e._v(" is the brain behind the "),t("a",{attrs:{href:""}},[e._v("Kyoto")]),e._v(" client, its BDK integration with "),t("code",[e._v("bdk_kyoto")]),e._v(", and the PR to wrap it all up into our language bindings!")]),e._v(" "),t("li",[t("strong",[e._v("Wei Chen.")]),e._v(" "),t("a",{attrs:{href:"https://github.com/LagginTimes",target:"_blank",rel:"noopener noreferrer"}},[e._v("Wei"),t("OutboundLink")],1),e._v(" is continuing his work on the lower-level BDK crates "),t("code",[e._v("bdk_chain")]),e._v(" and "),t("code",[e._v("bdk_core")]),e._v(", as well as his work on the Electrum client.")])]),e._v(" "),t("p",[e._v("We've also been active at conferences!")]),e._v(" "),t("ul",[t("li",[e._v("Steve "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=Qlbwxbe7xHE",target:"_blank",rel:"noopener noreferrer"}},[e._v("was on a panel at the 2024 Bitcoin Conference"),t("OutboundLink")],1),e._v(" discussing with 2 teams that are building on BDK.")]),e._v(" "),t("li",[e._v('The team was in Nashville for a week of hard work and collaboration between devs in the Rust bitcoin ecosystem we called the "Rust Bitcoin Summit". The event was so successful we\'re hoping to do it again next year! Here is a link to a '),t("a",{attrs:{href:"https://serve.podhome.fm/episodepage/CitadelDispatch/cd136-rust-bitcoin-summit-with-poelstra-harding-myers-corallo-and-more",target:"_blank",rel:"noopener noreferrer"}},[e._v("Citadel Dispatch podcast"),t("OutboundLink")],1),e._v(" with some of the devs who hosted and participated.")])]),e._v(" "),t("h3",{attrs:{id:"bdk-in-the-wild"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-in-the-wild"}},[e._v("#")]),e._v(" BDK in the Wild")]),e._v(" "),t("p",[e._v("In Q3, a number of new projects have started using BDK:")]),e._v(" "),t("ul",[t("li",[e._v("The Protonmail team has released the latest tool in the Proton family: the "),t("a",{attrs:{href:"https://proton.me/blog/proton-wallet-launch",target:"_blank",rel:"noopener noreferrer"}},[e._v("Proton Bitcoin Wallet App"),t("OutboundLink")],1),e._v(". The wallet is using the 1.0 beta version of the library. Welcome aboard Proton!")]),e._v(" "),t("li",[e._v("The "),t("a",{attrs:{href:""}},[e._v("bark Ark implementation")]),e._v(" started using the BDK beta releases for its wallet implementation.")]),e._v(" "),t("li",[t("a",{attrs:{href:""}},[e._v("Bitcoin Safe")]),e._v(" released its first beta release.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.satsails.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Satsails"),t("OutboundLink")],1),e._v(" is now live on the Play Store!")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.stratabtc.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Strata"),t("OutboundLink")],1),e._v(" has released a devnet version of their CLI wallet, which uses BDK.")]),e._v(" "),t("li",[e._v("Our BDK Swift Example Wallet is "),t("a",{attrs:{href:"https://testflight.apple.com/join/A3nAuYvZ",target:"_blank",rel:"noopener noreferrer"}},[e._v("now available on iOS Testflight"),t("OutboundLink")],1),e._v("!")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{405:function(e,t,n){"use strict";n.r(t);var a=n(7),o=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("The bitcoindevkit team has been hard at work for Q3 in 2024, polishing the API of our "),t("code",[e._v("bdk_wallet")]),e._v(" crate and releasing 4 new beta versions (1, 2, 3, and 4!), and aiming to release a final 1.0 release by the end of 2024. Here are some of the notable changes and upgrades to the software libraries we maintain:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("RBF by default on TxBuilder.")]),e._v(" The transaction builder in BDK will now signal RBF by default.")]),e._v(" "),t("li",[t("strong",[e._v("New wallet builder API.")]),e._v(" The new wallet builder offers flexibility and ease-of-development for future features. We've also been listening to user feedback, and brought back support for single-descriptor wallets.")]),e._v(" "),t("li",[t("strong",[e._v("MVP of the Book of BDK.")]),e._v(" We are working on a high-level documentation website for BDK libraries called the Book of BDK. The MVP website is live at "),t("a",{attrs:{href:"https://bookofbdk.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bookofbdk.com"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("li",[t("strong",[e._v("Bug chasing and optimizations.")]),e._v(" As feedback from early testers comes in, we are keeping a close eye on reported bugs and questions, and have been fixing a ton of smaller but very important snags!")]),e._v(" "),t("li",[t("strong",[e._v("Development of a CBF client crate and related bindings.")]),e._v(" Work is ongoing on a crate to allow BDK users to interoperate with a new CBF library called "),t("a",{attrs:{href:"https://github.com/rustaceanrob/kyoto",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kyoto"),t("OutboundLink")],1),e._v(". Work has been done to integrate this with the language bindings for mobile users, and the preliminary integrations have been very positive.")])]),e._v(" "),t("p",[e._v("The language bindings for iOS, Android, and Python have also seen some new beta releases and a ton of new features, in preparation for the 1.0 final release.")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("Exposing a much larger number of Wallet APIs.")]),e._v(" The Wallet type in the language bindings now exposes most of what users will need for a 1.0 release.")]),e._v(" "),t("li",[t("strong",[e._v("Rework of the Kotlin and Swift build systems.")]),e._v(" We have migrated the build workflows for bdk-jvm and bdk-android from Gradle scripts to shell scripts, making them easier to parse and consume for contributors and other libraries wanting to leverage our approach to bindings. We have also made it much easier to build the Swift package for iOS users.")]),e._v(" "),t("li",[t("strong",[e._v("Testing of Compact Block Filters for both Android and iOS.")]),e._v(" Both our wallet examples have full examples of using the new "),t("a",{attrs:{href:"https://github.com/rustaceanrob/kyoto",target:"_blank",rel:"noopener noreferrer"}},[e._v("Kyoto"),t("OutboundLink")],1),e._v(" client on mobile phones. Once the PR for the new client lands, users will have access to clear examples on how to leverage the new client!")]),e._v(" "),t("li",[t("strong",[e._v("Building bitcoin-ffi.")]),e._v(" The team has been working on a crate called "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin-ffi"),t("OutboundLink")],1),e._v(", migrating the types we exposed from rust-bitcoin into a standalone crate that other projects building on uniffi can use. We have been stress-testing this in production and are finding new ways to leverage this approach.")])]),e._v(" "),t("h3",{attrs:{id:"our-grantees-in-action"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#our-grantees-in-action"}},[e._v("#")]),e._v(" Our Grantees in Action")]),e._v(" "),t("p",[e._v("Full-time grants changes:")]),e._v(" "),t("ul",[t("li",[e._v("Our lead Rust developer Evan is moving to a part-time grant while he goes and works for a company that leverages BDK!\nIn addition to our full-time grantees, the "),t("a",{attrs:{href:"https://bitcoindevkit.org/foundation/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK Foundation"),t("OutboundLink")],1),e._v(" provides part-time grants to folks on special projects. Q3 is funding 2 projects in particular:")]),e._v(" "),t("li",[t("strong",[e._v("Leonardo.")]),e._v(" "),t("a",{attrs:{href:""}},[e._v("Leo")]),e._v("'s been working on our integration of the Tor Rust client into the Electrum and Esplora crates.")]),e._v(" "),t("li",[t("strong",[e._v("Rob.")]),e._v(" "),t("a",{attrs:{href:""}},[e._v("Rob")]),e._v(" is the brain behind the "),t("a",{attrs:{href:""}},[e._v("Kyoto")]),e._v(" client, its BDK integration with "),t("code",[e._v("bdk_kyoto")]),e._v(", and the PR to wrap it all up into our language bindings!")]),e._v(" "),t("li",[t("strong",[e._v("Wei Chen.")]),e._v(" "),t("a",{attrs:{href:"https://github.com/LagginTimes",target:"_blank",rel:"noopener noreferrer"}},[e._v("Wei"),t("OutboundLink")],1),e._v(" is continuing his work on the lower-level BDK crates "),t("code",[e._v("bdk_chain")]),e._v(" and "),t("code",[e._v("bdk_core")]),e._v(", as well as his work on the Electrum client.")])]),e._v(" "),t("p",[e._v("We've also been active at conferences!")]),e._v(" "),t("ul",[t("li",[e._v("Steve "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=Qlbwxbe7xHE",target:"_blank",rel:"noopener noreferrer"}},[e._v("was on a panel at the 2024 Bitcoin Conference"),t("OutboundLink")],1),e._v(" discussing with 2 teams that are building on BDK.")]),e._v(" "),t("li",[e._v('The team was in Nashville for a week of hard work and collaboration between devs in the Rust bitcoin ecosystem we called the "Rust Bitcoin Summit". The event was so successful we\'re hoping to do it again next year! Here is a link to a '),t("a",{attrs:{href:"https://serve.podhome.fm/episodepage/CitadelDispatch/cd136-rust-bitcoin-summit-with-poelstra-harding-myers-corallo-and-more",target:"_blank",rel:"noopener noreferrer"}},[e._v("Citadel Dispatch podcast"),t("OutboundLink")],1),e._v(" with some of the devs who hosted and participated.")])]),e._v(" "),t("h3",{attrs:{id:"bdk-in-the-wild"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-in-the-wild"}},[e._v("#")]),e._v(" BDK in the Wild")]),e._v(" "),t("p",[e._v("In Q3, a number of new projects have started using BDK:")]),e._v(" "),t("ul",[t("li",[e._v("The Protonmail team has released the latest tool in the Proton family: the "),t("a",{attrs:{href:"https://proton.me/blog/proton-wallet-launch",target:"_blank",rel:"noopener noreferrer"}},[e._v("Proton Bitcoin Wallet App"),t("OutboundLink")],1),e._v(". The wallet is using the 1.0 beta version of the library. Welcome aboard Proton!")]),e._v(" "),t("li",[e._v("The "),t("a",{attrs:{href:""}},[e._v("bark Ark implementation")]),e._v(" started using the BDK beta releases for its wallet implementation.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://bitcoin-safe.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Safe"),t("OutboundLink")],1),e._v(" released its first beta release.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.satsails.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Satsails"),t("OutboundLink")],1),e._v(" is now live on the Play Store!")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.stratabtc.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Strata"),t("OutboundLink")],1),e._v(" has released a devnet version of their CLI wallet, which uses BDK.")]),e._v(" "),t("li",[e._v("Our BDK Swift Example Wallet is "),t("a",{attrs:{href:"https://testflight.apple.com/join/A3nAuYvZ",target:"_blank",rel:"noopener noreferrer"}},[e._v("now available on iOS Testflight"),t("OutboundLink")],1),e._v("!")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/51.d80754c0.js b/assets/js/51.8de4cf97.js similarity index 99% rename from assets/js/51.d80754c0.js rename to assets/js/51.8de4cf97.js index 8495c3acf4..4566fcb827 100644 --- a/assets/js/51.d80754c0.js +++ b/assets/js/51.8de4cf97.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{405:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("BDK wallet developer library can be used to easily deploy wallets with various kinds of blockchain backend support, like "),s("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("electrum")]),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("esplora")]),s("OutboundLink")],1),t._v(", "),s("code",[t._v("compact-filters")]),t._v(" ("),s("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP157"),s("OutboundLink")],1),t._v(") etc. With the latest release of BDK "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v0.10.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.10.0")]),s("OutboundLink")],1),t._v(", BDK now supports Bitcoin Core as a blockchain backend. BDK talks with Bitcoin Core using rust-bitcoin's "),s("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoincore-rpc",target:"_blank",rel:"noopener noreferrer"}},[t._v("bitcoincore-rpc"),s("OutboundLink")],1),t._v(" library.")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("Unlike other tutorials, we will not use "),s("code",[t._v("bdk-cli")]),t._v(" tools, but instead write rust code directly using "),s("code",[t._v("BDK")]),t._v(" devkit. In the end we will end up with our own simple bitcoin wallet.")]),t._v(" "),s("h2",{attrs:{id:"prerequisite"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisite"}},[t._v("#")]),t._v(" Prerequisite")]),t._v(" "),s("p",[t._v("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 "),s("a",{attrs:{href:"https://bitcoincore.org/bin/bitcoin-core-0.21.1/",target:"_blank",rel:"noopener noreferrer"}},[t._v("bitcoin core repo"),s("OutboundLink")],1),t._v(" or "),s("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/v0.21.1/doc/build-unix.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("build from source"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("Then configure the node with a following "),s("code",[t._v("bitcoin.conf")]),t._v(" file")]),t._v(" "),s("div",{staticClass:"language-txt extra-class"},[s("pre",{pre:!0,attrs:{class:"language-txt"}},[s("code",[t._v("regtest=1\nfallbackfee=0.0001\nserver=1\ntxindex=1\nrpcuser=admin\nrpcpassword=password\n")])])]),s("p",[t._v("Apart from that, you would need to install rust in your system. Grab the installation one-liner from "),s("a",{attrs:{href:"https://www.rust-lang.org/tools/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"setting-up"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),s("p",[t._v("Create a new cargo binary repository.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdir")]),t._v(" ~/tutorial\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" tutorial\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" new bdk-example\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-example\n")])])]),s("p",[t._v("This will create a new project folder named "),s("code",[t._v("bdk-example")]),t._v(" with "),s("code",[t._v("src/main.rs")]),t._v(" and a "),s("code",[t._v("cargo.toml")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ tree "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-L")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v("\n├── Cargo.toml\n└── src\n └── main.rs\n\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" directory, "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" files\n")])])]),s("p",[t._v("Opening "),s("code",[t._v("main.rs")]),t._v(" you will see some predefined code like this")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, world!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Try running "),s("code",[t._v("cargo run")]),t._v(' and if everything is set, you should see "Hello, world!" printed in your terminal')]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n Compiling bdk-example v0.1.0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("/home/raj/github-repo/tutorial/bdk-example"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Finished dev "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("unoptimized + debuginfo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(".95s\n Running "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("target/debug/bdk-example"),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v("\nHello, world"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n")])])]),s("p",[t._v("Of course we will not use the given "),s("code",[t._v("println!()")]),t._v(" statement, but we will put our main code in the "),s("code",[t._v("main()")]),t._v(" function.")]),t._v(" "),s("p",[s("code",[t._v("cargo new")]),t._v(" will also produce a skeleton "),s("code",[t._v("Cargo.toml")]),t._v(" file like this")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("package")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("name")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-example"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.1.0"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("edition")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2018"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("h2",{attrs:{id:"setting-dependencies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-dependencies"}},[t._v("#")]),t._v(" Setting dependencies")]),t._v(" "),s("p",[t._v("Once the rust binary is compiled and running, we now need to specify the dependencies we need to work on our library.")]),t._v(" "),s("p",[t._v("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 "),s("a",{attrs:{href:"https://crates.io/crates/dirs-next",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("dirs_next")]),s("OutboundLink")],1),t._v(" to find our home directory and store wallet files in a subfolder there.")]),t._v(" "),s("p",[t._v("Add the dependencies into "),s("code",[t._v("Cargo.toml")]),t._v(" like below")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("package")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("name")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-example"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.1.0"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("edition")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2018"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.10"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"all-keys"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key-value-db"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"rpc"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("dirs-next")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.0"')]),t._v("\n")])])]),s("p",[t._v("We disabled the default BDK feature (which specifies blockchain backend as an electrum server) and we requested the following features:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("all-keys")]),t._v(": Adds BIP39 key derivation capabilities")]),t._v(" "),s("li",[s("strong",[t._v("key-value-db")]),t._v(": Adds a persistence storage capability")]),t._v(" "),s("li",[s("strong",[t._v("rpc")]),t._v(": Adds the RPC blockchain backend capability.")])]),t._v(" "),s("p",[t._v("Now that we have the dependencies added, we can import them in the "),s("code",[t._v("main.rs")]),t._v(" file to use in our code.\nAdd the following imports at the start of "),s("code",[t._v("main.rs")])]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("secp256k1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoincore_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcApi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet_name_from_descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip39"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("With this we are now ready to add our wallet code.")]),t._v(" "),s("h2",{attrs:{id:"getting-descriptors"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getting-descriptors"}},[t._v("#")]),t._v(" Getting Descriptors")]),t._v(" "),s("p",[t._v("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 "),s("a",{attrs:{href:"https://bitcoindevkit.org/descriptors/",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),s("OutboundLink")],1),t._v(". A descriptor string looks like this\n"),s("code",[t._v("\"wpkh([b8b575c2/84'/1'/0'/0]tprv8icWtRzy9CWgFxpGMLSdAeE4wWyz39XGc6SwykeTo13tYm14JkVVQAf7jz8WDDarCgNJrG3aEPJEqchDWeJdiaWpS3FwbLB9SzsN57V7qxB/*)\"")]),t._v(".")]),t._v(" "),s("p",[t._v("This describes a SegwitV0 descriptor of a key derived at path "),s("code",[t._v("m/84'/1'/0'/0")]),t._v(". 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 "),s("code",[t._v("wpkh()")]),t._v(" string.")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("Add a function named "),s("code",[t._v("get-descriptor()")]),t._v(" below the "),s("code",[t._v("main()")]),t._v(" function as shown")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// generate fresh descriptor strings and return them via (receive, change) tuple")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a new secp context")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" secp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can also set a password to unlock the mnemonic")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"random password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate a fresh mnemonic, and from there a privatekey")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Words12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("English")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_extended_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_xprv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create derived privkey from the above master privkey")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// We use the following derivation paths for receive and change keys")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// receive: "m/84h/1h/0h/0"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// change: "m/84h/1h/0h/1" ')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" keys "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" path "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("derive_priv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fingerprint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv_desc_key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n derived_xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_descriptor_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Wrap the derived key with the wpkh() string to produce a descriptor string")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" derived_xprv_desc_key "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" desc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('")"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Return the keys as a tuple")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("To check that the above added function is working as expected, call it in the main function and print the descriptors")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"recv: {:#?}, \\nchng: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Running the binary should produce the following result")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\nrecv: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh([89df6a67/84'/1'/0'/0]tprv8iSRXyLtTKJN9qt1jyPVqwhDMEaYztXunPaRQznaH1z8gj8e2g7RnF2ZoHP56VEXwMn76AiV1Je6nJmZbFistwAQCrRGmSrsoKfdqfTDNA1/*)\"")]),t._v(", \nchng: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh([89df6a67/84'/1'/0'/1]tprv8iSRXyLtTKJNCECQxBJ19cgx2ueS7mC7GNq7VqTWY3RNPMBY7DfTb9HUnXpJqa14jCJNRmi4yGxfoTVS4WLBXDkvTLq4vujeAD9NfDtSxGP/*)\"")]),t._v("\n")])])]),s("p",[t._v("Voila! Now we have nice descriptors strings handy to use for our BDK wallet construction.")]),t._v(" "),s("h2",{attrs:{id:"talking-to-bitcoin-core-programmatically"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#talking-to-bitcoin-core-programmatically"}},[t._v("#")]),t._v(" Talking to Bitcoin Core Programmatically")]),t._v(" "),s("p",[t._v("Like all other tutorials we will use two wallets to send coins back and forth. A Bitcoin Core wallet accessible via "),s("code",[t._v("bitcoin-cli")]),t._v(" command line tools, and a BDK wallet maintained by BDK library.")]),t._v(" "),s("p",[t._v("But unlike other tutorials, we won't be using "),s("code",[t._v("bitcoin-cli")]),t._v(" to talk to the Core wallet (we can, but let's spice things up). Instead, we will use the "),s("code",[t._v("bitcoin-rpc")]),t._v(" library, to talk with our core node listening at "),s("code",[t._v("127.0.0.1:18443")]),t._v(", 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!")]),t._v(" "),s("p",[t._v("Remember we imported "),s("code",[t._v("use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};")]),t._v("? Thats exactly for this purpose.")]),t._v(" "),s("p",[t._v("Start the "),s("code",[t._v("bitcoind")]),t._v(" node.")]),t._v(" "),s("p",[t._v("you should see bitcoind listening at port 18443")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("netstat")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-nptl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grep")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("18443")]),t._v(" \ntcp "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),t._v(".0.0:18443 "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),t._v(".0.0:* LISTEN "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("135532")]),t._v("/bitcoind \n")])])]),s("p",[t._v("Lets create a core rpc interface in our main function.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a RPC interface")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_rpc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://127.0.0.1:18443/wallet/test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_blockchain_info")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("We have provided our RPC authentication "),s("code",[t._v("username")]),t._v(" and "),s("code",[t._v("password")]),t._v(" (same as provided in "),s("code",[t._v("bitcoin.conf")]),t._v(" file).\nWe have provided the RPC address of our local bitcoin node, with the path to a wallet file, named "),s("code",[t._v("test")]),t._v(". And then asked the rpc client to give us the current blockchain info.\nIf everything goes well, running "),s("code",[t._v("cargo run")]),t._v(" you should see an output like below:")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nGetBlockchainInfoResult "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n chain: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"regtest"')]),t._v(",\n blocks: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n headers: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n best_block_hash: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206,\n difficulty: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.00000000046565423739069247")]),t._v(",\n median_time: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1296688602")]),t._v(",\n verification_progress: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(",\n initial_block_download: true,\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\n")])])]),s("p",[t._v("Thats it. Now we can programmatically talk to our core node.")]),t._v(" "),s("h2",{attrs:{id:"get-some-balance-in-core-wallet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#get-some-balance-in-core-wallet"}},[t._v("#")]),t._v(" Get some balance in core wallet.")]),t._v(" "),s("p",[t._v("We have told our rpc client that we would use a wallet named "),s("code",[t._v("test")]),t._v(". But currently, our core node doesn't have such a wallet. So let's create the wallet and fund it with some test coins.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the test wallet ")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get a new address")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_new_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate 101 blocks and use the above address as coinbase")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("101")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// fetch the new balance")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Show balance")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"core balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("This will create a wallet in bitcoin core named "),s("code",[t._v("test")]),t._v(". 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.\nThe last "),s("code",[t._v("println!()")]),t._v(" statement will show the new updated balance as 50 BTC.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\ncore balance: Amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50.00000000")]),t._v(" BTC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" \n")])])]),s("p",[t._v("Great! We now have 50 regtest BTC to play with.")]),t._v(" "),s("h2",{attrs:{id:"setup-the-bdk-wallet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setup-the-bdk-wallet"}},[t._v("#")]),t._v(" Setup the BDK wallet")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[s("strong",[t._v("Note")]),t._v(": You might want to comment out the previous code in "),s("code",[t._v("main()")]),t._v(", as running them again will create more coins in core, which isn't an issue, but might be confusing.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get receive and change descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use deterministic wallet name derived from descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("wallet_name_from_descriptor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the datadir to store wallet data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" datadir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("dirs_next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("home_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('".bdk-example"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" database "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_tree "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open_tree")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set RPC username, password and url")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n username"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" rpc_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:18443"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Setup the RPC configuration")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n skip_blocks"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the above configuration to create a RPC blockchain backend")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("rpc_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Combine everything and finally create the BDK wallet structure")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" db_tree"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch a fresh address to receive coins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk address: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("That's a lot of code. They are divided into logical sections. Let's discuss each step one by one.")]),t._v(" "),s("ul",[s("li",[t._v("First we used our previous "),s("code",[t._v("get_descriptors()")]),t._v(" function to generate two descriptor strings. One for generating receive addresses and one for change addresses.")]),t._v(" "),s("li",[t._v("Then we used a special function from BDK called "),s("code",[t._v("wallet_name_from_descriptor()")]),t._v(" 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 "),s("code",[t._v("test")]),t._v(" wallet, we could also access this wallet.")]),t._v(" "),s("li",[t._v("Then we created a data directory at path "),s("code",[t._v("/home/username/.bdk-example")]),t._v(". We use "),s("code",[t._v("dirs_next")]),t._v(" to find our home path, and then appended that with "),s("code",[t._v(".bdk-example")]),t._v(". All the BDK wallet files will be created and maintained in that directory. In the Database we instructed BDK to create a new "),s("code",[t._v("Tree")]),t._v(" with "),s("code",[t._v("wallet_name")]),t._v(", so given a descriptor, BDK will always know which DB Tree to refer ("),s("code",[t._v("Tree")]),t._v(" is a "),s("code",[t._v("sled")]),t._v(" specific term).")]),t._v(" "),s("li",[t._v("Then like we did previously, we created the rpc username/password authentication, and specified the rpc url. Note that we cannot use the same "),s("code",[t._v("rpc_auth")]),t._v(" we used before for "),s("code",[t._v("core_rpc")]),t._v(" as BDK auth and bitcoin-rpc auth are slightly separate structures.")]),t._v(" "),s("li",[t._v("We combined all this information and created an "),s("code",[t._v("RpcConfig")]),t._v(" structure.")]),t._v(" "),s("li",[t._v("We used the rpc configuration to create a "),s("code",[t._v("RpcBlockchain")]),t._v(" structure.")]),t._v(" "),s("li",[t._v("Finally we used the Descriptors, Database, and Blockchain to create our final BDK "),s("code",[t._v("wallet")]),t._v(" structure.")])]),t._v(" "),s("p",[t._v("Now that we have our wallet cooked, in the end, we instructed it to sync with the bitcoin core backend, and fetch us a new address.")]),t._v(" "),s("p",[t._v("If all goes well, you should see an address printed in the terminal.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n Finished dev "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("unoptimized + debuginfo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(".99s\n Running "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("target/debug/bdk-example"),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v("\nbdk address: bcrt1q9vkmujggvzs0rd4z6069v3v0jucje7ua7ap308\n")])])]),s("h2",{attrs:{id:"sending-sats-around"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sending-sats-around"}},[t._v("#")]),t._v(" Sending Sats Around")]),t._v(" "),s("p",[t._v("Now that we have covered all the groundwork, we have all we need to send coins back and forth between core and BDK wallet.")]),t._v(" "),s("p",[t._v("We will keep things simple here and make the following actions")]),t._v(" "),s("ul",[s("li",[t._v("Send 10 BTC from Core to BDK")]),t._v(" "),s("li",[t._v("Send back 5 BTC from BDK to Core")]),t._v(" "),s("li",[t._v("Display balance of two wallets")])]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch a fresh address to receive coins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Send 10 BTC from Core to BDK")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_btc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a transaction builder")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tx_builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set recipient of the transaction")]),t._v("\n tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set_recipients")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finalise the transaction and extract PSBT")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set signing option")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" signopt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n assume_height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sign the above psbt with signing option")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" signopt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Extract the final transaction")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Broadcast the transaction")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch and display wallet balances")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bdk_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"core wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BDK wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bdk_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The above code segment is mostly straightforward. The only new thing added is "),s("code",[t._v("wallet.build_tx()")]),t._v(" which returns a "),s("code",[t._v("TxBuilder")]),t._v(". 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 "),s("code",[t._v("TxBuilder")]),t._v(" supports scour its implementation "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/38d1d0b0e29d38cd370c740d798d96a3c9fcaa1f/src/wallet/tx_builder.rs#L123-L153",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("Finally to step through what we did above:")]),t._v(" "),s("ul",[s("li",[t._v("We asked core wallet to send 10 BTC to bdk wallet address.")]),t._v(" "),s("li",[t._v("We confirmed the transaction, and synced the wallet.")]),t._v(" "),s("li",[t._v("We asked BDK to create a transaction sending 5 BTC to core wallet address.")]),t._v(" "),s("li",[t._v("We signed and broadcast the transaction. BDK will use the same core node to broadcast the transaction to network.")]),t._v(" "),s("li",[t._v("We confirmed the transaction by mining a block, and synced the wallet.")]),t._v(" "),s("li",[t._v("We fetched and displayed balance of both core and BDK wallet.")])]),t._v(" "),s("p",[t._v("If all goes well, you should see the final updated balance as below:")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n Compiling bdk-example v0.1.0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("/home/raj/github-repo/bdk-example/bdk-example"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Finished dev "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("unoptimized + debuginfo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(".57s\n Running "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("target/debug/bdk-example"),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v("\ncore wallet balance: Amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("144.99998590")]),t._v(" BTC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nBDK wallet balance: Amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.99999859")]),t._v(" BTC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("Check out the data directory where BDK has created the wallet data files.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ls")]),t._v(" ~/.bdk-example/\nblobs conf db snap.0000000000023CAB\n")])])]),s("p",[t._v("And finally, this is what the final "),s("code",[t._v("main.rs")]),t._v(" file looks like.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("secp256k1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoincore_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcApi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet_name_from_descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip39"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a RPC interface")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_rpc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://127.0.0.1:18443/wallet/test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the test wallet ")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get a new address")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_new_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate 101 blocks and use the above address as coinbase")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("101")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get receive and change descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use deterministic wallet name derived from descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("wallet_name_from_descriptor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the datadir to store wallet data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" datadir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("dirs_next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("home_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('".bdk-example"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" database "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_tree "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open_tree")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set RPC username and password")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n username"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set RPC url")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" rpc_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:18443"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Setup the RPC configuration")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n skip_blocks"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the above configuration to create a RPC blockchain backend")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("rpc_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Combine everything and finally create the BDK wallet structure")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" db_tree"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch a fresh address to receive coins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Send 10 BTC from Core to BDK")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_btc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a transaction builder")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tx_builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set recipient of the transaction")]),t._v("\n tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set_recipients")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finalise the transaction and extract PSBT")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set signing option")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" signopt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n assume_height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sign the above psbt with signing option")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" signopt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Extract the final transaction")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Broadcast the transaction")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch and display wallet balances")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bdk_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"core wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BDK wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bdk_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// generate fresh descriptor strings and return them via (receive, change) tupple ")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a new secp context")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" secp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can also set a password to unlock the mnemonic")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"random password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate a fresh menmonic, and from their, a fresh private key xprv")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Words12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("English")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_extended_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_xprv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Derive our descriptors to use")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// We use the following paths for recieve and change descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// recieve: "m/84h/1h/0h/0"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// change: "m/84h/1h/0h/1" ')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" keys "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" path "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("derive_priv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fingerprint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv_desc_key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n derived_xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_descriptor_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Wrap the derived key with the wpkh() string to produce a descriptor string")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" derived_xprv_desc_key "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" desc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('")"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Return the keys as a tupple")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"conclusion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),s("p",[t._v("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).")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("To find and explore more about the BDK capabilities and how it can fit your development need refer the following resources.")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[t._v("source code"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/",target:"_blank",rel:"noopener noreferrer"}},[t._v("dev docs"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://discord.com/invite/d7NkDKm",target:"_blank",rel:"noopener noreferrer"}},[t._v("community"),s("OutboundLink")],1)])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{403:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("BDK wallet developer library can be used to easily deploy wallets with various kinds of blockchain backend support, like "),s("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("electrum")]),s("OutboundLink")],1),t._v(", "),s("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("esplora")]),s("OutboundLink")],1),t._v(", "),s("code",[t._v("compact-filters")]),t._v(" ("),s("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP157"),s("OutboundLink")],1),t._v(") etc. With the latest release of BDK "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v0.10.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.10.0")]),s("OutboundLink")],1),t._v(", BDK now supports Bitcoin Core as a blockchain backend. BDK talks with Bitcoin Core using rust-bitcoin's "),s("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoincore-rpc",target:"_blank",rel:"noopener noreferrer"}},[t._v("bitcoincore-rpc"),s("OutboundLink")],1),t._v(" library.")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("Unlike other tutorials, we will not use "),s("code",[t._v("bdk-cli")]),t._v(" tools, but instead write rust code directly using "),s("code",[t._v("BDK")]),t._v(" devkit. In the end we will end up with our own simple bitcoin wallet.")]),t._v(" "),s("h2",{attrs:{id:"prerequisite"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisite"}},[t._v("#")]),t._v(" Prerequisite")]),t._v(" "),s("p",[t._v("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 "),s("a",{attrs:{href:"https://bitcoincore.org/bin/bitcoin-core-0.21.1/",target:"_blank",rel:"noopener noreferrer"}},[t._v("bitcoin core repo"),s("OutboundLink")],1),t._v(" or "),s("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/v0.21.1/doc/build-unix.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("build from source"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("Then configure the node with a following "),s("code",[t._v("bitcoin.conf")]),t._v(" file")]),t._v(" "),s("div",{staticClass:"language-txt extra-class"},[s("pre",{pre:!0,attrs:{class:"language-txt"}},[s("code",[t._v("regtest=1\nfallbackfee=0.0001\nserver=1\ntxindex=1\nrpcuser=admin\nrpcpassword=password\n")])])]),s("p",[t._v("Apart from that, you would need to install rust in your system. Grab the installation one-liner from "),s("a",{attrs:{href:"https://www.rust-lang.org/tools/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"setting-up"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),s("p",[t._v("Create a new cargo binary repository.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdir")]),t._v(" ~/tutorial\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" tutorial\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" new bdk-example\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-example\n")])])]),s("p",[t._v("This will create a new project folder named "),s("code",[t._v("bdk-example")]),t._v(" with "),s("code",[t._v("src/main.rs")]),t._v(" and a "),s("code",[t._v("cargo.toml")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ tree "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-L")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v("\n├── Cargo.toml\n└── src\n └── main.rs\n\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" directory, "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" files\n")])])]),s("p",[t._v("Opening "),s("code",[t._v("main.rs")]),t._v(" you will see some predefined code like this")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, world!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Try running "),s("code",[t._v("cargo run")]),t._v(' and if everything is set, you should see "Hello, world!" printed in your terminal')]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n Compiling bdk-example v0.1.0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("/home/raj/github-repo/tutorial/bdk-example"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Finished dev "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("unoptimized + debuginfo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(".95s\n Running "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("target/debug/bdk-example"),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v("\nHello, world"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n")])])]),s("p",[t._v("Of course we will not use the given "),s("code",[t._v("println!()")]),t._v(" statement, but we will put our main code in the "),s("code",[t._v("main()")]),t._v(" function.")]),t._v(" "),s("p",[s("code",[t._v("cargo new")]),t._v(" will also produce a skeleton "),s("code",[t._v("Cargo.toml")]),t._v(" file like this")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("package")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("name")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-example"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.1.0"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("edition")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2018"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("h2",{attrs:{id:"setting-dependencies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-dependencies"}},[t._v("#")]),t._v(" Setting dependencies")]),t._v(" "),s("p",[t._v("Once the rust binary is compiled and running, we now need to specify the dependencies we need to work on our library.")]),t._v(" "),s("p",[t._v("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 "),s("a",{attrs:{href:"https://crates.io/crates/dirs-next",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("dirs_next")]),s("OutboundLink")],1),t._v(" to find our home directory and store wallet files in a subfolder there.")]),t._v(" "),s("p",[t._v("Add the dependencies into "),s("code",[t._v("Cargo.toml")]),t._v(" like below")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("package")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("name")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-example"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.1.0"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("edition")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2018"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.10"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"all-keys"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key-value-db"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"rpc"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("dirs-next")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.0"')]),t._v("\n")])])]),s("p",[t._v("We disabled the default BDK feature (which specifies blockchain backend as an electrum server) and we requested the following features:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("all-keys")]),t._v(": Adds BIP39 key derivation capabilities")]),t._v(" "),s("li",[s("strong",[t._v("key-value-db")]),t._v(": Adds a persistence storage capability")]),t._v(" "),s("li",[s("strong",[t._v("rpc")]),t._v(": Adds the RPC blockchain backend capability.")])]),t._v(" "),s("p",[t._v("Now that we have the dependencies added, we can import them in the "),s("code",[t._v("main.rs")]),t._v(" file to use in our code.\nAdd the following imports at the start of "),s("code",[t._v("main.rs")])]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("secp256k1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoincore_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcApi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet_name_from_descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip39"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("With this we are now ready to add our wallet code.")]),t._v(" "),s("h2",{attrs:{id:"getting-descriptors"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getting-descriptors"}},[t._v("#")]),t._v(" Getting Descriptors")]),t._v(" "),s("p",[t._v("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 "),s("a",{attrs:{href:"https://bitcoindevkit.org/descriptors/",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),s("OutboundLink")],1),t._v(". A descriptor string looks like this\n"),s("code",[t._v("\"wpkh([b8b575c2/84'/1'/0'/0]tprv8icWtRzy9CWgFxpGMLSdAeE4wWyz39XGc6SwykeTo13tYm14JkVVQAf7jz8WDDarCgNJrG3aEPJEqchDWeJdiaWpS3FwbLB9SzsN57V7qxB/*)\"")]),t._v(".")]),t._v(" "),s("p",[t._v("This describes a SegwitV0 descriptor of a key derived at path "),s("code",[t._v("m/84'/1'/0'/0")]),t._v(". 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 "),s("code",[t._v("wpkh()")]),t._v(" string.")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("Add a function named "),s("code",[t._v("get-descriptor()")]),t._v(" below the "),s("code",[t._v("main()")]),t._v(" function as shown")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// generate fresh descriptor strings and return them via (receive, change) tuple")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a new secp context")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" secp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can also set a password to unlock the mnemonic")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"random password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate a fresh mnemonic, and from there a privatekey")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Words12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("English")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_extended_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_xprv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create derived privkey from the above master privkey")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// We use the following derivation paths for receive and change keys")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// receive: "m/84h/1h/0h/0"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// change: "m/84h/1h/0h/1" ')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" keys "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" path "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("derive_priv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fingerprint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv_desc_key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n derived_xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_descriptor_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Wrap the derived key with the wpkh() string to produce a descriptor string")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" derived_xprv_desc_key "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" desc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('")"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Return the keys as a tuple")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("To check that the above added function is working as expected, call it in the main function and print the descriptors")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"recv: {:#?}, \\nchng: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Running the binary should produce the following result")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\nrecv: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh([89df6a67/84'/1'/0'/0]tprv8iSRXyLtTKJN9qt1jyPVqwhDMEaYztXunPaRQznaH1z8gj8e2g7RnF2ZoHP56VEXwMn76AiV1Je6nJmZbFistwAQCrRGmSrsoKfdqfTDNA1/*)\"")]),t._v(", \nchng: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh([89df6a67/84'/1'/0'/1]tprv8iSRXyLtTKJNCECQxBJ19cgx2ueS7mC7GNq7VqTWY3RNPMBY7DfTb9HUnXpJqa14jCJNRmi4yGxfoTVS4WLBXDkvTLq4vujeAD9NfDtSxGP/*)\"")]),t._v("\n")])])]),s("p",[t._v("Voila! Now we have nice descriptors strings handy to use for our BDK wallet construction.")]),t._v(" "),s("h2",{attrs:{id:"talking-to-bitcoin-core-programmatically"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#talking-to-bitcoin-core-programmatically"}},[t._v("#")]),t._v(" Talking to Bitcoin Core Programmatically")]),t._v(" "),s("p",[t._v("Like all other tutorials we will use two wallets to send coins back and forth. A Bitcoin Core wallet accessible via "),s("code",[t._v("bitcoin-cli")]),t._v(" command line tools, and a BDK wallet maintained by BDK library.")]),t._v(" "),s("p",[t._v("But unlike other tutorials, we won't be using "),s("code",[t._v("bitcoin-cli")]),t._v(" to talk to the Core wallet (we can, but let's spice things up). Instead, we will use the "),s("code",[t._v("bitcoin-rpc")]),t._v(" library, to talk with our core node listening at "),s("code",[t._v("127.0.0.1:18443")]),t._v(", 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!")]),t._v(" "),s("p",[t._v("Remember we imported "),s("code",[t._v("use bdk::bitcoincore_rpc::{Auth as rpc_auth, Client, RpcApi};")]),t._v("? Thats exactly for this purpose.")]),t._v(" "),s("p",[t._v("Start the "),s("code",[t._v("bitcoind")]),t._v(" node.")]),t._v(" "),s("p",[t._v("you should see bitcoind listening at port 18443")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("netstat")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-nptl")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grep")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("18443")]),t._v(" \ntcp "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),t._v(".0.0:18443 "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),t._v(".0.0:* LISTEN "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("135532")]),t._v("/bitcoind \n")])])]),s("p",[t._v("Lets create a core rpc interface in our main function.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a RPC interface")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_rpc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://127.0.0.1:18443/wallet/test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_blockchain_info")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("We have provided our RPC authentication "),s("code",[t._v("username")]),t._v(" and "),s("code",[t._v("password")]),t._v(" (same as provided in "),s("code",[t._v("bitcoin.conf")]),t._v(" file).\nWe have provided the RPC address of our local bitcoin node, with the path to a wallet file, named "),s("code",[t._v("test")]),t._v(". And then asked the rpc client to give us the current blockchain info.\nIf everything goes well, running "),s("code",[t._v("cargo run")]),t._v(" you should see an output like below:")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nGetBlockchainInfoResult "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n chain: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"regtest"')]),t._v(",\n blocks: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n headers: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n best_block_hash: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206,\n difficulty: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.00000000046565423739069247")]),t._v(",\n median_time: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1296688602")]),t._v(",\n verification_progress: "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(",\n initial_block_download: true,\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\n")])])]),s("p",[t._v("Thats it. Now we can programmatically talk to our core node.")]),t._v(" "),s("h2",{attrs:{id:"get-some-balance-in-core-wallet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#get-some-balance-in-core-wallet"}},[t._v("#")]),t._v(" Get some balance in core wallet.")]),t._v(" "),s("p",[t._v("We have told our rpc client that we would use a wallet named "),s("code",[t._v("test")]),t._v(". But currently, our core node doesn't have such a wallet. So let's create the wallet and fund it with some test coins.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the test wallet ")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get a new address")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_new_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate 101 blocks and use the above address as coinbase")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("101")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// fetch the new balance")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Show balance")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"core balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("This will create a wallet in bitcoin core named "),s("code",[t._v("test")]),t._v(". 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.\nThe last "),s("code",[t._v("println!()")]),t._v(" statement will show the new updated balance as 50 BTC.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\ncore balance: Amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50.00000000")]),t._v(" BTC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" \n")])])]),s("p",[t._v("Great! We now have 50 regtest BTC to play with.")]),t._v(" "),s("h2",{attrs:{id:"setup-the-bdk-wallet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setup-the-bdk-wallet"}},[t._v("#")]),t._v(" Setup the BDK wallet")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[s("strong",[t._v("Note")]),t._v(": You might want to comment out the previous code in "),s("code",[t._v("main()")]),t._v(", as running them again will create more coins in core, which isn't an issue, but might be confusing.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get receive and change descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use deterministic wallet name derived from descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("wallet_name_from_descriptor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the datadir to store wallet data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" datadir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("dirs_next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("home_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('".bdk-example"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" database "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_tree "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open_tree")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set RPC username, password and url")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n username"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" rpc_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:18443"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Setup the RPC configuration")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n skip_blocks"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the above configuration to create a RPC blockchain backend")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("rpc_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Combine everything and finally create the BDK wallet structure")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" db_tree"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch a fresh address to receive coins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk address: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("That's a lot of code. They are divided into logical sections. Let's discuss each step one by one.")]),t._v(" "),s("ul",[s("li",[t._v("First we used our previous "),s("code",[t._v("get_descriptors()")]),t._v(" function to generate two descriptor strings. One for generating receive addresses and one for change addresses.")]),t._v(" "),s("li",[t._v("Then we used a special function from BDK called "),s("code",[t._v("wallet_name_from_descriptor()")]),t._v(" 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 "),s("code",[t._v("test")]),t._v(" wallet, we could also access this wallet.")]),t._v(" "),s("li",[t._v("Then we created a data directory at path "),s("code",[t._v("/home/username/.bdk-example")]),t._v(". We use "),s("code",[t._v("dirs_next")]),t._v(" to find our home path, and then appended that with "),s("code",[t._v(".bdk-example")]),t._v(". All the BDK wallet files will be created and maintained in that directory. In the Database we instructed BDK to create a new "),s("code",[t._v("Tree")]),t._v(" with "),s("code",[t._v("wallet_name")]),t._v(", so given a descriptor, BDK will always know which DB Tree to refer ("),s("code",[t._v("Tree")]),t._v(" is a "),s("code",[t._v("sled")]),t._v(" specific term).")]),t._v(" "),s("li",[t._v("Then like we did previously, we created the rpc username/password authentication, and specified the rpc url. Note that we cannot use the same "),s("code",[t._v("rpc_auth")]),t._v(" we used before for "),s("code",[t._v("core_rpc")]),t._v(" as BDK auth and bitcoin-rpc auth are slightly separate structures.")]),t._v(" "),s("li",[t._v("We combined all this information and created an "),s("code",[t._v("RpcConfig")]),t._v(" structure.")]),t._v(" "),s("li",[t._v("We used the rpc configuration to create a "),s("code",[t._v("RpcBlockchain")]),t._v(" structure.")]),t._v(" "),s("li",[t._v("Finally we used the Descriptors, Database, and Blockchain to create our final BDK "),s("code",[t._v("wallet")]),t._v(" structure.")])]),t._v(" "),s("p",[t._v("Now that we have our wallet cooked, in the end, we instructed it to sync with the bitcoin core backend, and fetch us a new address.")]),t._v(" "),s("p",[t._v("If all goes well, you should see an address printed in the terminal.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n Finished dev "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("unoptimized + debuginfo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(".99s\n Running "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("target/debug/bdk-example"),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v("\nbdk address: bcrt1q9vkmujggvzs0rd4z6069v3v0jucje7ua7ap308\n")])])]),s("h2",{attrs:{id:"sending-sats-around"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sending-sats-around"}},[t._v("#")]),t._v(" Sending Sats Around")]),t._v(" "),s("p",[t._v("Now that we have covered all the groundwork, we have all we need to send coins back and forth between core and BDK wallet.")]),t._v(" "),s("p",[t._v("We will keep things simple here and make the following actions")]),t._v(" "),s("ul",[s("li",[t._v("Send 10 BTC from Core to BDK")]),t._v(" "),s("li",[t._v("Send back 5 BTC from BDK to Core")]),t._v(" "),s("li",[t._v("Display balance of two wallets")])]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch a fresh address to receive coins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Send 10 BTC from Core to BDK")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_btc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a transaction builder")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tx_builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set recipient of the transaction")]),t._v("\n tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set_recipients")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finalise the transaction and extract PSBT")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set signing option")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" signopt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n assume_height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sign the above psbt with signing option")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" signopt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Extract the final transaction")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Broadcast the transaction")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch and display wallet balances")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bdk_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"core wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BDK wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bdk_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The above code segment is mostly straightforward. The only new thing added is "),s("code",[t._v("wallet.build_tx()")]),t._v(" which returns a "),s("code",[t._v("TxBuilder")]),t._v(". 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 "),s("code",[t._v("TxBuilder")]),t._v(" supports scour its implementation "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/38d1d0b0e29d38cd370c740d798d96a3c9fcaa1f/src/wallet/tx_builder.rs#L123-L153",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("Finally to step through what we did above:")]),t._v(" "),s("ul",[s("li",[t._v("We asked core wallet to send 10 BTC to bdk wallet address.")]),t._v(" "),s("li",[t._v("We confirmed the transaction, and synced the wallet.")]),t._v(" "),s("li",[t._v("We asked BDK to create a transaction sending 5 BTC to core wallet address.")]),t._v(" "),s("li",[t._v("We signed and broadcast the transaction. BDK will use the same core node to broadcast the transaction to network.")]),t._v(" "),s("li",[t._v("We confirmed the transaction by mining a block, and synced the wallet.")]),t._v(" "),s("li",[t._v("We fetched and displayed balance of both core and BDK wallet.")])]),t._v(" "),s("p",[t._v("If all goes well, you should see the final updated balance as below:")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n Compiling bdk-example v0.1.0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("/home/raj/github-repo/bdk-example/bdk-example"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n Finished dev "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("unoptimized + debuginfo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(".57s\n Running "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("target/debug/bdk-example"),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v("\ncore wallet balance: Amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("144.99998590")]),t._v(" BTC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nBDK wallet balance: Amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.99999859")]),t._v(" BTC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("Check out the data directory where BDK has created the wallet data files.")]),t._v(" "),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ls")]),t._v(" ~/.bdk-example/\nblobs conf db snap.0000000000023CAB\n")])])]),s("p",[t._v("And finally, this is what the final "),s("code",[t._v("main.rs")]),t._v(" file looks like.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("secp256k1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoincore_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcApi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet_name_from_descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip39"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivableKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("miniscript"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a RPC interface")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_rpc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://127.0.0.1:18443/wallet/test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rpc_auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the test wallet ")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get a new address")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_new_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate 101 blocks and use the above address as coinbase")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("101")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get receive and change descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use deterministic wallet name derived from descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("wallet_name_from_descriptor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create the datadir to store wallet data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" datadir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("dirs_next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("home_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('".bdk-example"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" database "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("datadir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" db_tree "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open_tree")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set RPC username and password")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" auth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserPass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n username"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set RPC url")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" rpc_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:18443"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Setup the RPC configuration")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" rpc_config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" rpc_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n auth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n wallet_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n skip_blocks"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the above configuration to create a RPC blockchain backend")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("rpc_config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Combine everything and finally create the BDK wallet structure")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("receive_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("change_desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" db_tree"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch a fresh address to receive coins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Send 10 BTC from Core to BDK")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_btc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a transaction builder")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tx_builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set recipient of the transaction")]),t._v("\n tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("set_recipients")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Finalise the transaction and extract PSBT")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tx_builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set signing option")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" signopt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n assume_height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sign the above psbt with signing option")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" signopt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Extract the final transaction")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" tx "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Broadcast the transaction")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Confirm transaction by generating some blocks")]),t._v("\n core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_to_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("core_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Sync the BDK wallet")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoopProgress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fetch and display wallet balances")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" core_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" core_rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" bdk_balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Amount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"core wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" core_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BDK wallet balance: {:#?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bdk_balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// generate fresh descriptor strings and return them via (receive, change) tupple ")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create a new secp context")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" secp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secp256k1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can also set a password to unlock the mnemonic")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"random password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate a fresh menmonic, and from their, a fresh private key xprv")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratedKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MnemonicType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Words12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("English")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_extended_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" xkey"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_xprv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Regtest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Derive our descriptors to use")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// We use the following paths for recieve and change descriptor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// recieve: "m/84h/1h/0h/0"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// change: "m/84h/1h/0h/1" ')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" keys "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vec")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" path "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"m/84h/1h/0h/1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("derive_priv")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fingerprint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("secp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" deriv_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" derived_xprv_desc_key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n derived_xprv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_descriptor_key")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("origin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Wrap the derived key with the wpkh() string to produce a descriptor string")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" derived_xprv_desc_key "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" desc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('")"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("desc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Return the keys as a tupple")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" keys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"conclusion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),s("p",[t._v("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).")]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("To find and explore more about the BDK capabilities and how it can fit your development need refer the following resources.")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[t._v("source code"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/",target:"_blank",rel:"noopener noreferrer"}},[t._v("dev docs"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://discord.com/invite/d7NkDKm",target:"_blank",rel:"noopener noreferrer"}},[t._v("community"),s("OutboundLink")],1)])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/53.08f20b3c.js b/assets/js/53.185fde0b.js similarity index 99% rename from assets/js/53.08f20b3c.js rename to assets/js/53.185fde0b.js index 182845b178..20e580b331 100644 --- a/assets/js/53.08f20b3c.js +++ b/assets/js/53.185fde0b.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{408:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"tutorial-goals"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tutorial-goals"}},[t._v("#")]),t._v(" Tutorial Goals")]),t._v(" "),e("ul",[e("li",[e("p",[t._v("The goal for this tutorial is to introduce you to "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-cli"),e("OutboundLink")],1),t._v(", a powerful command-line program. You will be exposed to many of the basic skills that go into creating and managing bitcoin wallets.")])]),t._v(" "),e("li",[e("p",[t._v("If you've read most of the "),e("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook",target:"_blank",rel:"noopener noreferrer"}},[t._v('"Mastering Bitcoin"'),e("OutboundLink")],1),t._v(" book, this tutorial could serve as a stepping stone into your Bitcoin wallet development journey.")])]),t._v(" "),e("li",[e("p",[t._v("This short tutorial will expose you to the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("bdk library")]),t._v(" "),e("OutboundLink")],1),t._v(" and the practical knowledge needed for bitcoin wallet development. As a consequence you will deepen your technical understanding about bitcoin and the bdk library.")])]),t._v(" "),e("li",[e("p",[t._v("BDK also has "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[t._v("language-bindings"),e("OutboundLink")],1),t._v(" for "),e("strong",[t._v("Kotlin/Java, Swift, Python")]),t._v(" which enable the use of BDK's "),e("strong",[t._v("Rust")]),t._v(" library as an API. You can later use these similar steps to create your own bitcoin mobile, desktop or even WebApp by using the bdk-ffi language bindings.")])])]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"a-few-things-before-you-begin"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-few-things-before-you-begin"}},[t._v("#")]),t._v(" A few things before you begin:")]),t._v(" "),e("ul",[e("li",[t._v("Three things to look out for in each step of the tutorial:\n"),e("ul",[e("li",[e("ol",[e("li",[t._v("▶️ / 🔶 - Commands for the Terminal or Shell")])])]),t._v(" "),e("li",[e("ol",{attrs:{start:"2"}},[e("li",[t._v("👍 - Preview of the command output. Note, not all commands will output code.")])])]),t._v(" "),e("li",[e("ol",{attrs:{start:"3"}},[e("li",[t._v("Preview Video of the tutorial for reference of what things should look like in action.")])])])])])]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"outline-of-tutorial-and-installation-notes"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#outline-of-tutorial-and-installation-notes"}},[t._v("#")]),t._v(" Outline of Tutorial and Installation notes:")]),t._v(" "),e("h3",{attrs:{id:"brief-outline-of-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#brief-outline-of-tutorial"}},[t._v("#")]),t._v(" Brief Outline of Tutorial")]),t._v(" "),e("ul",[e("li",[t._v("Step 1: Creating a mnemonic word list + XPRV (Extended Private Key)")]),t._v(" "),e("li",[t._v("Step 2: Generate testnet Receive Address")]),t._v(" "),e("li",[t._v("Step 3: Send funds to newly generated address")]),t._v(" "),e("li",[t._v("Step 4: Sync Wallet")]),t._v(" "),e("li",[t._v("Step 5: Check Balance of Wallet")]),t._v(" "),e("li",[t._v("Step 6: Create a Transaction (PSBT)")]),t._v(" "),e("li",[t._v("Step 7: Sign the Transaction (PSBT)")]),t._v(" "),e("li",[t._v("Step 8: Broadcast Transaction")])]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"rust-and-cargo-installation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#rust-and-cargo-installation"}},[t._v("#")]),t._v(" Rust and Cargo installation:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://rustup.rs/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust and Cargo Installation"),e("OutboundLink")],1)])]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"bdk-cli-installation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-cli-installation"}},[t._v("#")]),t._v(" "),e("code",[t._v("bdk-cli")]),t._v(" installation:")]),t._v(" "),e("ul",[e("li",[t._v("Download the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli.git",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("bdk-cli")]),t._v(" github repository locally"),e("OutboundLink")],1),t._v(" "),e("ul",[e("li",[t._v("Enter the folder "),e("code",[t._v("cd bdk-cli")])]),t._v(" "),e("li",[t._v("Install "),e("code",[t._v("cargo install --path . --features electrum,repl,compiler")])]),t._v(" "),e("li",[t._v("Once installation is done exit and reopen your terminal (command-line interface)")])])])]),t._v(" "),e("h3",{attrs:{id:"emoji-legend"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#emoji-legend"}},[t._v("#")]),t._v(" Emoji Legend:")]),t._v(" "),e("p",[t._v("▶️ : Unix/Linux Commands to copied and pasted\n🔶 : Windows Powershell Commands to copied and pasted\n👍 : Output/ preview of code")]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-0-check-version-of-bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-0-check-version-of-bdk-cli"}},[t._v("#")]),t._v(" Step 0: Check Version of bdk-cli")]),t._v(" "),e("p",[t._v("▶️ / 🔶 "),e("code",[t._v("bdk-cli -V")]),t._v("\n👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("bdk-cli 0.6.0\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/IcuyeMS.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"preview-of-bdk-cli-help-menu"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#preview-of-bdk-cli-help-menu"}},[t._v("#")]),t._v(" Preview of bdk-cli help menu")]),t._v(" "),e("p",[t._v("▶️ / 🔶 "),e("code",[t._v("bdk-cli --help")]),e("br"),t._v("\n👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[t._v("The BDK Command Line Wallet App\n\nbdk-cli is a light weight "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("command")]),t._v(" line bitcoin wallet, powered by BDK. This app can be used as a playground as well as\ntesting environment to simulate various wallet testing situations. If you are planning to use BDK "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" your wallet, bdk-\ncli is also a great intro tool to get familiar with the BDK API.\n\nBut this is not just any toy. bdk-cli is also a fully functioning bitcoin wallet with taproot support"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n\nFor "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("more")]),t._v(" information checkout "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("https://bitcoindevkit.org/"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\nUSAGE:\n bdk-cli "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("OPTIONS"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("SUBCOMMAND"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\nFLAGS:\n -h, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--help")]),t._v(" Prints "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("help")]),t._v(" information\n -V, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--version")]),t._v(" Prints version information\n\nOPTIONS:\n -d, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--datadir")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("DATADIR"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" Sets the wallet data directory. Default value "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(' "~/.bdk-bitcoin\n -n, '),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--network")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("NETWORK"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" Sets the network "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("default: testnet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("possible values: bitcoin, testnet, signet, regtest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\nSUBCOMMANDS:\n compile Compile a miniscript policy to an output descriptor\n "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("help")]),t._v(" Prints this message or the "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("help")]),t._v(" of the given subcommand"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n key Subcommands "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" Key operations\n repl Options to configure a SOCKS5 proxy "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" a blockchain client connection\n wallet Wallet subcommands that can be issued without a blockchain backend\n")])])]),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-1-seed-generate"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-1-seed-generate"}},[t._v("#")]),t._v(" Step 1: Seed Generate")]),t._v(" "),e("h3",{attrs:{id:"1a-mnemonic-word-list-xprv-extended-private-key-"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1a-mnemonic-word-list-xprv-extended-private-key-"}},[t._v("#")]),t._v(" 1a: Mnemonic word-list + XPRV (Extended Private Key) 🔑")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli key generate | tee key.json")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v('bdk-cli key generate | Out-File -FilePath "key.json"')])]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"fingerprint"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"42b15d2f"')]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mnemonic"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"party salon worth satoshi envelope suggest garlic dry add pitch throw clap keen narrow antique oyster ketchup purchase gasp visual work venue fog crater"')]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"xprv"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tprv8ZgxMBicQKsPdwpamtjqMFpYRTafnE1bN2SphLEybCtRKakk6S1TgQCsZgiBwJuJNWe3jYdgVCTsKf9weMxj6tW4zNNKWptykszJpS2L8wE"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/ii62Hul.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1b-save-xprv-extended-private-key-into-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1b-save-xprv-extended-private-key-into-environment-variable"}},[t._v("#")]),t._v(" 1b: Save XPRV (Extended Private Key) into environment variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("export XPRV_00=$(cat key.json | jq -r .xprv)")])]),t._v(" "),e("p",[t._v("Windows Powershell:")]),t._v(" "),e("p",[t._v("🔶 "),e("code",[t._v("$json = Get-Content -Path .\\key.json | ConvertFrom-Json")])]),t._v(" "),e("p",[t._v("🔶 "),e("code",[t._v("$mykeyValue = $json.xprv")])]),t._v(" "),e("p",[t._v("🔶 "),e("code",[t._v("[System.Environment]::SetEnvironmentVariable('XPRV',$mykeyValue, 'Process')")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/KYW2Cdo.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1c-verify-environment-variable-xprv-00-is-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1c-verify-environment-variable-xprv-00-is-active"}},[t._v("#")]),t._v(" 1c: Verify environment variable XPRV_00 is active")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("env | grep XPRV")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("$env:XPRV")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/ZahbJwe.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1d-create-descriptor-and-save-into-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1d-create-descriptor-and-save-into-environment-variable"}},[t._v("#")]),t._v(" 1d: Create Descriptor and Save into environment variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v('export my_descriptor="wpkh($XPRV_00/84h/1h/0h/0/*)"')])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("[System.Environment]::SetEnvironmentVariable('my_descriptor', \"wpkh($env:XPRV/84h/1h/0h/0/*)\", 'Process')")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/UV4Vgsq.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1e-verify-environment-variable-my-descriptor-is-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1e-verify-environment-variable-my-descriptor-is-active"}},[t._v("#")]),t._v(" 1e: Verify environment variable my_descriptor is active")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("env | grep my_descriptor")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("$env:my_descriptor")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/s7ZeRQN.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-2-generate-receive-address"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-2-generate-receive-address"}},[t._v("#")]),t._v(" Step 2: Generate Receive-Address")]),t._v(" "),e("p",[t._v("Linux/Terminal:")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor get_new_address")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor get_new_address")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/P8PjTAo.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"address"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1qrh4sq5va0unqtxyfv8al9lz3sna3988cj59uya"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-3-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-3-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[t._v("#")]),t._v(" Step 3: Send testnet bitcoin to the newly created receive-address")]),t._v(" "),e("p",[t._v("Use a faucet to send funds to your newly created address. Here is a link to one: "),e("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Testnet Faucet"),e("OutboundLink")],1)]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-4-sync-the-wallet"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-4-sync-the-wallet"}},[t._v("#")]),t._v(" Step 4: Sync the wallet")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor sync")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor sync")])]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/WFYBgVB.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-5-check-the-balance"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-5-check-the-balance"}},[t._v("#")]),t._v(" Step 5: Check the balance")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor get_balance")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor get_balance")])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[t._v("Note: The balance will only show after the transaction has been confirmed in a block at least once.")])]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful:")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"confirmed"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100000")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"immature"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"trusted_pending"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"untrusted_pending"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/v8MAYB2.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-6-create-transaction-psbt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-6-create-transaction-psbt"}},[t._v("#")]),t._v(" Step 6: Create Transaction (PSBT)")]),t._v(" "),e("p",[t._v("To create a PSBT (partially-signed-bitcoin-transaction) run the command:")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor create_tx --to tb1qw2c3lxufxqe2x9s4rdzh65tpf4d7fssjgh8nv6:50000")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor create_tx --to tb1qjk6n943uwhqhdf7en600tnwxpslvwtr0udsehp:0 --send_all")]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/EUCovcJ.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"details"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"confirmation_time"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" null,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"fee"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("113")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"received"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sent"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("123000")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"transaction"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" null,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"029173d76253e3441f9dc26f91e6ef30dff486848e91a7941f0cacd0af25ee30"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cHNidP8BAFUBAAAAAak8uMR3UGkAGUKWsq8Mv45qg2fdD93JQRIsa2P0wFloAQAAAAD/////AQfgAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA3gIAAAAAAQFY9sVfEEbyjrHXSlxXDxL+71WOMnsPpVElwk+3E/J9vAAAAAAA/v///wIYZRIAAAAAABYAFBKYf7yF+ss6EFdw2rDZTfdLhep8eOABAAAAAAAWABQd6wBRnX8mBZiJYfvy/FGE+xKc+AJHMEQCIFSIkvEUI9yUgEw4JocRs1aiVsBlKKXrOQaQb3XFqR21AiBqiEVzCVVSRGjckyPDgAQBnOdSzBYR6Rw6KFcCP+E27wEhAwIlXdfM2WYnYa36Hp4MS6YkplBAgBsb1tYG9NiWFWTKzPYhAAEBH3jgAQAAAAAAFgAUHesAUZ1/JgWYiWH78vxRhPsSnPgiBgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6SxgTizKsVAAAgAEAAIAAAACAAAAAAAAAAAAAAA=="')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h3",{attrs:{id:"6a-export-psbt-to-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#6a-export-psbt-to-environment-variable"}},[t._v("#")]),t._v(" 6a: export PSBT to environment-variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v('export PSBT="PASTE_PSBT_HERE"')])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶"),e("code",[t._v("[System.Environment]::SetEnvironmentVariable('PSBT',\"PASTE_PSBT_HERE\",'Process')")]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/CEDKcPZ.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-7-sign-transaction-psbt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-7-sign-transaction-psbt"}},[t._v("#")]),t._v(" Step 7: Sign Transaction (PSBT)")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor sign --psbt $PSBT")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor sign --psbt $env:PSBT")])]),t._v(" "),e("ul",[e("li",[t._v("DON'T FORGET to COPY the PSBT for the next step")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/f4o4Ce8.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"is_finalized"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" true,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cHNidP8BAFUBAAAAAak8uMR3UGkAGUKWsq8Mv45qg2fdD93JQRIsa2P0wFloAQAAAAD/////AQfgAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA3gIAAAAAAQFY9sVfEEbyjrHXSlxXDxL+71WOMnsPpVElwk+3E/J9vAAAAAAA/v///wIYZRIAAAAAABYAFBKYf7yF+ss6EFdw2rDZTfdLhep8eOABAAAAAAAWABQd6wBRnX8mBZiJYfvy/FGE+xKc+AJHMEQCIFSIkvEUI9yUgEw4JocRs1aiVsBlKKXrOQaQb3XFqR21AiBqiEVzCVVSRGjckyPDgAQBnOdSzBYR6Rw6KFcCP+E27wEhAwIlXdfM2WYnYa36Hp4MS6YkplBAgBsb1tYG9NiWFWTKzPYhAAEBH3jgAQAAAAAAFgAUHesAUZ1/JgWYiWH78vxRhPsSnPgiAgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6S0gwRQIhALWkBRSJzxuf0od4tPu3qFmEfJ2Y+/QBGtfjSFObWsPeAiA4QJx8Rk5pacrjHv5EOdw6RNHXcdtepFs+m0/Za/h0UQEiBgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6SxgTizKsVAAAgAEAAIAAAACAAAAAAAAAAAABBwABCGwCSDBFAiEAtaQFFInPG5/Sh3i0+7eoWYR8nZj79AEa1+NIU5taw94CIDhAnHxGTmlpyuMe/kQ53DpE0ddx216kWz6bT9lr+HRRASED/NBaWlmEMxswpzSPW5V23outWKQJraHszEcaVbwSeksAAA=="')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h3",{attrs:{id:"7a-export-signed-psbt-to-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#7a-export-signed-psbt-to-environment-variable"}},[t._v("#")]),t._v(" 7a: export signed psbt to environment variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v('export SIGNED_PSBT="Paste_PSBT_HERE"')])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v('$env:PSBTSIGNED = "STRINGHERE"')]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/VJsl8zR.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-8-broadcast-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-8-broadcast-transaction"}},[t._v("#")]),t._v(" Step 8: Broadcast Transaction")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor broadcast --psbt $SIGNED_PSBT")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor broadcast --psbt $env:PSBTSIGNED")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/yQZZk0d.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a0877b7ce91ea6d141ba63277673f5bdf0edfdd45f91a39ba1a1ace15f839b52"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Verify transaction in the memory pool on testnet "),e("a",{attrs:{href:"https://mempool.space/testnet",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mempool-testnet!"),e("OutboundLink")],1)])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[t._v("Run sync one more time and see that the balance has decreased.")])]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"resources"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#resources"}},[t._v("#")]),t._v(" Resources")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP-32: Hierarchical Deterministic Wallets"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 39 - Mnemonic code for generating deterministic keys"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 44 - Multi-Account Hierarchy for Deterministic Wallets"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 84 - Derivation scheme for P2WPKH based accounts"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 174 - Partially Signed Bitcoin Transaction Format"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://blog.summerofbitcoin.org/miniscript-policy-descriptors-hidden-powers-of-bitcoin/",target:"_blank",rel:"noopener noreferrer"}},[t._v("What are Descriptors and miniscript?"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoin.stackexchange.com/questions/97242/bip39-tool-bip32-extended-private-key-vs-bip32-root-key",target:"_blank",rel:"noopener noreferrer"}},[t._v("Master Private Key and Extended Private Key"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://min.sc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Minsc A Miniscript-based scripting language for Bitcoin contracts"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{406:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"tutorial-goals"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tutorial-goals"}},[t._v("#")]),t._v(" Tutorial Goals")]),t._v(" "),e("ul",[e("li",[e("p",[t._v("The goal for this tutorial is to introduce you to "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-cli"),e("OutboundLink")],1),t._v(", a powerful command-line program. You will be exposed to many of the basic skills that go into creating and managing bitcoin wallets.")])]),t._v(" "),e("li",[e("p",[t._v("If you've read most of the "),e("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook",target:"_blank",rel:"noopener noreferrer"}},[t._v('"Mastering Bitcoin"'),e("OutboundLink")],1),t._v(" book, this tutorial could serve as a stepping stone into your Bitcoin wallet development journey.")])]),t._v(" "),e("li",[e("p",[t._v("This short tutorial will expose you to the "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("bdk library")]),t._v(" "),e("OutboundLink")],1),t._v(" and the practical knowledge needed for bitcoin wallet development. As a consequence you will deepen your technical understanding about bitcoin and the bdk library.")])]),t._v(" "),e("li",[e("p",[t._v("BDK also has "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[t._v("language-bindings"),e("OutboundLink")],1),t._v(" for "),e("strong",[t._v("Kotlin/Java, Swift, Python")]),t._v(" which enable the use of BDK's "),e("strong",[t._v("Rust")]),t._v(" library as an API. You can later use these similar steps to create your own bitcoin mobile, desktop or even WebApp by using the bdk-ffi language bindings.")])])]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"a-few-things-before-you-begin"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-few-things-before-you-begin"}},[t._v("#")]),t._v(" A few things before you begin:")]),t._v(" "),e("ul",[e("li",[t._v("Three things to look out for in each step of the tutorial:\n"),e("ul",[e("li",[e("ol",[e("li",[t._v("▶️ / 🔶 - Commands for the Terminal or Shell")])])]),t._v(" "),e("li",[e("ol",{attrs:{start:"2"}},[e("li",[t._v("👍 - Preview of the command output. Note, not all commands will output code.")])])]),t._v(" "),e("li",[e("ol",{attrs:{start:"3"}},[e("li",[t._v("Preview Video of the tutorial for reference of what things should look like in action.")])])])])])]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"outline-of-tutorial-and-installation-notes"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#outline-of-tutorial-and-installation-notes"}},[t._v("#")]),t._v(" Outline of Tutorial and Installation notes:")]),t._v(" "),e("h3",{attrs:{id:"brief-outline-of-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#brief-outline-of-tutorial"}},[t._v("#")]),t._v(" Brief Outline of Tutorial")]),t._v(" "),e("ul",[e("li",[t._v("Step 1: Creating a mnemonic word list + XPRV (Extended Private Key)")]),t._v(" "),e("li",[t._v("Step 2: Generate testnet Receive Address")]),t._v(" "),e("li",[t._v("Step 3: Send funds to newly generated address")]),t._v(" "),e("li",[t._v("Step 4: Sync Wallet")]),t._v(" "),e("li",[t._v("Step 5: Check Balance of Wallet")]),t._v(" "),e("li",[t._v("Step 6: Create a Transaction (PSBT)")]),t._v(" "),e("li",[t._v("Step 7: Sign the Transaction (PSBT)")]),t._v(" "),e("li",[t._v("Step 8: Broadcast Transaction")])]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"rust-and-cargo-installation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#rust-and-cargo-installation"}},[t._v("#")]),t._v(" Rust and Cargo installation:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://rustup.rs/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rust and Cargo Installation"),e("OutboundLink")],1)])]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"bdk-cli-installation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-cli-installation"}},[t._v("#")]),t._v(" "),e("code",[t._v("bdk-cli")]),t._v(" installation:")]),t._v(" "),e("ul",[e("li",[t._v("Download the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli.git",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("bdk-cli")]),t._v(" github repository locally"),e("OutboundLink")],1),t._v(" "),e("ul",[e("li",[t._v("Enter the folder "),e("code",[t._v("cd bdk-cli")])]),t._v(" "),e("li",[t._v("Install "),e("code",[t._v("cargo install --path . --features electrum,repl,compiler")])]),t._v(" "),e("li",[t._v("Once installation is done exit and reopen your terminal (command-line interface)")])])])]),t._v(" "),e("h3",{attrs:{id:"emoji-legend"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#emoji-legend"}},[t._v("#")]),t._v(" Emoji Legend:")]),t._v(" "),e("p",[t._v("▶️ : Unix/Linux Commands to copied and pasted\n🔶 : Windows Powershell Commands to copied and pasted\n👍 : Output/ preview of code")]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-0-check-version-of-bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-0-check-version-of-bdk-cli"}},[t._v("#")]),t._v(" Step 0: Check Version of bdk-cli")]),t._v(" "),e("p",[t._v("▶️ / 🔶 "),e("code",[t._v("bdk-cli -V")]),t._v("\n👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("bdk-cli 0.6.0\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/IcuyeMS.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"preview-of-bdk-cli-help-menu"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#preview-of-bdk-cli-help-menu"}},[t._v("#")]),t._v(" Preview of bdk-cli help menu")]),t._v(" "),e("p",[t._v("▶️ / 🔶 "),e("code",[t._v("bdk-cli --help")]),e("br"),t._v("\n👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[t._v("The BDK Command Line Wallet App\n\nbdk-cli is a light weight "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("command")]),t._v(" line bitcoin wallet, powered by BDK. This app can be used as a playground as well as\ntesting environment to simulate various wallet testing situations. If you are planning to use BDK "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" your wallet, bdk-\ncli is also a great intro tool to get familiar with the BDK API.\n\nBut this is not just any toy. bdk-cli is also a fully functioning bitcoin wallet with taproot support"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n\nFor "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("more")]),t._v(" information checkout "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("https://bitcoindevkit.org/"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\nUSAGE:\n bdk-cli "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("OPTIONS"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("SUBCOMMAND"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\nFLAGS:\n -h, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--help")]),t._v(" Prints "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("help")]),t._v(" information\n -V, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--version")]),t._v(" Prints version information\n\nOPTIONS:\n -d, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--datadir")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("DATADIR"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" Sets the wallet data directory. Default value "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(' "~/.bdk-bitcoin\n -n, '),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--network")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("NETWORK"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" Sets the network "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("default: testnet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("possible values: bitcoin, testnet, signet, regtest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\nSUBCOMMANDS:\n compile Compile a miniscript policy to an output descriptor\n "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("help")]),t._v(" Prints this message or the "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("help")]),t._v(" of the given subcommand"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n key Subcommands "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" Key operations\n repl Options to configure a SOCKS5 proxy "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" a blockchain client connection\n wallet Wallet subcommands that can be issued without a blockchain backend\n")])])]),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-1-seed-generate"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-1-seed-generate"}},[t._v("#")]),t._v(" Step 1: Seed Generate")]),t._v(" "),e("h3",{attrs:{id:"1a-mnemonic-word-list-xprv-extended-private-key-"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1a-mnemonic-word-list-xprv-extended-private-key-"}},[t._v("#")]),t._v(" 1a: Mnemonic word-list + XPRV (Extended Private Key) 🔑")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli key generate | tee key.json")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v('bdk-cli key generate | Out-File -FilePath "key.json"')])]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"fingerprint"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"42b15d2f"')]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mnemonic"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"party salon worth satoshi envelope suggest garlic dry add pitch throw clap keen narrow antique oyster ketchup purchase gasp visual work venue fog crater"')]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"xprv"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tprv8ZgxMBicQKsPdwpamtjqMFpYRTafnE1bN2SphLEybCtRKakk6S1TgQCsZgiBwJuJNWe3jYdgVCTsKf9weMxj6tW4zNNKWptykszJpS2L8wE"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/ii62Hul.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1b-save-xprv-extended-private-key-into-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1b-save-xprv-extended-private-key-into-environment-variable"}},[t._v("#")]),t._v(" 1b: Save XPRV (Extended Private Key) into environment variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("export XPRV_00=$(cat key.json | jq -r .xprv)")])]),t._v(" "),e("p",[t._v("Windows Powershell:")]),t._v(" "),e("p",[t._v("🔶 "),e("code",[t._v("$json = Get-Content -Path .\\key.json | ConvertFrom-Json")])]),t._v(" "),e("p",[t._v("🔶 "),e("code",[t._v("$mykeyValue = $json.xprv")])]),t._v(" "),e("p",[t._v("🔶 "),e("code",[t._v("[System.Environment]::SetEnvironmentVariable('XPRV',$mykeyValue, 'Process')")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/KYW2Cdo.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1c-verify-environment-variable-xprv-00-is-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1c-verify-environment-variable-xprv-00-is-active"}},[t._v("#")]),t._v(" 1c: Verify environment variable XPRV_00 is active")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("env | grep XPRV")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("$env:XPRV")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/ZahbJwe.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1d-create-descriptor-and-save-into-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1d-create-descriptor-and-save-into-environment-variable"}},[t._v("#")]),t._v(" 1d: Create Descriptor and Save into environment variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v('export my_descriptor="wpkh($XPRV_00/84h/1h/0h/0/*)"')])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("[System.Environment]::SetEnvironmentVariable('my_descriptor', \"wpkh($env:XPRV/84h/1h/0h/0/*)\", 'Process')")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/UV4Vgsq.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"1e-verify-environment-variable-my-descriptor-is-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1e-verify-environment-variable-my-descriptor-is-active"}},[t._v("#")]),t._v(" 1e: Verify environment variable my_descriptor is active")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("env | grep my_descriptor")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("$env:my_descriptor")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/s7ZeRQN.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-2-generate-receive-address"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-2-generate-receive-address"}},[t._v("#")]),t._v(" Step 2: Generate Receive-Address")]),t._v(" "),e("p",[t._v("Linux/Terminal:")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor get_new_address")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor get_new_address")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/P8PjTAo.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"address"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1qrh4sq5va0unqtxyfv8al9lz3sna3988cj59uya"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-3-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-3-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[t._v("#")]),t._v(" Step 3: Send testnet bitcoin to the newly created receive-address")]),t._v(" "),e("p",[t._v("Use a faucet to send funds to your newly created address. Here is a link to one: "),e("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Testnet Faucet"),e("OutboundLink")],1)]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-4-sync-the-wallet"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-4-sync-the-wallet"}},[t._v("#")]),t._v(" Step 4: Sync the wallet")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor sync")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶 "),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor sync")])]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/WFYBgVB.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-5-check-the-balance"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-5-check-the-balance"}},[t._v("#")]),t._v(" Step 5: Check the balance")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor get_balance")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor get_balance")])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[t._v("Note: The balance will only show after the transaction has been confirmed in a block at least once.")])]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful:")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"confirmed"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100000")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"immature"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"trusted_pending"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"untrusted_pending"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/v8MAYB2.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-6-create-transaction-psbt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-6-create-transaction-psbt"}},[t._v("#")]),t._v(" Step 6: Create Transaction (PSBT)")]),t._v(" "),e("p",[t._v("To create a PSBT (partially-signed-bitcoin-transaction) run the command:")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor create_tx --to tb1qw2c3lxufxqe2x9s4rdzh65tpf4d7fssjgh8nv6:50000")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor create_tx --to tb1qjk6n943uwhqhdf7en600tnwxpslvwtr0udsehp:0 --send_all")]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/EUCovcJ.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"details"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"confirmation_time"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" null,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"fee"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("113")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"received"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sent"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("123000")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"transaction"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" null,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"029173d76253e3441f9dc26f91e6ef30dff486848e91a7941f0cacd0af25ee30"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cHNidP8BAFUBAAAAAak8uMR3UGkAGUKWsq8Mv45qg2fdD93JQRIsa2P0wFloAQAAAAD/////AQfgAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA3gIAAAAAAQFY9sVfEEbyjrHXSlxXDxL+71WOMnsPpVElwk+3E/J9vAAAAAAA/v///wIYZRIAAAAAABYAFBKYf7yF+ss6EFdw2rDZTfdLhep8eOABAAAAAAAWABQd6wBRnX8mBZiJYfvy/FGE+xKc+AJHMEQCIFSIkvEUI9yUgEw4JocRs1aiVsBlKKXrOQaQb3XFqR21AiBqiEVzCVVSRGjckyPDgAQBnOdSzBYR6Rw6KFcCP+E27wEhAwIlXdfM2WYnYa36Hp4MS6YkplBAgBsb1tYG9NiWFWTKzPYhAAEBH3jgAQAAAAAAFgAUHesAUZ1/JgWYiWH78vxRhPsSnPgiBgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6SxgTizKsVAAAgAEAAIAAAACAAAAAAAAAAAAAAA=="')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h3",{attrs:{id:"6a-export-psbt-to-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#6a-export-psbt-to-environment-variable"}},[t._v("#")]),t._v(" 6a: export PSBT to environment-variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v('export PSBT="PASTE_PSBT_HERE"')])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶"),e("code",[t._v("[System.Environment]::SetEnvironmentVariable('PSBT',\"PASTE_PSBT_HERE\",'Process')")]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/CEDKcPZ.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-7-sign-transaction-psbt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-7-sign-transaction-psbt"}},[t._v("#")]),t._v(" Step 7: Sign Transaction (PSBT)")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor sign --psbt $PSBT")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor sign --psbt $env:PSBT")])]),t._v(" "),e("ul",[e("li",[t._v("DON'T FORGET to COPY the PSBT for the next step")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/f4o4Ce8.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"is_finalized"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" true,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"cHNidP8BAFUBAAAAAak8uMR3UGkAGUKWsq8Mv45qg2fdD93JQRIsa2P0wFloAQAAAAD/////AQfgAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA3gIAAAAAAQFY9sVfEEbyjrHXSlxXDxL+71WOMnsPpVElwk+3E/J9vAAAAAAA/v///wIYZRIAAAAAABYAFBKYf7yF+ss6EFdw2rDZTfdLhep8eOABAAAAAAAWABQd6wBRnX8mBZiJYfvy/FGE+xKc+AJHMEQCIFSIkvEUI9yUgEw4JocRs1aiVsBlKKXrOQaQb3XFqR21AiBqiEVzCVVSRGjckyPDgAQBnOdSzBYR6Rw6KFcCP+E27wEhAwIlXdfM2WYnYa36Hp4MS6YkplBAgBsb1tYG9NiWFWTKzPYhAAEBH3jgAQAAAAAAFgAUHesAUZ1/JgWYiWH78vxRhPsSnPgiAgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6S0gwRQIhALWkBRSJzxuf0od4tPu3qFmEfJ2Y+/QBGtfjSFObWsPeAiA4QJx8Rk5pacrjHv5EOdw6RNHXcdtepFs+m0/Za/h0UQEiBgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6SxgTizKsVAAAgAEAAIAAAACAAAAAAAAAAAABBwABCGwCSDBFAiEAtaQFFInPG5/Sh3i0+7eoWYR8nZj79AEa1+NIU5taw94CIDhAnHxGTmlpyuMe/kQ53DpE0ddx216kWz6bT9lr+HRRASED/NBaWlmEMxswpzSPW5V23outWKQJraHszEcaVbwSeksAAA=="')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h3",{attrs:{id:"7a-export-signed-psbt-to-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#7a-export-signed-psbt-to-environment-variable"}},[t._v("#")]),t._v(" 7a: export signed psbt to environment variable")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v('export SIGNED_PSBT="Paste_PSBT_HERE"')])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v('$env:PSBTSIGNED = "STRINGHERE"')]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/VJsl8zR.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-8-broadcast-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-8-broadcast-transaction"}},[t._v("#")]),t._v(" Step 8: Broadcast Transaction")]),t._v(" "),e("p",[t._v("Linux/Terminal:\n▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor broadcast --psbt $SIGNED_PSBT")])]),t._v(" "),e("p",[t._v("Windows Powershell:\n🔶\n"),e("code",[t._v("bdk-cli wallet --descriptor $env:my_descriptor broadcast --psbt $env:PSBTSIGNED")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/yQZZk0d.gif",alt:""}})]),t._v(" "),e("p",[t._v("👍 The output below confirms the command was successful.")]),t._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a0877b7ce91ea6d141ba63277673f5bdf0edfdd45f91a39ba1a1ace15f839b52"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Verify transaction in the memory pool on testnet "),e("a",{attrs:{href:"https://mempool.space/testnet",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mempool-testnet!"),e("OutboundLink")],1)])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[t._v("Run sync one more time and see that the balance has decreased.")])]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"resources"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#resources"}},[t._v("#")]),t._v(" Resources")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP-32: Hierarchical Deterministic Wallets"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 39 - Mnemonic code for generating deterministic keys"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 44 - Multi-Account Hierarchy for Deterministic Wallets"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 84 - Derivation scheme for P2WPKH based accounts"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP: 174 - Partially Signed Bitcoin Transaction Format"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://blog.summerofbitcoin.org/miniscript-policy-descriptors-hidden-powers-of-bitcoin/",target:"_blank",rel:"noopener noreferrer"}},[t._v("What are Descriptors and miniscript?"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoin.stackexchange.com/questions/97242/bip39-tool-bip32-extended-private-key-vs-bip32-root-key",target:"_blank",rel:"noopener noreferrer"}},[t._v("Master Private Key and Extended Private Key"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://min.sc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Minsc A Miniscript-based scripting language for Bitcoin contracts"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/54.018c80a1.js b/assets/js/54.c56c2eff.js similarity index 99% rename from assets/js/54.018c80a1.js rename to assets/js/54.c56c2eff.js index f3bbe32307..b94a225fae 100644 --- a/assets/js/54.018c80a1.js +++ b/assets/js/54.c56c2eff.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{410:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("It’s easy to underestimate the importance of privacy tech for Bitcoin,\nespecially when connecting to third party services. They can learn your\nIP address and associate the transactions you sent over it. You can only\nhope that this information will not be leaked anytime in the future with\nunpredictable consequences. In order to use Bitcoin privately, you need\nto encrypt and anonymize the data you send over the Internet.")]),t._v(" "),s("p",[t._v("Tor is one of the must-have privacy preserving tools for the Internet in\ngeneral, and for Bitcoin in particular. Tor network consists of nodes that\nuse clever cryptographic methods to encrypt user data and transfer them as\nanonymously as possible.")]),t._v(" "),s("p",[t._v("In this article we show how to integrate Tor with your BDK application.")]),t._v(" "),s("h2",{attrs:{id:"prerequisite"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisite"}},[t._v("#")]),t._v(" Prerequisite")]),t._v(" "),s("p",[t._v("First, you would need to have a Tor daemon up and running.")]),t._v(" "),s("p",[t._v("On Mac OS X you can install with Homebrew.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("brew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\nbrew services start tor\n")])])]),s("p",[t._v("On Ubuntu or other Debian-based distributions.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\n")])])]),s("p",[t._v("In some cases you'll need to wait a minute or two for the bootstrapping to finish.\nIn general, Tor is not the fastest network, so if any of the examples below fail\ndue to timeout, simply restart it.")]),t._v(" "),s("p",[t._v("At the very end of the article we’ll show how to integrate Tor directly to\nyour application.")]),t._v(" "),s("p",[t._v("By default, Tor creates a "),s("a",{attrs:{href:"https://en.wikipedia.org/wiki/SOCKS",target:"_blank",rel:"noopener noreferrer"}},[t._v("SOCKS5"),s("OutboundLink")],1),t._v(" proxy\nendpoint and listens on port 9050. Your application should connect to the\nproxy on "),s("code",[t._v("localhost:9050")]),t._v(" and use it for its network activities.")]),t._v(" "),s("h2",{attrs:{id:"setting-up"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),s("p",[t._v("Create a new cargo project.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdir")]),t._v(" ~/tutorial\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" tutorial\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" new bdk-tor\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-tor\n")])])]),s("p",[t._v("Open "),s("code",[t._v("src/main.rs")]),t._v(" file remove all its contents and add these lines.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("template"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add additional imports here")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Syncing the wallet..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The wallet synced. Height: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_height")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Internal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this code we create a testnet wallet with "),s("code",[t._v("create_wallet()")]),t._v(" function and\ntry to sync it with a specific blockchain client implementation. We create a\nblockchain client using "),s("code",[t._v("create_blockchain()")]),t._v(" function. We’ll implement it\nlater for each type of blockchain client supported by BDK.")]),t._v(" "),s("h2",{attrs:{id:"electrumblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#electrumblockchain"}},[t._v("#")]),t._v(" ElectrumBlockchain")]),t._v(" "),s("p",[t._v("The Electrum client is enabled by default so the "),s("code",[t._v("Cargo.toml")]),t._v(" dependencies\nsection will look like this.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("And the imports look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("electrum_client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Here is the implementation of "),s("code",[t._v("create_blockchain()")]),t._v(" function for the\nElectrum client.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("socks5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n credentials"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we create an instance of "),s("code",[t._v("Socks5Config")]),t._v(" which defines the\nTor proxy parameters for "),s("code",[t._v("ElectrumBlockchain")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"blocking-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#blocking-esplorablockchain"}},[t._v("#")]),t._v(" Blocking EsploraBlockchain")]),t._v(" "),s("p",[t._v("The blocking version of "),s("code",[t._v("EsploraBlockchain")]),t._v(" uses "),s("code",[t._v("ureq")]),t._v(" crate to send HTTP\nrequests to Eslora backends. By default, its SOCKS5 feature is disabled,\nso we need to enable it in "),s("code",[t._v("Cargo.toml")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-blocking"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("And "),s("code",[t._v("create_blockchain()")]),t._v(" implementation is")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("proxy()")]),t._v(" method of the config builder to set the Tor proxy\naddress. Please note, that unlike the previous examples, the Esplora client\nbuilder requires not just a proxy address, but a URL\n“socks5://127.0.0.1:9050”.")]),t._v(" "),s("h2",{attrs:{id:"asynchronous-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#asynchronous-esplorablockchain"}},[t._v("#")]),t._v(" Asynchronous EsploraBlockchain")]),t._v(" "),s("p",[t._v("There’s no need in enabling SOCKS5 for the asynchronous Esplora client,\nso we are good to go without additional dependencies.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-async"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are the same as in previous example.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" is almost identical.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5h://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("There are two notable differences though. First, we call "),s("code",[t._v("build_async()")]),t._v(" to\ncreate an asynchronous Esplora client. Second the SOCKS5 URL scheme is\n“socks5h”. It’s not a typo. The async client supports two SOCKS5 schemes\n“socks5” and “socks5h”. The difference between them is that the former\nmakes the client to resolve domain names, and the latter does not, so the\nclient passes them to the proxy as is. A regular DNS resolver cannot\nresolve Tor onion addresses, so we should use “socks5h” here.")]),t._v(" "),s("h2",{attrs:{id:"compactfiltersblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compactfiltersblockchain"}},[t._v("#")]),t._v(" CompactFiltersBlockchain")]),t._v(" "),s("p",[t._v("Add these lines to the dependencies section of "),s("code",[t._v("Cargo.toml")]),t._v(" file to enable\nBIP-157/BIP-158 compact filter support.")]),t._v(" "),s("p",[t._v("It can take a while to sync a wallet using compact filters over Tor, so be\npatient.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compact_filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Now add the required imports into "),s("code",[t._v("src/main.rs")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("compact_filters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" function will look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"neutrino.testnet3.suredbits.com:18333"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mempool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect_proxy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mempool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("peer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./wallet-filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("Peer::connect_proxy()")]),t._v(" which accepts the address to the SOCKS5\nproxy and performs all the heavy lifting for us.")]),t._v(" "),s("h2",{attrs:{id:"integrated-tor-daemon"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#integrated-tor-daemon"}},[t._v("#")]),t._v(" Integrated Tor daemon")]),t._v(" "),s("p",[t._v("As an application developer you don’t have to rely on your users to install\nand start Tor to use your application. Using "),s("code",[t._v("libtor")]),t._v(" crate you can bundle\nTor daemon with your app.")]),t._v(" "),s("p",[s("code",[t._v("libtor")]),t._v(" builds a Tor binary from the source files. Since Tor is written in C\nyou'll need a C compiler and build tools.")]),t._v(" "),s("p",[t._v("Install these packages on Mac OS X:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("xcode-select "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--install")]),t._v("\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" automake\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" libtool\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" openssl\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" pkg-config\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("LDFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-L/opt/homebrew/opt/openssl/lib"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("CPPFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-I/opt/homebrew/opt/openssl/include"')]),t._v("\n")])])]),s("p",[t._v("Or these packages on Ubuntu or another Debian-based Linux distribution:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf automake clang "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("file")]),t._v(" libtool openssl pkg-config\n")])])]),s("p",[t._v("Then add these dependencies to the "),s("code",[t._v("Cargo.toml")]),t._v(" file.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("libtor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"47.8.0+0.4.7.x"')]),t._v("\n")])])]),s("p",[t._v("This is an example of how we can use "),s("code",[t._v("libtor")]),t._v(" to start a Tor daemon.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("prelude"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HiddenServiceVersion")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorAddress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_port "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("19050")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data_dir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("temp_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("display")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-tor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" log_file_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"log"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Staring Tor in {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("truncate_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataDirectory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Notice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SocksPort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ExitPolicy reject *:*"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BridgeRelay 0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_background")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("started "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("panic!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"It took too long to start Tor. See {} for details"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sleep")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_millis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find_string_in_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bootstrapped 100%"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tor started"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("First, we create a Tor object, and then we call "),s("code",[t._v("start_background()")]),t._v(" method\nto start it in the background. After that, we continuously try to find\n“Bootstrapped 100%” string in the log file. Once we find it, Tor is\nready to proxy our connections. We use port 19050 because, the user can\nhave their own instance of Tor running already.")]),t._v(" "),s("p",[t._v("Next you can modify "),s("code",[t._v("create_blockchain()")]),t._v(" like this")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we start Tor first, then use the address returned by\n"),s("code",[t._v("start_tor()")]),t._v(" function as proxy address.")]),t._v(" "),s("p",[t._v("We omitted "),s("code",[t._v("find_string_in_log()")]),t._v(" and "),s("code",[t._v("truncate_log()")]),t._v(" for brevity. You\ncan find their implementations in "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/master/examples/esplora_backend_with_tor.rs",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora_backend_with_tor.rs"),s("OutboundLink")],1)])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{409:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("It’s easy to underestimate the importance of privacy tech for Bitcoin,\nespecially when connecting to third party services. They can learn your\nIP address and associate the transactions you sent over it. You can only\nhope that this information will not be leaked anytime in the future with\nunpredictable consequences. In order to use Bitcoin privately, you need\nto encrypt and anonymize the data you send over the Internet.")]),t._v(" "),s("p",[t._v("Tor is one of the must-have privacy preserving tools for the Internet in\ngeneral, and for Bitcoin in particular. Tor network consists of nodes that\nuse clever cryptographic methods to encrypt user data and transfer them as\nanonymously as possible.")]),t._v(" "),s("p",[t._v("In this article we show how to integrate Tor with your BDK application.")]),t._v(" "),s("h2",{attrs:{id:"prerequisite"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisite"}},[t._v("#")]),t._v(" Prerequisite")]),t._v(" "),s("p",[t._v("First, you would need to have a Tor daemon up and running.")]),t._v(" "),s("p",[t._v("On Mac OS X you can install with Homebrew.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("brew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\nbrew services start tor\n")])])]),s("p",[t._v("On Ubuntu or other Debian-based distributions.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\n")])])]),s("p",[t._v("In some cases you'll need to wait a minute or two for the bootstrapping to finish.\nIn general, Tor is not the fastest network, so if any of the examples below fail\ndue to timeout, simply restart it.")]),t._v(" "),s("p",[t._v("At the very end of the article we’ll show how to integrate Tor directly to\nyour application.")]),t._v(" "),s("p",[t._v("By default, Tor creates a "),s("a",{attrs:{href:"https://en.wikipedia.org/wiki/SOCKS",target:"_blank",rel:"noopener noreferrer"}},[t._v("SOCKS5"),s("OutboundLink")],1),t._v(" proxy\nendpoint and listens on port 9050. Your application should connect to the\nproxy on "),s("code",[t._v("localhost:9050")]),t._v(" and use it for its network activities.")]),t._v(" "),s("h2",{attrs:{id:"setting-up"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),s("p",[t._v("Create a new cargo project.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdir")]),t._v(" ~/tutorial\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" tutorial\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" new bdk-tor\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-tor\n")])])]),s("p",[t._v("Open "),s("code",[t._v("src/main.rs")]),t._v(" file remove all its contents and add these lines.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("template"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add additional imports here")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Syncing the wallet..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The wallet synced. Height: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_height")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Internal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this code we create a testnet wallet with "),s("code",[t._v("create_wallet()")]),t._v(" function and\ntry to sync it with a specific blockchain client implementation. We create a\nblockchain client using "),s("code",[t._v("create_blockchain()")]),t._v(" function. We’ll implement it\nlater for each type of blockchain client supported by BDK.")]),t._v(" "),s("h2",{attrs:{id:"electrumblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#electrumblockchain"}},[t._v("#")]),t._v(" ElectrumBlockchain")]),t._v(" "),s("p",[t._v("The Electrum client is enabled by default so the "),s("code",[t._v("Cargo.toml")]),t._v(" dependencies\nsection will look like this.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("And the imports look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("electrum_client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Here is the implementation of "),s("code",[t._v("create_blockchain()")]),t._v(" function for the\nElectrum client.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("socks5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n credentials"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we create an instance of "),s("code",[t._v("Socks5Config")]),t._v(" which defines the\nTor proxy parameters for "),s("code",[t._v("ElectrumBlockchain")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"blocking-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#blocking-esplorablockchain"}},[t._v("#")]),t._v(" Blocking EsploraBlockchain")]),t._v(" "),s("p",[t._v("The blocking version of "),s("code",[t._v("EsploraBlockchain")]),t._v(" uses "),s("code",[t._v("ureq")]),t._v(" crate to send HTTP\nrequests to Eslora backends. By default, its SOCKS5 feature is disabled,\nso we need to enable it in "),s("code",[t._v("Cargo.toml")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-blocking"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("And "),s("code",[t._v("create_blockchain()")]),t._v(" implementation is")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("proxy()")]),t._v(" method of the config builder to set the Tor proxy\naddress. Please note, that unlike the previous examples, the Esplora client\nbuilder requires not just a proxy address, but a URL\n“socks5://127.0.0.1:9050”.")]),t._v(" "),s("h2",{attrs:{id:"asynchronous-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#asynchronous-esplorablockchain"}},[t._v("#")]),t._v(" Asynchronous EsploraBlockchain")]),t._v(" "),s("p",[t._v("There’s no need in enabling SOCKS5 for the asynchronous Esplora client,\nso we are good to go without additional dependencies.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-async"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are the same as in previous example.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" is almost identical.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5h://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("There are two notable differences though. First, we call "),s("code",[t._v("build_async()")]),t._v(" to\ncreate an asynchronous Esplora client. Second the SOCKS5 URL scheme is\n“socks5h”. It’s not a typo. The async client supports two SOCKS5 schemes\n“socks5” and “socks5h”. The difference between them is that the former\nmakes the client to resolve domain names, and the latter does not, so the\nclient passes them to the proxy as is. A regular DNS resolver cannot\nresolve Tor onion addresses, so we should use “socks5h” here.")]),t._v(" "),s("h2",{attrs:{id:"compactfiltersblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compactfiltersblockchain"}},[t._v("#")]),t._v(" CompactFiltersBlockchain")]),t._v(" "),s("p",[t._v("Add these lines to the dependencies section of "),s("code",[t._v("Cargo.toml")]),t._v(" file to enable\nBIP-157/BIP-158 compact filter support.")]),t._v(" "),s("p",[t._v("It can take a while to sync a wallet using compact filters over Tor, so be\npatient.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compact_filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Now add the required imports into "),s("code",[t._v("src/main.rs")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("compact_filters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" function will look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"neutrino.testnet3.suredbits.com:18333"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mempool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect_proxy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mempool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("peer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./wallet-filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("Peer::connect_proxy()")]),t._v(" which accepts the address to the SOCKS5\nproxy and performs all the heavy lifting for us.")]),t._v(" "),s("h2",{attrs:{id:"integrated-tor-daemon"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#integrated-tor-daemon"}},[t._v("#")]),t._v(" Integrated Tor daemon")]),t._v(" "),s("p",[t._v("As an application developer you don’t have to rely on your users to install\nand start Tor to use your application. Using "),s("code",[t._v("libtor")]),t._v(" crate you can bundle\nTor daemon with your app.")]),t._v(" "),s("p",[s("code",[t._v("libtor")]),t._v(" builds a Tor binary from the source files. Since Tor is written in C\nyou'll need a C compiler and build tools.")]),t._v(" "),s("p",[t._v("Install these packages on Mac OS X:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("xcode-select "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--install")]),t._v("\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" automake\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" libtool\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" openssl\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" pkg-config\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("LDFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-L/opt/homebrew/opt/openssl/lib"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("CPPFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-I/opt/homebrew/opt/openssl/include"')]),t._v("\n")])])]),s("p",[t._v("Or these packages on Ubuntu or another Debian-based Linux distribution:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf automake clang "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("file")]),t._v(" libtool openssl pkg-config\n")])])]),s("p",[t._v("Then add these dependencies to the "),s("code",[t._v("Cargo.toml")]),t._v(" file.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("libtor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"47.8.0+0.4.7.x"')]),t._v("\n")])])]),s("p",[t._v("This is an example of how we can use "),s("code",[t._v("libtor")]),t._v(" to start a Tor daemon.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("prelude"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HiddenServiceVersion")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorAddress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_port "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("19050")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data_dir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("temp_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("display")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-tor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" log_file_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"log"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Staring Tor in {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("truncate_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataDirectory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Notice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SocksPort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ExitPolicy reject *:*"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BridgeRelay 0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_background")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("started "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("panic!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"It took too long to start Tor. See {} for details"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sleep")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_millis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find_string_in_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bootstrapped 100%"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tor started"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("First, we create a Tor object, and then we call "),s("code",[t._v("start_background()")]),t._v(" method\nto start it in the background. After that, we continuously try to find\n“Bootstrapped 100%” string in the log file. Once we find it, Tor is\nready to proxy our connections. We use port 19050 because, the user can\nhave their own instance of Tor running already.")]),t._v(" "),s("p",[t._v("Next you can modify "),s("code",[t._v("create_blockchain()")]),t._v(" like this")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we start Tor first, then use the address returned by\n"),s("code",[t._v("start_tor()")]),t._v(" function as proxy address.")]),t._v(" "),s("p",[t._v("We omitted "),s("code",[t._v("find_string_in_log()")]),t._v(" and "),s("code",[t._v("truncate_log()")]),t._v(" for brevity. You\ncan find their implementations in "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/master/examples/esplora_backend_with_tor.rs",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora_backend_with_tor.rs"),s("OutboundLink")],1)])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/55.06a752f4.js b/assets/js/55.fc6f0c87.js similarity index 99% rename from assets/js/55.06a752f4.js rename to assets/js/55.fc6f0c87.js index 80d65ce45f..b4fe62a00f 100644 --- a/assets/js/55.06a752f4.js +++ b/assets/js/55.fc6f0c87.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{409:function(e,t,i){"use strict";i.r(t);var r=i(7),o=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[t("strong",[e._v("tldr;")]),e._v(" "),t("em",[e._v("we can't produce and maintain bindings for all Rust crates we get requests for, but we are working to help others build their own bindings by (1) making our architecture composable and reusable, and (2) building strong examples and documentation on how to do it for other crates.")])]),e._v(" "),t("br"),e._v(" "),t("p",[e._v("Over the past 2 years, the Bitcoin Development Kit team has been successful at building and releasing language bindings for our Rust library. In particular, over the past 18 months we have locked in and solidified our approach for the iOS, Android, Kotlin, Java, and Python bindings by using a Rust library called "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Over the course of the year, we've had many requests to add to the bindings certain features that are not directly in the Rust BDK library. These request mainly break down into two groups:")]),e._v(" "),t("ol",[t("li",[e._v('Features that are part of crates "upstream" of BDK (rust-bitcoin, rust-miniscript)')]),e._v(" "),t("li",[e._v("Features that are not but that have Rust crates and would be useful on mobile (payjoin, coinjoin implementations, silent payments, BIP-47)")])]),e._v(" "),t("h2",{attrs:{id:"current-architecture"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#current-architecture"}},[e._v("#")]),e._v(" Current architecture")]),e._v(" "),t("p",[e._v("The current architecture for the BDK bindings is more or less wrapping the bdk, rust-bitcoin, and rust-miniscript crates and exposing an API that allows users to leverage them similarly to how they would BDK in Rust if they were using it in a Rust project.")]),e._v(" "),t("p",[e._v('While we started with a simplified version of the Rust BDK API, over time users asked for more and more functionality, and exposing some of the underlying rust-bitcoin constructs became important. This makes sense, and indeed users of the bitcoin development kit in Rust have access to all the related APIs by simply importing rust-bitcoin and rust-miniscript, hence our desire to accommodate these use cases as well. However, this is currently done all in one "bindings" library (i.e. if you import '),t("code",[e._v("bdk-android")]),e._v(" in a project, you'll have access to an API that is mostly bdk-based, but also contains a bit of rust-bitcoin and rust-miniscript).")]),e._v(" "),t("h2",{attrs:{id:"moving-forward-building-a-family-of-libraries"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#moving-forward-building-a-family-of-libraries"}},[e._v("#")]),e._v(" Moving forward: building a family of libraries")]),e._v(" "),t("p",[e._v("At the same time, other Rust-based libraries started using the uniffi approach (a good example is "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-node"),t("OutboundLink")],1),e._v(") to expose bindings. When developing and using those libraries together, it quickly became clear that much of the work was duplicated; both libraries needed access to underlying rust-bitcoin types, but they both exposed their own versions of it.")]),e._v(" "),t("p",[e._v("Over the coming months, the team is looking at extracting the rust-bitcoin part of the BDK bindings library (bdk-ffi) and publishing that library on "),t("a",{attrs:{href:"https://crates.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("crates.io"),t("OutboundLink")],1),e._v(" so as to make it available to others who wish to build Rust bindings using uniffi.")]),e._v(" "),t("h2",{attrs:{id:"why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[e._v("#")]),e._v(" Why can't we just build one big BDK library with "),t("em",[e._v("everything")]),e._v(" in it?")]),e._v(" "),t("ol",[t("li",[e._v("The short answer to this is that it would simply not be maintainable. If we rely on many underlying Rust crates, we'd need to release patches every time one of the underlying libraries patches a bug. We'd also need to keep them all in sync (what API versions work with what), and we'd be relying on work from teams that may or may not have the capacity to keep their crates up to date.")]),e._v(" "),t("li",[e._v("Scope creep. Unless we define a narrow and structured scope for the library, we will forever be handling requests for features that may or may not be feasible to accommodate.")]),e._v(" "),t("li",[e._v("Library size. Because one of our primary focus for the bindings is mobile devices, we need to make sure we don't build a library that is too big. This is a more nuanced issue, but it relates to point (2), where too large a scope would eventually produce a library that is potentially not optimal for mobile devices because it attempts to do too much all in one package.")])]),e._v(" "),t("h2",{attrs:{id:"are-you-looking-to-build-rust-bindings-yourself"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#are-you-looking-to-build-rust-bindings-yourself"}},[e._v("#")]),e._v(" Are you looking to build Rust bindings yourself?")]),e._v(" "),t("p",[e._v("We got your back! The Bitcoin Development Kit team intends to help others in the Rust bitcoin ecosystem build bindings if they wish to. To that effect, we maintain 3 repositories that should help you get going with bindings in no time:")]),e._v(" "),t("ol",[t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-bindings-template",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi library template"),t("OutboundLink")],1)]),e._v(". This is a repository you can fork and start adding code to produce bindings directly for iOS and Android. Included are our custom-made Gradle plugin and Swift release shell scripts, as well as information about the little build quirks you need to know about for smooth releases.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi examples"),t("OutboundLink")],1)]),e._v(". This repository provides boiled-down examples of APIs exposed using uniffi, with an "),t("a",{attrs:{href:"https://thunderbiscuit.github.io/uniffi-examples/",target:"_blank",rel:"noopener noreferrer"}},[e._v("accompanying documentation website"),t("OutboundLink")],1),e._v(". Functions, enums, objects, callbacks, multi-libraries, a lot of information and examples to get you started.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/bitcoin-frontier",target:"_blank",rel:"noopener noreferrer"}},[e._v("Sandbox library "),t("code",[e._v("bitcoin-frontier")]),t("OutboundLink")],1)]),e._v(". This repository is meant as a sandbox to start developing and testing your own bindings. Simply fork it and start adding code! It comes with a fully working Android app you can leverage to test out whatever bindings you're building.")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{410:function(e,t,i){"use strict";i.r(t);var r=i(7),o=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[t("strong",[e._v("tldr;")]),e._v(" "),t("em",[e._v("we can't produce and maintain bindings for all Rust crates we get requests for, but we are working to help others build their own bindings by (1) making our architecture composable and reusable, and (2) building strong examples and documentation on how to do it for other crates.")])]),e._v(" "),t("br"),e._v(" "),t("p",[e._v("Over the past 2 years, the Bitcoin Development Kit team has been successful at building and releasing language bindings for our Rust library. In particular, over the past 18 months we have locked in and solidified our approach for the iOS, Android, Kotlin, Java, and Python bindings by using a Rust library called "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Over the course of the year, we've had many requests to add to the bindings certain features that are not directly in the Rust BDK library. These request mainly break down into two groups:")]),e._v(" "),t("ol",[t("li",[e._v('Features that are part of crates "upstream" of BDK (rust-bitcoin, rust-miniscript)')]),e._v(" "),t("li",[e._v("Features that are not but that have Rust crates and would be useful on mobile (payjoin, coinjoin implementations, silent payments, BIP-47)")])]),e._v(" "),t("h2",{attrs:{id:"current-architecture"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#current-architecture"}},[e._v("#")]),e._v(" Current architecture")]),e._v(" "),t("p",[e._v("The current architecture for the BDK bindings is more or less wrapping the bdk, rust-bitcoin, and rust-miniscript crates and exposing an API that allows users to leverage them similarly to how they would BDK in Rust if they were using it in a Rust project.")]),e._v(" "),t("p",[e._v('While we started with a simplified version of the Rust BDK API, over time users asked for more and more functionality, and exposing some of the underlying rust-bitcoin constructs became important. This makes sense, and indeed users of the bitcoin development kit in Rust have access to all the related APIs by simply importing rust-bitcoin and rust-miniscript, hence our desire to accommodate these use cases as well. However, this is currently done all in one "bindings" library (i.e. if you import '),t("code",[e._v("bdk-android")]),e._v(" in a project, you'll have access to an API that is mostly bdk-based, but also contains a bit of rust-bitcoin and rust-miniscript).")]),e._v(" "),t("h2",{attrs:{id:"moving-forward-building-a-family-of-libraries"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#moving-forward-building-a-family-of-libraries"}},[e._v("#")]),e._v(" Moving forward: building a family of libraries")]),e._v(" "),t("p",[e._v("At the same time, other Rust-based libraries started using the uniffi approach (a good example is "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-node"),t("OutboundLink")],1),e._v(") to expose bindings. When developing and using those libraries together, it quickly became clear that much of the work was duplicated; both libraries needed access to underlying rust-bitcoin types, but they both exposed their own versions of it.")]),e._v(" "),t("p",[e._v("Over the coming months, the team is looking at extracting the rust-bitcoin part of the BDK bindings library (bdk-ffi) and publishing that library on "),t("a",{attrs:{href:"https://crates.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("crates.io"),t("OutboundLink")],1),e._v(" so as to make it available to others who wish to build Rust bindings using uniffi.")]),e._v(" "),t("h2",{attrs:{id:"why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[e._v("#")]),e._v(" Why can't we just build one big BDK library with "),t("em",[e._v("everything")]),e._v(" in it?")]),e._v(" "),t("ol",[t("li",[e._v("The short answer to this is that it would simply not be maintainable. If we rely on many underlying Rust crates, we'd need to release patches every time one of the underlying libraries patches a bug. We'd also need to keep them all in sync (what API versions work with what), and we'd be relying on work from teams that may or may not have the capacity to keep their crates up to date.")]),e._v(" "),t("li",[e._v("Scope creep. Unless we define a narrow and structured scope for the library, we will forever be handling requests for features that may or may not be feasible to accommodate.")]),e._v(" "),t("li",[e._v("Library size. Because one of our primary focus for the bindings is mobile devices, we need to make sure we don't build a library that is too big. This is a more nuanced issue, but it relates to point (2), where too large a scope would eventually produce a library that is potentially not optimal for mobile devices because it attempts to do too much all in one package.")])]),e._v(" "),t("h2",{attrs:{id:"are-you-looking-to-build-rust-bindings-yourself"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#are-you-looking-to-build-rust-bindings-yourself"}},[e._v("#")]),e._v(" Are you looking to build Rust bindings yourself?")]),e._v(" "),t("p",[e._v("We got your back! The Bitcoin Development Kit team intends to help others in the Rust bitcoin ecosystem build bindings if they wish to. To that effect, we maintain 3 repositories that should help you get going with bindings in no time:")]),e._v(" "),t("ol",[t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-bindings-template",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi library template"),t("OutboundLink")],1)]),e._v(". This is a repository you can fork and start adding code to produce bindings directly for iOS and Android. Included are our custom-made Gradle plugin and Swift release shell scripts, as well as information about the little build quirks you need to know about for smooth releases.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi examples"),t("OutboundLink")],1)]),e._v(". This repository provides boiled-down examples of APIs exposed using uniffi, with an "),t("a",{attrs:{href:"https://thunderbiscuit.github.io/uniffi-examples/",target:"_blank",rel:"noopener noreferrer"}},[e._v("accompanying documentation website"),t("OutboundLink")],1),e._v(". Functions, enums, objects, callbacks, multi-libraries, a lot of information and examples to get you started.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/bitcoin-frontier",target:"_blank",rel:"noopener noreferrer"}},[e._v("Sandbox library "),t("code",[e._v("bitcoin-frontier")]),t("OutboundLink")],1)]),e._v(". This repository is meant as a sandbox to start developing and testing your own bindings. Simply fork it and start adding code! It comes with a fully working Android app you can leverage to test out whatever bindings you're building.")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/58.b6598903.js b/assets/js/58.10758a4f.js similarity index 99% rename from assets/js/58.b6598903.js rename to assets/js/58.10758a4f.js index d98a3939d1..c9c32aef0d 100644 --- a/assets/js/58.b6598903.js +++ b/assets/js/58.10758a4f.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[58],{416:function(e,t,r){"use strict";r.r(t);var a=r(7),s=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"introduction"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[e._v("#")]),e._v(" Introduction")]),e._v(" "),t("p",[e._v("I have tried to setup a 2 of 2 multi signature infrastructure with two\ndifferent wallets, which know nothing about each other, but are compliant with\ntwo very important protocols: "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("Partially Signed\nBitcoin Transactions"),t("OutboundLink")],1),e._v(" described in BIP 174.")]),e._v(" "),t("p",[e._v("Before these two protocols came into existence, making a multi signature setup\nand spending from it was possible only if the involved parties were using the\nsame wallet (eg. Electrum Desktop Wallet). This limitation was due to the fact\nthat the two parties had to agree:")]),e._v(" "),t("ul",[t("li",[e._v("on the particular type of script and address to use")]),e._v(" "),t("li",[e._v("on the way the transaction would be shared composed and signed with all the\ninvolved parties.")])]),e._v(" "),t("p",[t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(" are a way to express which kind scriptPubKey and\naddresses to produce with a key or a series of keys.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("PSBT"),t("OutboundLink")],1),e._v(" is instead the standard protocol used to create a transaction and to enrich\nit with the necessary signatures and other components, to make it valid and complete.")]),e._v(" "),t("p",[e._v("Together they provide a common ground to create and use a multi signature\ninfrastructure in a heterogeneous environment, and this is what I have put\nto test.")]),e._v(" "),t("h2",{attrs:{id:"the-use-case"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-use-case"}},[e._v("#")]),e._v(" The use case")]),e._v(" "),t("p",[e._v("Imagine Alice and Bob owning a company and being willing to put the corporate cash\nin a 2of2 multi signature setup, so that each one of them have to agree and sign each\ntransaction.")]),e._v(" "),t("h2",{attrs:{id:"the-role-of-descriptors"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-role-of-descriptors"}},[e._v("#")]),e._v(" The role of Descriptors")]),e._v(" "),t("p",[e._v("If Alice and Bob cannot agree on the software to use, to monitor the same financial\nsituation, the two software must control and produce exactly the same series\nof multisignature addresses.")]),e._v(" "),t("p",[e._v("To make two different software produce the same addresses in a deterministic way\nwe must ensure that they:")]),e._v(" "),t("ul",[t("li",[e._v("produce the same pair of public keys")]),e._v(" "),t("li",[e._v("combine them in the same order")]),e._v(" "),t("li",[e._v("put them inside the same scriptPubKey to produce the same address")])]),e._v(" "),t("p",[e._v("Here is where the "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(" come into play. They describe:")]),e._v(" "),t("ul",[t("li",[e._v("the sequence of public keys each extended key (xpub) will produce")]),e._v(" "),t("li",[e._v("the sequence in which the new public keys of various parties will enter into\nthe script")]),e._v(" "),t("li",[e._v("the type of script the wallet will prepare with that group keys and so the type\nof address the group of keys will produce.")])]),e._v(" "),t("p",[t("strong",[e._v("By sharing the same Descriptor, every compliant wallet will derive\ndeterministically the same series of multisig addresses")]),e._v(".")]),e._v(" "),t("p",[e._v("Imagine Alice using Bitcoin Core (from now on "),t("a",{attrs:{href:"https://bitcoincore.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Core"'),t("OutboundLink")],1),e._v(') as a\nWallet and Bob using a "Last generation" wallet, Bitcoin Development Kit\n(from now on '),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"BDK"'),t("OutboundLink")],1),e._v("), which uses descriptors and miniscript natively.")]),e._v(" "),t("p",[e._v("Each of these two software wallets should be able to:")]),e._v(" "),t("ul",[t("li",[e._v("Create a new address which is seen as belonging to the multi signature\nwallet in both software")]),e._v(" "),t("li",[e._v("Express the consent of each party by partially signing the transaction in a way\nthe other wallet can understand and complete it with its own signature.")])]),e._v(" "),t("p",[e._v("The infrastructure of multiple Extended keys combined toghether to produce\nmultiple multisignature addresses is often referred as\n"),t("em",[t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("Hierarchical Deterministic"),t("OutboundLink")],1),e._v(" multi signature wallet or HDM")]),e._v(".")]),e._v(" "),t("p",[e._v("What follows are the steps to create the HDM usable both in Core and\nin BDK.")]),e._v(" "),t("p",[t("em",[e._v("Note: In Core, "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/pull/16528",target:"_blank",rel:"noopener noreferrer"}},[e._v("Descriptor wallets"),t("OutboundLink")],1),e._v(" are still experimental and in general,\nboth wallets should be tested for descriptor capabilities only in testnet.")])]),e._v(" "),t("h2",{attrs:{id:"our-playground"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#our-playground"}},[e._v("#")]),e._v(" Our playground")]),e._v(" "),t("p",[e._v("We will build a 2of2 key set up that will be used cooperatively by Bitcoin Core\nand Bitcoin Development Kit.\nThe steps Alice and Bob will do are:")]),e._v(" "),t("ol",[t("li",[e._v("creation of the seed and the derived Extended Master Public and send it to\nthe other party")]),e._v(" "),t("li",[e._v("Create the multi signature descriptor for each wallet")]),e._v(" "),t("li",[e._v("Use each other's software to receive testnet coins from a faucet")]),e._v(" "),t("li",[e._v("return part of the coins to the faucet signing the transaction with both\nwallets.")])]),e._v(" "),t("p",[e._v("We need:")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Dev Kit"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://bitcoincore.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Core"),t("OutboundLink")],1),e._v(" (v0.21.0 or later)")])]),e._v(" "),t("h3",{attrs:{id:"1-creating-the-seeds-and-the-derived-extended-public-keys"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#1-creating-the-seeds-and-the-derived-extended-public-keys"}},[e._v("#")]),e._v(" 1. Creating the seeds and the derived Extended Public keys")]),e._v(" "),t("h4",{attrs:{id:"seeds-and-extended-master-public"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeds-and-extended-master-public"}},[e._v("#")]),e._v(" Seeds and Extended Master Public")]),e._v(" "),t("p",[e._v("We build an Extended Private Master Key for both wallet and derive a BIP84\nExtended Master Public for Bitcoin Core and then for BDK.")]),e._v(" "),t("p",[e._v("For Bitcoin Core (Alice):")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("# new Extended wallet data\nexport core_key=$(bdk-cli key generate)\n\n# New Extended Master Private\n\nexport core_xprv=$(echo $core_key | jq -r '.xprv')\n\n# Now I derive the xpubs (one for receiving and one for the change)\n# together with informations about the derivation path to be communicated\n# to BDK wallet's owner (Bob).\n\nexport core_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $core_xprv | jq -r '.xpub')\nexport core_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $core_xprv | jq -r '.xpub')\n")])])]),t("p",[e._v("For BDK (Bob) we do the same:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("# new Extended wallet data\n\nexport BDK_key=$(bdk-cli key generate)\n\n# New Extended Master Private\n\nexport BDK_xprv=$(echo $BDK_key | jq -r '.xprv')\n\n# Now I build the derived xpubs to be communicated (to Alice).\n\nexport BDK_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $BDK_xprv | jq -r '.xpub')\nexport BDK_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $BDK_xprv | jq -r '.xpub')\n")])])]),t("h3",{attrs:{id:"2-creation-of-the-multi-signature-descriptor-for-each-wallet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#2-creation-of-the-multi-signature-descriptor-for-each-wallet"}},[e._v("#")]),e._v(" 2. Creation of the multi signature descriptor for each wallet")]),e._v(" "),t("p",[e._v("To build a multisig wallet, each wallet owner must compose the descriptor\nadding:")]),e._v(" "),t("ul",[t("li",[e._v("his derived extended "),t("strong",[e._v("private")]),e._v(" key AND")]),e._v(" "),t("li",[e._v("all the extended "),t("strong",[e._v("public")]),e._v(" keys of the other wallets involved in the\nmulti signature setup")])]),e._v(" "),t("p",[t("em",[e._v("The different nature of the two keys (one is private and one is public) is\ndue to the fact that each wallet, to be able to partially sign the transaction,\n"),t("strong",[e._v("must manage the private key of the wallet's owner")])]),e._v(" AND have the other\nparty's public key. Otherwise, if we put both public keys, we would obtain\na watch-only wallet unable to sign the transactions. If we\nhad both extended private keys inside the descriptor, we would allow each party\nto finalize the transactions autonomously.")]),e._v(" "),t("h4",{attrs:{id:"in-bitcoin-core"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#in-bitcoin-core"}},[e._v("#")]),e._v(" In Bitcoin Core:")]),e._v(" "),t("p",[e._v("In our case, the multi signature descriptor for Bitcoin Core will be composed\nwith:")]),e._v(" "),t("ul",[t("li",[e._v("The BIP84 derived Extended "),t("strong",[e._v("Public")]),e._v(" Key from BDK")]),e._v(" "),t("li",[e._v("The BIP84 derived Extended "),t("strong",[e._v("Private")]),e._v(" Key from Core.")])]),e._v(" "),t("p",[e._v("BDK wallet's owner will send to Core's owner the derived xpub for this purpose.\nThis is how the Core's multisig descriptor will be created and put into an\nenvironment variable:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export core_rec_desc=\"wsh(multi(2,$BDK_xpub_84_for_rec_desc,$core_xprv/84'/0'/0'/0/*))\"\n")])])]),t("p",[e._v("Where of course "),t("code",[e._v("$BDK_xpub_84_for_rec_desc")]),e._v("is the derived master public created\nin BDK and received by Core's owner.")]),e._v(" "),t("p",[e._v("The meaning of what is before and after is illustrated in the doc that explain\nthe use of "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors in Bitcoin Core"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("We add the necessary checksum using the specific "),t("code",[e._v("bitcoin-cli")]),e._v(" call.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export core_rec_desc_chksum=$core_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_rec_desc | jq -r '.checksum')\n")])])]),t("p",[e._v("We repeat the same to build the descriptor to receive the change.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export core_chg_desc=\"wsh(multi(2,$BDK_xpub_84_for_chg_desc,$core_xprv/84'/0'/0'/1/*))\"\nexport core_chg_desc_chksum=$core_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_chg_desc|jq -r '.checksum')\n")])])]),t("h4",{attrs:{id:"in-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#in-bdk"}},[e._v("#")]),e._v(" In BDK:")]),e._v(" "),t("p",[e._v("For BDK we set the derivation for receiving addresses and change addresses\nin the command line (maybe setting an alias)")]),e._v(" "),t("p",[e._v("Building the descriptor:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export BDK_rec_desc=\"wsh(multi(2,$BDK_xprv/84'/0'/0'/0/*,$core_xpub_84_for_rec_desc))\"`\n")])])]),t("p",[e._v("Please note that the order of the extended key in the descriptor MUST be the\nsame in the 2 wallets.")]),e._v(" "),t("p",[t("em",[e._v("We have chosen to put BDK first and in each software wallet, the public key\nderived from BDK will always come first. In alternative, we could have chosen to\nproduce the descriptor, "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/pull/17056?ref=tokendaily",target:"_blank",rel:"noopener noreferrer"}},[e._v("chosing a "),t("code",[e._v("soretedmulti")]),e._v(" multisignature setup"),t("OutboundLink")],1)]),e._v(".")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export BDK_rec_desc_chksum=$BDK_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_rec_desc | jq -r '.checksum')\nexport BDK_chg_desc=\"wsh(multi(2,$BDK_xprv/84'/0'/0'/1/*,$core_xpub_84_for_chg_desc))\"\nexport BDK_chg_desc_chksum=$BDK_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_chg_desc | jq -r '.checksum')\n")])])]),t("p",[e._v("To take a look at the variables we have produced so far:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("env | grep 'core_'\nenv | grep 'BDK_'\n")])])]),t("p",[e._v("Now we will use the multisig descriptor wallet to receive testnet coins with\nAlice and Bob's software")]),e._v(" "),t("h3",{attrs:{id:"3-use-each-others-software-to-receive-testnet-coins-from-a-faucet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#3-use-each-others-software-to-receive-testnet-coins-from-a-faucet"}},[e._v("#")]),e._v(" 3. Use each other's software to receive testnet coins from a faucet")]),e._v(" "),t("h4",{attrs:{id:"in-bitcoin-core-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#in-bitcoin-core-2"}},[e._v("#")]),e._v(" In Bitcoin Core")]),e._v(" "),t("p",[e._v('Alice must create an empty, experimental new "descriptors wallet" in Core and\nto import the multisig Output Descriptor.')]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('bitcoin-cli -testnet createwallet "multisig2of2withBDK" false true "" false true false\n')])])]),t("p",[e._v("The flag are to:")]),e._v(" "),t("ul",[t("li",[e._v("use the private keys")]),e._v(" "),t("li",[e._v("make it empty")]),e._v(" "),t("li",[e._v("no password provided to the wallet")]),e._v(" "),t("li",[e._v("reusing of addresses not allowed")]),e._v(" "),t("li",[e._v('"new experimental descriptors wallet"')]),e._v(" "),t("li",[e._v("don't load it on start up")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('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}]"\n')])])]),t("p",[e._v("Now Alice asks for her first receiving multisignature address.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export first_address=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getnewaddress)\necho $first_address\n")])])]),t("h4",{attrs:{id:"bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk"}},[e._v("#")]),e._v(" BDK")]),e._v(" "),t("p",[e._v("In BDK Bob can specify directly the descriptors on the command line to produce\nthe multisig address, because BDK is descriptors aware natively.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_new_address`\n')])])]),t("p",[e._v('Et voilà: if we have done everything correctly, the newly created address in\nCore is the same of the newly created address in BDK. this is part of the\n"miracle" of descriptors\' interoperability.')]),e._v(" "),t("h4",{attrs:{id:"we-ask-for-testnet-coins-giving-the-first-created-address"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#we-ask-for-testnet-coins-giving-the-first-created-address"}},[e._v("#")]),e._v(" We ask for testnet coins giving the first created address.")]),e._v(" "),t("p",[e._v('To find testnet coins for free, you can just google "testnet faucet" and you\nshould find some satoshis to play with. Just give to the site your first\ngenerated address and, in twenty minutes, you will find the satoshis in\nyour balance both in Core and in BDK.')]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('# to check it in Core:\n\nbitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getbalance\n\n# In BDK:\n\n# Sync with the blockchain\nrepl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sync\n# Get the balance\nrepl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_balance\n')])])]),t("p",[e._v("Some testnet faucets have an address to send back the unused satoshi after\nthe use. Take note of that because we will use it in the next step.")]),e._v(" "),t("h3",{attrs:{id:"4-we-return-part-of-the-satoshis-received-back-to-the-faucet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#4-we-return-part-of-the-satoshis-received-back-to-the-faucet"}},[e._v("#")]),e._v(" 4. we return part of the satoshis received back to the faucet")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('export psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletcreatefundedpsbt "[]" "[{\\"tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a\\":0.000012}]" | jq -r \'.psbt\')\n\nexport psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletprocesspsbt $psbt | jq -r \'.psbt\')\n{\n "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=",\n "complete": false\n}\n')])])]),t("p",[e._v("Exactly! Note the "),t("code",[e._v('"complete": false')]),e._v(". We have processed the transaction with\nCore but we miss one of the necessary key of the multisig 2of2 setup (The one\ncontained inside BDK).")]),e._v(" "),t("p",[t("code",[e._v("tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a")]),e._v(" is the address\nwe got from the faucet site to return the satoshis.")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("PSBT"),t("OutboundLink")],1),e._v(" is sent over to the BDK wallet owner who tries to sign the\ntransaction:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sign --psbt $psbt\n{\n "is_finalized": true,\n "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"\n}\n')])])]),t("p",[e._v('The signature has succeded (note the "is_finalized": true,) and now we can\nbroadcast the transction.')]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('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"\n{\n "txid": "a0b082e3b0579822d4a0b0fa95a4c4662f6b128ffd43fdcfe53c37473ce85dee"\n}\n')])])]),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("We have built an HDM and we have used it with two indipendent wallets, which\nare compatible with "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("BIP 174"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(". Hopefully we\nwill see many other compatible wallets beyound "),t("a",{attrs:{href:"https://bitcoincore.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Core"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v(",\nwith which we will be able to easily set up multi signature schemes.")])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[58],{413:function(e,t,r){"use strict";r.r(t);var a=r(7),s=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"introduction"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[e._v("#")]),e._v(" Introduction")]),e._v(" "),t("p",[e._v("I have tried to setup a 2 of 2 multi signature infrastructure with two\ndifferent wallets, which know nothing about each other, but are compliant with\ntwo very important protocols: "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("Partially Signed\nBitcoin Transactions"),t("OutboundLink")],1),e._v(" described in BIP 174.")]),e._v(" "),t("p",[e._v("Before these two protocols came into existence, making a multi signature setup\nand spending from it was possible only if the involved parties were using the\nsame wallet (eg. Electrum Desktop Wallet). This limitation was due to the fact\nthat the two parties had to agree:")]),e._v(" "),t("ul",[t("li",[e._v("on the particular type of script and address to use")]),e._v(" "),t("li",[e._v("on the way the transaction would be shared composed and signed with all the\ninvolved parties.")])]),e._v(" "),t("p",[t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(" are a way to express which kind scriptPubKey and\naddresses to produce with a key or a series of keys.")]),e._v(" "),t("p",[t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("PSBT"),t("OutboundLink")],1),e._v(" is instead the standard protocol used to create a transaction and to enrich\nit with the necessary signatures and other components, to make it valid and complete.")]),e._v(" "),t("p",[e._v("Together they provide a common ground to create and use a multi signature\ninfrastructure in a heterogeneous environment, and this is what I have put\nto test.")]),e._v(" "),t("h2",{attrs:{id:"the-use-case"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-use-case"}},[e._v("#")]),e._v(" The use case")]),e._v(" "),t("p",[e._v("Imagine Alice and Bob owning a company and being willing to put the corporate cash\nin a 2of2 multi signature setup, so that each one of them have to agree and sign each\ntransaction.")]),e._v(" "),t("h2",{attrs:{id:"the-role-of-descriptors"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-role-of-descriptors"}},[e._v("#")]),e._v(" The role of Descriptors")]),e._v(" "),t("p",[e._v("If Alice and Bob cannot agree on the software to use, to monitor the same financial\nsituation, the two software must control and produce exactly the same series\nof multisignature addresses.")]),e._v(" "),t("p",[e._v("To make two different software produce the same addresses in a deterministic way\nwe must ensure that they:")]),e._v(" "),t("ul",[t("li",[e._v("produce the same pair of public keys")]),e._v(" "),t("li",[e._v("combine them in the same order")]),e._v(" "),t("li",[e._v("put them inside the same scriptPubKey to produce the same address")])]),e._v(" "),t("p",[e._v("Here is where the "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(" come into play. They describe:")]),e._v(" "),t("ul",[t("li",[e._v("the sequence of public keys each extended key (xpub) will produce")]),e._v(" "),t("li",[e._v("the sequence in which the new public keys of various parties will enter into\nthe script")]),e._v(" "),t("li",[e._v("the type of script the wallet will prepare with that group keys and so the type\nof address the group of keys will produce.")])]),e._v(" "),t("p",[t("strong",[e._v("By sharing the same Descriptor, every compliant wallet will derive\ndeterministically the same series of multisig addresses")]),e._v(".")]),e._v(" "),t("p",[e._v("Imagine Alice using Bitcoin Core (from now on "),t("a",{attrs:{href:"https://bitcoincore.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Core"'),t("OutboundLink")],1),e._v(') as a\nWallet and Bob using a "Last generation" wallet, Bitcoin Development Kit\n(from now on '),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"BDK"'),t("OutboundLink")],1),e._v("), which uses descriptors and miniscript natively.")]),e._v(" "),t("p",[e._v("Each of these two software wallets should be able to:")]),e._v(" "),t("ul",[t("li",[e._v("Create a new address which is seen as belonging to the multi signature\nwallet in both software")]),e._v(" "),t("li",[e._v("Express the consent of each party by partially signing the transaction in a way\nthe other wallet can understand and complete it with its own signature.")])]),e._v(" "),t("p",[e._v("The infrastructure of multiple Extended keys combined toghether to produce\nmultiple multisignature addresses is often referred as\n"),t("em",[t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("Hierarchical Deterministic"),t("OutboundLink")],1),e._v(" multi signature wallet or HDM")]),e._v(".")]),e._v(" "),t("p",[e._v("What follows are the steps to create the HDM usable both in Core and\nin BDK.")]),e._v(" "),t("p",[t("em",[e._v("Note: In Core, "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/pull/16528",target:"_blank",rel:"noopener noreferrer"}},[e._v("Descriptor wallets"),t("OutboundLink")],1),e._v(" are still experimental and in general,\nboth wallets should be tested for descriptor capabilities only in testnet.")])]),e._v(" "),t("h2",{attrs:{id:"our-playground"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#our-playground"}},[e._v("#")]),e._v(" Our playground")]),e._v(" "),t("p",[e._v("We will build a 2of2 key set up that will be used cooperatively by Bitcoin Core\nand Bitcoin Development Kit.\nThe steps Alice and Bob will do are:")]),e._v(" "),t("ol",[t("li",[e._v("creation of the seed and the derived Extended Master Public and send it to\nthe other party")]),e._v(" "),t("li",[e._v("Create the multi signature descriptor for each wallet")]),e._v(" "),t("li",[e._v("Use each other's software to receive testnet coins from a faucet")]),e._v(" "),t("li",[e._v("return part of the coins to the faucet signing the transaction with both\nwallets.")])]),e._v(" "),t("p",[e._v("We need:")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Dev Kit"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://bitcoincore.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Core"),t("OutboundLink")],1),e._v(" (v0.21.0 or later)")])]),e._v(" "),t("h3",{attrs:{id:"1-creating-the-seeds-and-the-derived-extended-public-keys"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#1-creating-the-seeds-and-the-derived-extended-public-keys"}},[e._v("#")]),e._v(" 1. Creating the seeds and the derived Extended Public keys")]),e._v(" "),t("h4",{attrs:{id:"seeds-and-extended-master-public"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeds-and-extended-master-public"}},[e._v("#")]),e._v(" Seeds and Extended Master Public")]),e._v(" "),t("p",[e._v("We build an Extended Private Master Key for both wallet and derive a BIP84\nExtended Master Public for Bitcoin Core and then for BDK.")]),e._v(" "),t("p",[e._v("For Bitcoin Core (Alice):")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("# new Extended wallet data\nexport core_key=$(bdk-cli key generate)\n\n# New Extended Master Private\n\nexport core_xprv=$(echo $core_key | jq -r '.xprv')\n\n# Now I derive the xpubs (one for receiving and one for the change)\n# together with informations about the derivation path to be communicated\n# to BDK wallet's owner (Bob).\n\nexport core_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $core_xprv | jq -r '.xpub')\nexport core_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $core_xprv | jq -r '.xpub')\n")])])]),t("p",[e._v("For BDK (Bob) we do the same:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("# new Extended wallet data\n\nexport BDK_key=$(bdk-cli key generate)\n\n# New Extended Master Private\n\nexport BDK_xprv=$(echo $BDK_key | jq -r '.xprv')\n\n# Now I build the derived xpubs to be communicated (to Alice).\n\nexport BDK_xpub_84_for_rec_desc=$(bdk-cli key derive --path m/84h/0h/0h/0 --xprv $BDK_xprv | jq -r '.xpub')\nexport BDK_xpub_84_for_chg_desc=$(bdk-cli key derive --path m/84h/0h/0h/1 --xprv $BDK_xprv | jq -r '.xpub')\n")])])]),t("h3",{attrs:{id:"2-creation-of-the-multi-signature-descriptor-for-each-wallet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#2-creation-of-the-multi-signature-descriptor-for-each-wallet"}},[e._v("#")]),e._v(" 2. Creation of the multi signature descriptor for each wallet")]),e._v(" "),t("p",[e._v("To build a multisig wallet, each wallet owner must compose the descriptor\nadding:")]),e._v(" "),t("ul",[t("li",[e._v("his derived extended "),t("strong",[e._v("private")]),e._v(" key AND")]),e._v(" "),t("li",[e._v("all the extended "),t("strong",[e._v("public")]),e._v(" keys of the other wallets involved in the\nmulti signature setup")])]),e._v(" "),t("p",[t("em",[e._v("The different nature of the two keys (one is private and one is public) is\ndue to the fact that each wallet, to be able to partially sign the transaction,\n"),t("strong",[e._v("must manage the private key of the wallet's owner")])]),e._v(" AND have the other\nparty's public key. Otherwise, if we put both public keys, we would obtain\na watch-only wallet unable to sign the transactions. If we\nhad both extended private keys inside the descriptor, we would allow each party\nto finalize the transactions autonomously.")]),e._v(" "),t("h4",{attrs:{id:"in-bitcoin-core"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#in-bitcoin-core"}},[e._v("#")]),e._v(" In Bitcoin Core:")]),e._v(" "),t("p",[e._v("In our case, the multi signature descriptor for Bitcoin Core will be composed\nwith:")]),e._v(" "),t("ul",[t("li",[e._v("The BIP84 derived Extended "),t("strong",[e._v("Public")]),e._v(" Key from BDK")]),e._v(" "),t("li",[e._v("The BIP84 derived Extended "),t("strong",[e._v("Private")]),e._v(" Key from Core.")])]),e._v(" "),t("p",[e._v("BDK wallet's owner will send to Core's owner the derived xpub for this purpose.\nThis is how the Core's multisig descriptor will be created and put into an\nenvironment variable:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export core_rec_desc=\"wsh(multi(2,$BDK_xpub_84_for_rec_desc,$core_xprv/84'/0'/0'/0/*))\"\n")])])]),t("p",[e._v("Where of course "),t("code",[e._v("$BDK_xpub_84_for_rec_desc")]),e._v("is the derived master public created\nin BDK and received by Core's owner.")]),e._v(" "),t("p",[e._v("The meaning of what is before and after is illustrated in the doc that explain\nthe use of "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors in Bitcoin Core"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("We add the necessary checksum using the specific "),t("code",[e._v("bitcoin-cli")]),e._v(" call.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export core_rec_desc_chksum=$core_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_rec_desc | jq -r '.checksum')\n")])])]),t("p",[e._v("We repeat the same to build the descriptor to receive the change.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export core_chg_desc=\"wsh(multi(2,$BDK_xpub_84_for_chg_desc,$core_xprv/84'/0'/0'/1/*))\"\nexport core_chg_desc_chksum=$core_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $core_chg_desc|jq -r '.checksum')\n")])])]),t("h4",{attrs:{id:"in-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#in-bdk"}},[e._v("#")]),e._v(" In BDK:")]),e._v(" "),t("p",[e._v("For BDK we set the derivation for receiving addresses and change addresses\nin the command line (maybe setting an alias)")]),e._v(" "),t("p",[e._v("Building the descriptor:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export BDK_rec_desc=\"wsh(multi(2,$BDK_xprv/84'/0'/0'/0/*,$core_xpub_84_for_rec_desc))\"`\n")])])]),t("p",[e._v("Please note that the order of the extended key in the descriptor MUST be the\nsame in the 2 wallets.")]),e._v(" "),t("p",[t("em",[e._v("We have chosen to put BDK first and in each software wallet, the public key\nderived from BDK will always come first. In alternative, we could have chosen to\nproduce the descriptor, "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/pull/17056?ref=tokendaily",target:"_blank",rel:"noopener noreferrer"}},[e._v("chosing a "),t("code",[e._v("soretedmulti")]),e._v(" multisignature setup"),t("OutboundLink")],1)]),e._v(".")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export BDK_rec_desc_chksum=$BDK_rec_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_rec_desc | jq -r '.checksum')\nexport BDK_chg_desc=\"wsh(multi(2,$BDK_xprv/84'/0'/0'/1/*,$core_xpub_84_for_chg_desc))\"\nexport BDK_chg_desc_chksum=$BDK_chg_desc#$(bitcoin-cli -testnet getdescriptorinfo $BDK_chg_desc | jq -r '.checksum')\n")])])]),t("p",[e._v("To take a look at the variables we have produced so far:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("env | grep 'core_'\nenv | grep 'BDK_'\n")])])]),t("p",[e._v("Now we will use the multisig descriptor wallet to receive testnet coins with\nAlice and Bob's software")]),e._v(" "),t("h3",{attrs:{id:"3-use-each-others-software-to-receive-testnet-coins-from-a-faucet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#3-use-each-others-software-to-receive-testnet-coins-from-a-faucet"}},[e._v("#")]),e._v(" 3. Use each other's software to receive testnet coins from a faucet")]),e._v(" "),t("h4",{attrs:{id:"in-bitcoin-core-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#in-bitcoin-core-2"}},[e._v("#")]),e._v(" In Bitcoin Core")]),e._v(" "),t("p",[e._v('Alice must create an empty, experimental new "descriptors wallet" in Core and\nto import the multisig Output Descriptor.')]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('bitcoin-cli -testnet createwallet "multisig2of2withBDK" false true "" false true false\n')])])]),t("p",[e._v("The flag are to:")]),e._v(" "),t("ul",[t("li",[e._v("use the private keys")]),e._v(" "),t("li",[e._v("make it empty")]),e._v(" "),t("li",[e._v("no password provided to the wallet")]),e._v(" "),t("li",[e._v("reusing of addresses not allowed")]),e._v(" "),t("li",[e._v('"new experimental descriptors wallet"')]),e._v(" "),t("li",[e._v("don't load it on start up")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('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}]"\n')])])]),t("p",[e._v("Now Alice asks for her first receiving multisignature address.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("export first_address=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getnewaddress)\necho $first_address\n")])])]),t("h4",{attrs:{id:"bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk"}},[e._v("#")]),e._v(" BDK")]),e._v(" "),t("p",[e._v("In BDK Bob can specify directly the descriptors on the command line to produce\nthe multisig address, because BDK is descriptors aware natively.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_new_address`\n')])])]),t("p",[e._v('Et voilà: if we have done everything correctly, the newly created address in\nCore is the same of the newly created address in BDK. this is part of the\n"miracle" of descriptors\' interoperability.')]),e._v(" "),t("h4",{attrs:{id:"we-ask-for-testnet-coins-giving-the-first-created-address"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#we-ask-for-testnet-coins-giving-the-first-created-address"}},[e._v("#")]),e._v(" We ask for testnet coins giving the first created address.")]),e._v(" "),t("p",[e._v('To find testnet coins for free, you can just google "testnet faucet" and you\nshould find some satoshis to play with. Just give to the site your first\ngenerated address and, in twenty minutes, you will find the satoshis in\nyour balance both in Core and in BDK.')]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('# to check it in Core:\n\nbitcoin-cli -testnet -rpcwallet=multisig2of2withBDK getbalance\n\n# In BDK:\n\n# Sync with the blockchain\nrepl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sync\n# Get the balance\nrepl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint get_balance\n')])])]),t("p",[e._v("Some testnet faucets have an address to send back the unused satoshi after\nthe use. Take note of that because we will use it in the next step.")]),e._v(" "),t("h3",{attrs:{id:"4-we-return-part-of-the-satoshis-received-back-to-the-faucet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#4-we-return-part-of-the-satoshis-received-back-to-the-faucet"}},[e._v("#")]),e._v(" 4. we return part of the satoshis received back to the faucet")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('export psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletcreatefundedpsbt "[]" "[{\\"tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a\\":0.000012}]" | jq -r \'.psbt\')\n\nexport psbt=$(bitcoin-cli -testnet -rpcwallet=multisig2of2withBDK walletprocesspsbt $psbt | jq -r \'.psbt\')\n{\n "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=",\n "complete": false\n}\n')])])]),t("p",[e._v("Exactly! Note the "),t("code",[e._v('"complete": false')]),e._v(". We have processed the transaction with\nCore but we miss one of the necessary key of the multisig 2of2 setup (The one\ncontained inside BDK).")]),e._v(" "),t("p",[t("code",[e._v("tb1qrcesfj9f2d7x40xs6ztnlrcgxhh6vsw8658hjdhdy6qgkf6nfrds9rp79a")]),e._v(" is the address\nwe got from the faucet site to return the satoshis.")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("PSBT"),t("OutboundLink")],1),e._v(" is sent over to the BDK wallet owner who tries to sign the\ntransaction:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('repl -d "$BDK_rec_desc_chksum" -c "$BDK_chg_desc_chksum" -n testnet -w $BDK_fingerprint sign --psbt $psbt\n{\n "is_finalized": true,\n "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"\n}\n')])])]),t("p",[e._v('The signature has succeded (note the "is_finalized": true,) and now we can\nbroadcast the transction.')]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('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"\n{\n "txid": "a0b082e3b0579822d4a0b0fa95a4c4662f6b128ffd43fdcfe53c37473ce85dee"\n}\n')])])]),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("We have built an HDM and we have used it with two indipendent wallets, which\nare compatible with "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/BIP_0174",target:"_blank",rel:"noopener noreferrer"}},[e._v("BIP 174"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Output Descriptors"),t("OutboundLink")],1),e._v(". Hopefully we\nwill see many other compatible wallets beyound "),t("a",{attrs:{href:"https://bitcoincore.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Core"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://bitcoindevkit.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK"),t("OutboundLink")],1),e._v(",\nwith which we will be able to easily set up multi signature schemes.")])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/59.9b9541ac.js b/assets/js/59.1c408bd0.js similarity index 99% rename from assets/js/59.9b9541ac.js rename to assets/js/59.1c408bd0.js index d3de51f9c0..8e30176016 100644 --- a/assets/js/59.9b9541ac.js +++ b/assets/js/59.1c408bd0.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[59],{415:function(e,t,a){"use strict";a.r(t);var o=a(7),n=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 1 of 3 of a series. ("),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(", "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"}},[e._v("Part 3")]),e._v(")")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#introduction-what-is-fee-estimation"}},[e._v("Introduction: what is fee estimation?")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-problem"}},[e._v("The problem")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-challenges-and-the-solution"}},[e._v("The challenges and the solution")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-question"}},[e._v("The question")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-data-logger"}},[e._v("The data logger")])])])])]),e._v(" "),t("h2",{attrs:{id:"introduction-what-is-fee-estimation"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#introduction-what-is-fee-estimation"}},[e._v("#")]),e._v(" Introduction: what is fee estimation?")]),e._v(" "),t("p",[e._v("Fee estimation is the process of selecting the fee rate"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(" for a bitcoin transaction being created, according to two main factors:")]),e._v(" "),t("ul",[t("li",[e._v("The current congestion of the Bitcoin network.")]),e._v(" "),t("li",[e._v("The urgency, or lack thereof, for the transaction confirmation, i.e, its inclusion in a block.")])]),e._v(" "),t("p",[e._v("A fee rate should be adequate to the above factors: a fee too high would be a waste of money, because the same result could have been achieved with a lower expense. On the other hand, a fee rate too low would wait for a confirmation longer than planned or, even worse, the transaction could not be confirmed at all.")]),e._v(" "),t("h2",{attrs:{id:"the-problem"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-problem"}},[e._v("#")]),e._v(" The problem")]),e._v(" "),t("p",[e._v("Bitcoin Core offers fee estimation through the "),t("a",{attrs:{href:"https://bitcoincore.org/en/doc/0.20.0/rpc/util/estimatesmartfee/",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("estimatesmartfee")]),t("OutboundLink")],1),e._v(" RPC method, and there are also a lot of third-party "),t("a",{attrs:{href:"https://b10c.me/blog/003-a-list-of-public-bitcoin-feerate-estimation-apis/",target:"_blank",rel:"noopener noreferrer"}},[e._v("fee estimators"),t("OutboundLink")],1),e._v(" online, so do we need yet another estimator?")]),e._v(" "),t("p",[e._v("The model used by Bitcoin Core is not well suited for light-clients such as mobile wallets, even when running in pruned mode. Online estimators are lacking in terms of:")]),e._v(" "),t("ul",[t("li",[e._v("Privacy: Contacting the server leaks your IP (unless you are using Tor or a VPN), and the request timing may be used to correlate the request to a transaction broadcasted to the network soon thereafter.")]),e._v(" "),t("li",[e._v("Security: A malicious estimator could provide a high fee rate leading to a waste of money, or a low fee rate hampering the transaction confirmation.")])]),e._v(" "),t("p",[e._v("Replace By Fee (RBF) and Child Pays For Parent (CPFP) are techniques that can somewhat minimize the fee estimation problem, because one could simply underestimate the fee rate and then raise it when necessary, however:")]),e._v(" "),t("ul",[t("li",[e._v("RBF and CPFP may leak more information, such as patterns that may allow to detect the kind of wallet used, or which one of the transaction outputs is the change.")]),e._v(" "),t("li",[e._v('Requires additional interaction: the client must come back "online" to perform the fee bump. Sometimes this might be impractical or risky, for instance when using an offline signer or a multisignature with geographically distributed keys.')])]),e._v(" "),t("p",[e._v("Thus, this work is an effort to build a "),t("strong",[e._v("good fee estimator for purely peer to peer light clients")]),e._v(" such as "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("neutrino"),t("OutboundLink")],1),e._v(" based ones, or at least determine whether the approach we take is infeasible and open the discussion\nfor other, better, models.")]),e._v(" "),t("p",[e._v("In the meantime, another sub-goal is pursued: attract the interest of data scientists; Indeed the initial step for this analysis consists in constructing a data set, which could also also help kickstart other studies on fee estimation or, more broadly, on the Bitcoin mempool.")]),e._v(" "),t("h4",{attrs:{id:"the-challenges-and-the-solution"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-challenges-and-the-solution"}},[e._v("#")]),e._v(" The challenges and the solution")]),e._v(" "),t("p",[e._v("The hardest part of doing fee estimation on a light client is the lack of information: for example, Bitcoin Core's "),t("code",[e._v("estimatesmartfee")]),e._v(" uses up to the last 1008 blocks and knows everything about the mempool"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn2",id:"fnref2"}},[e._v("[2]")])]),e._v(", such as the fee rate of every transaction it contains, but a light-client does not.")]),e._v(" "),t("p",[e._v("Also, there are other factors that may help doing fee estimation, such as the day of the week (the mempool usually empties during the "),t("a",{attrs:{href:"https://www.blockchainresearchlab.org/2020/03/30/a-week-with-bitcoin-transaction-timing-and-transaction-fees/",target:"_blank",rel:"noopener noreferrer"}},[e._v("weekend"),t("OutboundLink")],1),e._v(") or the time of the day to anticipate recurring daily events\n(such as the batch of "),t("a",{attrs:{href:"https://b10c.me/mempool-observations/2-bitmex-broadcast-13-utc/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitmex withdrawals"),t("OutboundLink")],1),e._v(").")]),e._v(" "),t("p",[e._v("The idea is to apply Machine Learning (ML) techniques"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn3",id:"fnref3"}},[e._v("[3]")])]),e._v(" to discover patterns over what a light-client knows and see if they are enough to achieve consistently good estimations.")]),e._v(" "),t("h4",{attrs:{id:"the-question"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-question"}},[e._v("#")]),e._v(" The question")]),e._v(" "),t("p",[e._v('We are going to use a DNN (Deep Neural Network), a ML technique in the supervised learning branch. The "ELI5" is: give a lot of example inputs and the desired output to a black box; if there are correlations between inputs and outputs,\nand there are enough examples, the black box will eventually start predicting the correct output even with inputs it has never seen before.')]),e._v(" "),t("p",[e._v("To define our inputs and outputs, we need to start from the question we want to answer. For a fee estimator this is:")]),e._v(" "),t("p",[t("em",[e._v('"Which minimum fee rate should I use if I want this transaction to be confirmed in at most '),t("code",[e._v("n")]),e._v(' blocks?"')])]),e._v(" "),t("p",[e._v("This can be translated to a table with many rows like:")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("confirms_in")]),e._v(" "),t("th",[e._v("other_information")]),e._v(" "),t("th",[e._v("fee_rate")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("1")]),e._v(" "),t("td",[e._v("...")]),e._v(" "),t("td",[e._v("100.34")])]),e._v(" "),t("tr",[t("td",[e._v("2")]),e._v(" "),t("td",[e._v("...")]),e._v(" "),t("td",[e._v("84.33")])]),e._v(" "),t("tr",[t("td",[e._v("10")]),e._v(" "),t("td",[e._v("...")]),e._v(" "),t("td",[e._v("44.44")])])])]),e._v(" "),t("p",[e._v("where the "),t("code",[e._v("fee_rate")]),e._v(' column is the output we want, also called the "'),t("em",[e._v("target")]),e._v('" or "'),t("em",[e._v("label")]),e._v('" in ML terminology, and the other columns are our inputs.')]),e._v(" "),t("p",[e._v("Can we build this table just by looking at the Bitcoin blockchain? Unfortunately, we can't:\nThe main thing that's missing is an indication of when the node first saw a transaction that has been later confirmed in a block. With that knowledge we can say that the fee rate of that transaction was the exact value required to confirm\nwithin the number of blocks it actually took to be confirmed. For instance, if we see transaction "),t("code",[e._v("t")]),e._v(" when the blockchain is at height "),t("code",[e._v("1000")]),e._v(" and then we notice that "),t("code",[e._v("t")]),e._v(" has been included in block "),t("code",[e._v("1006")]),e._v(", we can deduce that the\nfee rate paid by "),t("code",[e._v("t")]),e._v(" was the exact value required to get confirmed within the next "),t("code",[e._v("6")]),e._v(" blocks.")]),e._v(" "),t("p",[e._v("So to build our model, we first need to gather these data, and machine learning needs a "),t("em",[e._v("lot")]),e._v(" of data to work well.")]),e._v(" "),t("h4",{attrs:{id:"the-data-logger"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-data-logger"}},[e._v("#")]),e._v(" The data logger")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://github.com/RCasatta/bitcoin_logger",target:"_blank",rel:"noopener noreferrer"}},[e._v("data logger"),t("OutboundLink")],1),e._v(" is built with the purpose of collecting all the data we need, and it's MIT licensed open source software written in Rust.")]),e._v(" "),t("p",[e._v("We need to register the moment in time when transactions enter in the node's mempool; to be efficient and precise we should not only call the RPC endpoints but listen to "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/zmq.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("ZMQ"),t("OutboundLink")],1),e._v(" events. Luckily, the just released bitcoin core 0.21.0 added a new "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/zmq.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("ZMQ"),t("OutboundLink")],1),e._v(" topic "),t("code",[e._v("zmqpubsequence")]),e._v(" notifying mempool events (and block events). The logger is also listening to "),t("code",[e._v("zmqpubrawtx")]),e._v(" and "),t("code",[e._v("zmqpubrawblock")]),e._v(" topics, to make less RPC calls.")]),e._v(" "),t("p",[e._v("We are not only interested in the timestamp of the transaction entering the mempool, but also how many blocks it will take until the same transaction is confirmed.\nIn the final dataset this field is called "),t("code",[e._v("confirms_in")]),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn4",id:"fnref4"}},[e._v("[4]")])]),e._v("; if "),t("code",[e._v("confirms_in = 1")]),e._v(" it means the transaction is confirmed in the first block created after it has been seen for the first time.")]),e._v(" "),t("p",[e._v("Another critical piece of information logged by the data logger is the "),t("code",[e._v("fee_rate")]),e._v(" of the transaction, since the absolute fee value paid by a bitcoin transaction is not available nor derivable given only the transaction itself, as the inputs don't have explicit amounts.")]),e._v(" "),t("p",[e._v("All these data (apart from the time of the transaction entering in the mempool) can actually be reconstructed simply by looking at the blockchain. However, querying the bitcoin node can be fairly slow, and during the model training iterations we want to recreate the ML dataset rapidly"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn5",id:"fnref5"}},[e._v("[5]")])]),e._v(", for example whenever we need to modify or add a new field.")]),e._v(" "),t("p",[e._v("For these reasons, the logger is split into two parts: a process listening to the events sent by our node, which creates raw logs, and then a second process that uses these logs to create the final CSV dataset.\nRaw logs are self-contained: for example, they contain all the previous transaction output values for every relevant transaction. This causes some redundancy, but in this case it's better to trade some efficiency for more performance\nwhen recreating the dataset.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/high-level-graph.svg",alt:"High level graph"}})]),e._v(" "),t("p",[e._v("My logger instance started collecting data on the 18th of December 2020, and as of today (25th January 2020), the raw logs are about 16GB.")]),e._v(" "),t("p",[e._v("I expect (or at least hope) the raw logs, the CSV dataset, or the data logger will be useful also for other projects as well, like monitoring the propagation of transactions or other works involving raw mempool data. We will share raw logs data through torrent soon.")]),e._v(" "),t("p",[e._v("In the following "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(" we are going to talk about the dataset.")],1),e._v(" "),t("hr",{staticClass:"footnotes-sep"}),e._v(" "),t("section",{staticClass:"footnotes"},[t("ol",{staticClass:"footnotes-list"},[t("li",{staticClass:"footnote-item",attrs:{id:"fn1"}},[t("p",[e._v("The transaction fee rate is the ratio between the absolute fee expressed in satoshi, over the weight of the transaction measured in virtual bytes. The weight of the transaction is similar to the byte size, however a part of the transaction (the segwit part) is discounted, their byte size is considered less because it creates less burden for the network. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn2"}},[t("p",[e._v("mempool is the set of transactions that are valid by consensus rules (for example, they are spending existing bitcoin), broadcasted in the bitcoin peer to peer network, but they are not yet part of the blockchain. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref2"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn3"}},[t("p",[e._v("DISCLAIMER: I am not an expert data-scientist! "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref3"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn4"}},[t("p",[e._v("Conceptually similar to bitcoin core "),t("code",[e._v("estimatesmartfee")]),e._v(' parameter called "blocks target", however, '),t("code",[e._v("confirms_in")]),e._v(" is the real value not the desired target. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref4"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn5"}},[t("p",[e._v("16GB of compressed raw logs are processed and a compressed CSV produced in about 5 minutes. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref5"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[59],{418:function(e,t,a){"use strict";a.r(t);var o=a(7),n=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 1 of 3 of a series. ("),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(", "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"}},[e._v("Part 3")]),e._v(")")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#introduction-what-is-fee-estimation"}},[e._v("Introduction: what is fee estimation?")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-problem"}},[e._v("The problem")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-challenges-and-the-solution"}},[e._v("The challenges and the solution")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-question"}},[e._v("The question")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-data-logger"}},[e._v("The data logger")])])])])]),e._v(" "),t("h2",{attrs:{id:"introduction-what-is-fee-estimation"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#introduction-what-is-fee-estimation"}},[e._v("#")]),e._v(" Introduction: what is fee estimation?")]),e._v(" "),t("p",[e._v("Fee estimation is the process of selecting the fee rate"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(" for a bitcoin transaction being created, according to two main factors:")]),e._v(" "),t("ul",[t("li",[e._v("The current congestion of the Bitcoin network.")]),e._v(" "),t("li",[e._v("The urgency, or lack thereof, for the transaction confirmation, i.e, its inclusion in a block.")])]),e._v(" "),t("p",[e._v("A fee rate should be adequate to the above factors: a fee too high would be a waste of money, because the same result could have been achieved with a lower expense. On the other hand, a fee rate too low would wait for a confirmation longer than planned or, even worse, the transaction could not be confirmed at all.")]),e._v(" "),t("h2",{attrs:{id:"the-problem"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-problem"}},[e._v("#")]),e._v(" The problem")]),e._v(" "),t("p",[e._v("Bitcoin Core offers fee estimation through the "),t("a",{attrs:{href:"https://bitcoincore.org/en/doc/0.20.0/rpc/util/estimatesmartfee/",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("estimatesmartfee")]),t("OutboundLink")],1),e._v(" RPC method, and there are also a lot of third-party "),t("a",{attrs:{href:"https://b10c.me/blog/003-a-list-of-public-bitcoin-feerate-estimation-apis/",target:"_blank",rel:"noopener noreferrer"}},[e._v("fee estimators"),t("OutboundLink")],1),e._v(" online, so do we need yet another estimator?")]),e._v(" "),t("p",[e._v("The model used by Bitcoin Core is not well suited for light-clients such as mobile wallets, even when running in pruned mode. Online estimators are lacking in terms of:")]),e._v(" "),t("ul",[t("li",[e._v("Privacy: Contacting the server leaks your IP (unless you are using Tor or a VPN), and the request timing may be used to correlate the request to a transaction broadcasted to the network soon thereafter.")]),e._v(" "),t("li",[e._v("Security: A malicious estimator could provide a high fee rate leading to a waste of money, or a low fee rate hampering the transaction confirmation.")])]),e._v(" "),t("p",[e._v("Replace By Fee (RBF) and Child Pays For Parent (CPFP) are techniques that can somewhat minimize the fee estimation problem, because one could simply underestimate the fee rate and then raise it when necessary, however:")]),e._v(" "),t("ul",[t("li",[e._v("RBF and CPFP may leak more information, such as patterns that may allow to detect the kind of wallet used, or which one of the transaction outputs is the change.")]),e._v(" "),t("li",[e._v('Requires additional interaction: the client must come back "online" to perform the fee bump. Sometimes this might be impractical or risky, for instance when using an offline signer or a multisignature with geographically distributed keys.')])]),e._v(" "),t("p",[e._v("Thus, this work is an effort to build a "),t("strong",[e._v("good fee estimator for purely peer to peer light clients")]),e._v(" such as "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("neutrino"),t("OutboundLink")],1),e._v(" based ones, or at least determine whether the approach we take is infeasible and open the discussion\nfor other, better, models.")]),e._v(" "),t("p",[e._v("In the meantime, another sub-goal is pursued: attract the interest of data scientists; Indeed the initial step for this analysis consists in constructing a data set, which could also also help kickstart other studies on fee estimation or, more broadly, on the Bitcoin mempool.")]),e._v(" "),t("h4",{attrs:{id:"the-challenges-and-the-solution"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-challenges-and-the-solution"}},[e._v("#")]),e._v(" The challenges and the solution")]),e._v(" "),t("p",[e._v("The hardest part of doing fee estimation on a light client is the lack of information: for example, Bitcoin Core's "),t("code",[e._v("estimatesmartfee")]),e._v(" uses up to the last 1008 blocks and knows everything about the mempool"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn2",id:"fnref2"}},[e._v("[2]")])]),e._v(", such as the fee rate of every transaction it contains, but a light-client does not.")]),e._v(" "),t("p",[e._v("Also, there are other factors that may help doing fee estimation, such as the day of the week (the mempool usually empties during the "),t("a",{attrs:{href:"https://www.blockchainresearchlab.org/2020/03/30/a-week-with-bitcoin-transaction-timing-and-transaction-fees/",target:"_blank",rel:"noopener noreferrer"}},[e._v("weekend"),t("OutboundLink")],1),e._v(") or the time of the day to anticipate recurring daily events\n(such as the batch of "),t("a",{attrs:{href:"https://b10c.me/mempool-observations/2-bitmex-broadcast-13-utc/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitmex withdrawals"),t("OutboundLink")],1),e._v(").")]),e._v(" "),t("p",[e._v("The idea is to apply Machine Learning (ML) techniques"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn3",id:"fnref3"}},[e._v("[3]")])]),e._v(" to discover patterns over what a light-client knows and see if they are enough to achieve consistently good estimations.")]),e._v(" "),t("h4",{attrs:{id:"the-question"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-question"}},[e._v("#")]),e._v(" The question")]),e._v(" "),t("p",[e._v('We are going to use a DNN (Deep Neural Network), a ML technique in the supervised learning branch. The "ELI5" is: give a lot of example inputs and the desired output to a black box; if there are correlations between inputs and outputs,\nand there are enough examples, the black box will eventually start predicting the correct output even with inputs it has never seen before.')]),e._v(" "),t("p",[e._v("To define our inputs and outputs, we need to start from the question we want to answer. For a fee estimator this is:")]),e._v(" "),t("p",[t("em",[e._v('"Which minimum fee rate should I use if I want this transaction to be confirmed in at most '),t("code",[e._v("n")]),e._v(' blocks?"')])]),e._v(" "),t("p",[e._v("This can be translated to a table with many rows like:")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("confirms_in")]),e._v(" "),t("th",[e._v("other_information")]),e._v(" "),t("th",[e._v("fee_rate")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("1")]),e._v(" "),t("td",[e._v("...")]),e._v(" "),t("td",[e._v("100.34")])]),e._v(" "),t("tr",[t("td",[e._v("2")]),e._v(" "),t("td",[e._v("...")]),e._v(" "),t("td",[e._v("84.33")])]),e._v(" "),t("tr",[t("td",[e._v("10")]),e._v(" "),t("td",[e._v("...")]),e._v(" "),t("td",[e._v("44.44")])])])]),e._v(" "),t("p",[e._v("where the "),t("code",[e._v("fee_rate")]),e._v(' column is the output we want, also called the "'),t("em",[e._v("target")]),e._v('" or "'),t("em",[e._v("label")]),e._v('" in ML terminology, and the other columns are our inputs.')]),e._v(" "),t("p",[e._v("Can we build this table just by looking at the Bitcoin blockchain? Unfortunately, we can't:\nThe main thing that's missing is an indication of when the node first saw a transaction that has been later confirmed in a block. With that knowledge we can say that the fee rate of that transaction was the exact value required to confirm\nwithin the number of blocks it actually took to be confirmed. For instance, if we see transaction "),t("code",[e._v("t")]),e._v(" when the blockchain is at height "),t("code",[e._v("1000")]),e._v(" and then we notice that "),t("code",[e._v("t")]),e._v(" has been included in block "),t("code",[e._v("1006")]),e._v(", we can deduce that the\nfee rate paid by "),t("code",[e._v("t")]),e._v(" was the exact value required to get confirmed within the next "),t("code",[e._v("6")]),e._v(" blocks.")]),e._v(" "),t("p",[e._v("So to build our model, we first need to gather these data, and machine learning needs a "),t("em",[e._v("lot")]),e._v(" of data to work well.")]),e._v(" "),t("h4",{attrs:{id:"the-data-logger"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-data-logger"}},[e._v("#")]),e._v(" The data logger")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://github.com/RCasatta/bitcoin_logger",target:"_blank",rel:"noopener noreferrer"}},[e._v("data logger"),t("OutboundLink")],1),e._v(" is built with the purpose of collecting all the data we need, and it's MIT licensed open source software written in Rust.")]),e._v(" "),t("p",[e._v("We need to register the moment in time when transactions enter in the node's mempool; to be efficient and precise we should not only call the RPC endpoints but listen to "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/zmq.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("ZMQ"),t("OutboundLink")],1),e._v(" events. Luckily, the just released bitcoin core 0.21.0 added a new "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/zmq.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("ZMQ"),t("OutboundLink")],1),e._v(" topic "),t("code",[e._v("zmqpubsequence")]),e._v(" notifying mempool events (and block events). The logger is also listening to "),t("code",[e._v("zmqpubrawtx")]),e._v(" and "),t("code",[e._v("zmqpubrawblock")]),e._v(" topics, to make less RPC calls.")]),e._v(" "),t("p",[e._v("We are not only interested in the timestamp of the transaction entering the mempool, but also how many blocks it will take until the same transaction is confirmed.\nIn the final dataset this field is called "),t("code",[e._v("confirms_in")]),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn4",id:"fnref4"}},[e._v("[4]")])]),e._v("; if "),t("code",[e._v("confirms_in = 1")]),e._v(" it means the transaction is confirmed in the first block created after it has been seen for the first time.")]),e._v(" "),t("p",[e._v("Another critical piece of information logged by the data logger is the "),t("code",[e._v("fee_rate")]),e._v(" of the transaction, since the absolute fee value paid by a bitcoin transaction is not available nor derivable given only the transaction itself, as the inputs don't have explicit amounts.")]),e._v(" "),t("p",[e._v("All these data (apart from the time of the transaction entering in the mempool) can actually be reconstructed simply by looking at the blockchain. However, querying the bitcoin node can be fairly slow, and during the model training iterations we want to recreate the ML dataset rapidly"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn5",id:"fnref5"}},[e._v("[5]")])]),e._v(", for example whenever we need to modify or add a new field.")]),e._v(" "),t("p",[e._v("For these reasons, the logger is split into two parts: a process listening to the events sent by our node, which creates raw logs, and then a second process that uses these logs to create the final CSV dataset.\nRaw logs are self-contained: for example, they contain all the previous transaction output values for every relevant transaction. This causes some redundancy, but in this case it's better to trade some efficiency for more performance\nwhen recreating the dataset.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/high-level-graph.svg",alt:"High level graph"}})]),e._v(" "),t("p",[e._v("My logger instance started collecting data on the 18th of December 2020, and as of today (25th January 2020), the raw logs are about 16GB.")]),e._v(" "),t("p",[e._v("I expect (or at least hope) the raw logs, the CSV dataset, or the data logger will be useful also for other projects as well, like monitoring the propagation of transactions or other works involving raw mempool data. We will share raw logs data through torrent soon.")]),e._v(" "),t("p",[e._v("In the following "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(" we are going to talk about the dataset.")],1),e._v(" "),t("hr",{staticClass:"footnotes-sep"}),e._v(" "),t("section",{staticClass:"footnotes"},[t("ol",{staticClass:"footnotes-list"},[t("li",{staticClass:"footnote-item",attrs:{id:"fn1"}},[t("p",[e._v("The transaction fee rate is the ratio between the absolute fee expressed in satoshi, over the weight of the transaction measured in virtual bytes. The weight of the transaction is similar to the byte size, however a part of the transaction (the segwit part) is discounted, their byte size is considered less because it creates less burden for the network. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn2"}},[t("p",[e._v("mempool is the set of transactions that are valid by consensus rules (for example, they are spending existing bitcoin), broadcasted in the bitcoin peer to peer network, but they are not yet part of the blockchain. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref2"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn3"}},[t("p",[e._v("DISCLAIMER: I am not an expert data-scientist! "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref3"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn4"}},[t("p",[e._v("Conceptually similar to bitcoin core "),t("code",[e._v("estimatesmartfee")]),e._v(' parameter called "blocks target", however, '),t("code",[e._v("confirms_in")]),e._v(" is the real value not the desired target. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref4"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn5"}},[t("p",[e._v("16GB of compressed raw logs are processed and a compressed CSV produced in about 5 minutes. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref5"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/60.48c95147.js b/assets/js/60.3b526e17.js similarity index 99% rename from assets/js/60.48c95147.js rename to assets/js/60.3b526e17.js index f8136e6826..f62190d2f1 100644 --- a/assets/js/60.48c95147.js +++ b/assets/js/60.3b526e17.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[60],{417:function(e,t,a){"use strict";a.r(t);var o=a(7),n=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 2 of 3 of a series. ("),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(", "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"}},[e._v("Part 3")]),e._v(")")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-dataset"}},[e._v("The dataset")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-mempool"}},[e._v("The mempool")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-outliers"}},[e._v("The outliers")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#recap"}},[e._v("Recap")])])])])]),e._v(" "),t("h2",{attrs:{id:"the-dataset"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-dataset"}},[e._v("#")]),e._v(" The dataset")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://storage.googleapis.com/bitcoin_log/dataset_18.csv.gz",target:"_blank",rel:"noopener noreferrer"}},[e._v("dataset"),t("OutboundLink")],1),e._v(" is publicly available (~500MB gzip compressed, ~2GB as plain CSV).")]),e._v(" "),t("p",[e._v("The output of the model is the fee rate, expressed in "),t("code",[e._v("[satoshi/vbytes]")]),e._v(".")]),e._v(" "),t("p",[e._v("What about the inputs? Generally speaking, we have two main requirements for what can be included as input for our model:")]),e._v(" "),t("ul",[t("li",[e._v("It must be correlated to the output, even with a non-linear relation.")]),e._v(" "),t("li",[e._v("It must be available to a light client: for instance, assuming to have knowledge and an index of the last 1000 blocks is considered too much.")])]),e._v(" "),t("p",[e._v("To evaluate the approach we are taking, we also want to compare our model's results with another available estimation: for this reason the dataset includes data to compute the error agains Bitcoin Core's "),t("code",[e._v("estimatesmartfee")]),e._v(" results, even though we are not going to use it for this model.")]),e._v(" "),t("p",[e._v("The dataset will contain only transactions that spend already confirmed inputs. If we wanted to include transactions with unconfirmed inputs as well, the fee rate would have to be computed as a whole;\nfor example if transaction "),t("code",[e._v("t2")]),e._v(" spends an unconfirmed input from "),t("code",[e._v("t1")]),e._v(" (while "),t("code",[e._v("t1")]),e._v(" only spends confirmed inputs, and all its other outputs are unspent), the aggregated fee rate would have to be used.\nSupposing "),t("code",[e._v("f()")]),e._v(" is extracts the absolute fee and "),t("code",[e._v("w()")]),e._v(" the transaction weight, the aggregated fee rate would be "),t("code",[e._v("(f(t1) + f(t2)) / (w(t1) + w(t2))")]),e._v(". Thus, as already said previously, to keep things simple the model simply discards all the transaction\nthat would need to perform this computation.")]),e._v(" "),t("p",[e._v("For the same reason the dataset has the "),t("code",[e._v("parent_in_cpfp")]),e._v(" flag. When a transaction has inputs confirmed (so it's not excluded by the previous rule) but one or more of its output have been spent by a transaction confirmed in the same block, "),t("code",[e._v("parent_in_cpfp")]),e._v(" is "),t("code",[e._v("1")]),e._v(".\nTransactions with "),t("code",[e._v("parent_in_cpfp = 1")]),e._v(" are included in the dataset but excluded by the current model, since the miner probably considered an aggregated fee rate while picking the transactions to build a block.")]),e._v(" "),t("h4",{attrs:{id:"the-mempool"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-mempool"}},[e._v("#")]),e._v(" The mempool")]),e._v(" "),t("p",[e._v("The most important input of our model is the current "),t("em",[e._v("status")]),e._v(' of the mempool itself. However, we cannot feed the model with a list of the fee rate of every unconfirmed transaction, because this array would have a variable length.\nTo overcome this, the transaction contained in the mempool are grouped in "buckets" which are basically subsets of the mempool where all the transactions contained in a bucket have a similar fee rate. In particular we only care about the\n'),t("em",[e._v("number")]),e._v(" of transaction in every "),t("em",[e._v("bucket")]),e._v(", not which transactions it contains.")]),e._v(" "),t("p",[e._v("The mempool buckets array is defined by two parameters, the "),t("code",[e._v("percentage_increment")]),e._v(" and the "),t("code",[e._v("array_max")]),e._v(" value.\nStarting from the minimum fee rate value "),t("code",[e._v("min_relay_fee=1.0")]),e._v(", the "),t("code",[e._v("ith")]),e._v(" element is: "),t("code",[e._v("a_i=min_relay_fee * (1+percentage_increment)^(i+1)")])]),e._v(" "),t("p",[e._v("For instance, choosing the mempool buckets array to have parameters "),t("code",[e._v("percentage_increment = 50%")]),e._v(" and "),t("code",[e._v("array_max = 500.0 sat/vbytes")]),e._v(" the buckets would be constructed like so:")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("bucket")]),e._v(" "),t("th",[e._v("bucket min fee rate")]),e._v(" "),t("th",[e._v("bucket max fee rate")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("a_0")]),e._v(" "),t("td",[e._v("1.0")]),e._v(" "),t("td",[e._v("1.5")])]),e._v(" "),t("tr",[t("td",[e._v("a_1")]),e._v(" "),t("td",[e._v("1.5")]),e._v(" "),t("td",[e._v("2.25")])]),e._v(" "),t("tr",[t("td",[e._v("a_2")]),e._v(" "),t("td",[e._v("2.25")]),e._v(" "),t("td",[e._v("3.375")])]),e._v(" "),t("tr",[t("td",[e._v("a_15")]),e._v(" "),t("td",[e._v("437.89")]),e._v(" "),t("td",[e._v("inf")])])])]),e._v(" "),t("p",[e._v("The array stops at "),t("code",[e._v("a15")]),e._v(" because "),t("code",[e._v("a16")]),e._v(" would have a bucket min greater than "),t("code",[e._v("array_max")]),e._v(".")]),e._v(" "),t("p",[e._v("The model is for light-client such as "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("neutrino"),t("OutboundLink")],1),e._v(" based ones. In these clients the mempool is already available (it's needed to check for received transactions) but we can't compute fee rates of this transactions because previous confirmed inputs are not in the mempool!")]),e._v(" "),t("p",[e._v("Luckily, "),t("strong",[e._v("thanks to temporal locality "),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(", an important part of mempool transactions spend outputs created very recently")]),e._v(", for example in the last 6 blocks.\nThe blocks are available through the p2p network, and downloading the last 6 is considered a good compromise between resource consumption and accurate prediction. We need the model to be built with the same data available in the prediction phase, as a consequence "),t("em",[e._v("the mempool data in the dataset refers only to transactions having their inputs in the last 6 blocks")]),e._v(". However the "),t("code",[e._v("bitcoin-csv")]),e._v(" tool inside the "),t("a",{attrs:{href:"https://github.com/RCasatta/bitcoin_logger",target:"_blank",rel:"noopener noreferrer"}},[e._v("data logger"),t("OutboundLink")],1),e._v(" allows to configure this parameter.")]),e._v(" "),t("h4",{attrs:{id:"the-outliers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-outliers"}},[e._v("#")]),e._v(" The outliers")]),e._v(" "),t("p",[e._v("The dataset also contains the block percentile fee rate "),t("code",[e._v("q_k")]),e._v(", considering "),t("code",[e._v("r_i")]),e._v(" to be the rate of the "),t("code",[e._v("ith")]),e._v(" transaction in a block, "),t("code",[e._v("q_k")]),e._v(" is the fee rate value such that for each transaction in a block "),t("code",[e._v("r_i")]),e._v(" < "),t("code",[e._v("q_k")]),e._v(" returns the "),t("code",[e._v("k%")]),e._v(" transactions in the block that are paying lower fees.")]),e._v(" "),t("p",[e._v("Percentiles are not used to feed the model but to filter some outliers tx.\nRemoving this observations is controversial at best and considered cheating at worse. However, it should be considered that Bitcoin Core "),t("code",[e._v("estimatesmartfee")]),e._v(" doesn't even bother to give estimation for the next block, we think this is due to the fact that many transactions that are confirming in the next block are huge overestimation, or clearly errors like "),t("a",{attrs:{href:"https://blockstream.info/tx/33291156ab79e9b4a1019b618b0acfa18cbdf8fa6b71c43a9eed62a849b86f9a",target:"_blank",rel:"noopener noreferrer"}},[e._v("this one"),t("OutboundLink")],1),e._v(" we found when we started logging data.\nThese outliers are several for transactions confirming in the next block ("),t("code",[e._v("confirms_in=1")]),e._v("), less so for "),t("code",[e._v("confirms_in=2")]),e._v(", mostly disappeared for "),t("code",[e._v("confirms_in=3")]),e._v(" or more. It's counterintuitive that overestimation exists for "),t("code",[e._v("confirms_in>1")]),e._v(", by definition an overestimation is a fee rate way higher than needed, so how is possible that an overestimation doesn't enter the very next block? There are a couple of reasons why a block is discovered without containing a transaction with high fee rate:")]),e._v(" "),t("ul",[t("li",[e._v("network latency: my node saw the transaction but the miner didn't see that transaction yet,")]),e._v(" "),t("li",[e._v("block building latency: the miner saw the transaction, but didn't finish to rebuild the block template or decided it's more efficient to finish a cycle on the older block template.")])]),e._v(" "),t("p",[e._v("To keep the model balanced, when overestimation is filtered out, underestimation are filtered out as well. This also has the effect to remove some of the transactions possibly included because a fee is payed out-of-band.\nAnother reason to filter transactions is that the dataset is over-represented by transactions with low "),t("code",[e._v("confirms_in")]),e._v(": more than 50% of transactions get confirmed in the next block, so we think it's good to filter some of these transactions.")]),e._v(" "),t("p",[e._v("The applied filters are the following:")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("confirms_in")]),e._v(" "),t("th",[e._v("lower")]),e._v(" "),t("th",[e._v("higher")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("1")]),e._v(" "),t("td",[e._v("q45")]),e._v(" "),t("td",[e._v("q55")])]),e._v(" "),t("tr",[t("td",[e._v("2")]),e._v(" "),t("td",[e._v("q30")]),e._v(" "),t("td",[e._v("q70")])]),e._v(" "),t("tr",[t("td",[e._v("3")]),e._v(" "),t("td",[e._v("q1")]),e._v(" "),t("td",[e._v("q99")])])])]),e._v(" "),t("p",[e._v("Not yet convinced by the removal of these outliers? The "),t("a",{attrs:{href:"https://storage.googleapis.com/bitcoin_log/dataset_18.csv.gz",target:"_blank",rel:"noopener noreferrer"}},[e._v("dataset"),t("OutboundLink")],1),e._v(" contains all the observations, make your model 😃")]),e._v(" "),t("h4",{attrs:{id:"recap"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#recap"}},[e._v("#")]),e._v(" Recap")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("column")]),e._v(" "),t("th",[e._v("used in the model")]),e._v(" "),t("th",[e._v("description")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("txid")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Transaction hash, useful for debugging")])]),e._v(" "),t("tr",[t("td",[e._v("timestamp")]),e._v(" "),t("td",[e._v("converted")]),e._v(" "),t("td",[e._v("The time when the transaction has been added in the mempool, in the model is used in the form "),t("code",[e._v("day_of_week")]),e._v(" and "),t("code",[e._v("hour")])])]),e._v(" "),t("tr",[t("td",[e._v("current_height")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("The blockchain height seen by the node in this moment")])]),e._v(" "),t("tr",[t("td",[e._v("confirms_in")]),e._v(" "),t("td",[e._v("yes")]),e._v(" "),t("td",[e._v("This transaction confirmed at block height "),t("code",[e._v("current_height+confirms_in")])])]),e._v(" "),t("tr",[t("td",[e._v("fee_rate")]),e._v(" "),t("td",[e._v("target")]),e._v(" "),t("td",[e._v("This transaction fee rate measured in "),t("code",[e._v("[sat/vbytes]")])])]),e._v(" "),t("tr",[t("td",[e._v("fee_rate_bytes")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("fee rate in satoshi / bytes, used to check Bitcoin Core "),t("code",[e._v("estimatesmartfee")]),e._v(" predictions")])]),e._v(" "),t("tr",[t("td",[e._v("block_avg_fee")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("block average fee rate "),t("code",[e._v("[sat/vbytes]")]),e._v(" of block "),t("code",[e._v("current_height+confirms_in")])])]),e._v(" "),t("tr",[t("td",[e._v("core_econ")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("bitcoin "),t("code",[e._v("estimatesmartfee")]),e._v(" result for "),t("code",[e._v("confirms_in")]),e._v(" block target and in economic mode. Could be not available "),t("code",[e._v("?")]),e._v(" when a block is connected more recently than the estimation has been requested, estimation are requested every 10 secs.")])]),e._v(" "),t("tr",[t("td",[e._v("core_cons")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Same as above but with conservative mode")])]),e._v(" "),t("tr",[t("td",[e._v("mempool_len")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Sum of the mempool transactions with fee rate available (sum of every "),t("code",[e._v("a*")]),e._v(" field)")])]),e._v(" "),t("tr",[t("td",[e._v("parent_in_cpfp")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("It's 1 when the transaction has outputs that are spent in the same block in which the transaction is confirmed (they are parent in a CPFP relations).")])]),e._v(" "),t("tr",[t("td",[e._v("q1-q30-...")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Transaction confirming fast could be outliers, usually paying a lot more than required, this percentiles are used to filter those transactions,")])]),e._v(" "),t("tr",[t("td",[e._v("a1-a2-...")]),e._v(" "),t("td",[e._v("yes")]),e._v(" "),t("td",[e._v("Contains the number of transaction in the mempool with known fee rate in the ith bucket.")])])])]),e._v(" "),t("p",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/the-good-the-bad-the-ugly.jpg",alt:"The good, the bad and the ugly"}})]),t("div",{attrs:{align:"center"}},[e._v('My biological neural network fired this, I think it\'s because a lot of chapters start with "The"')]),e._v(" "),t("br"),t("br"),t("p"),e._v(" "),t("p",[e._v("In the previous "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(" we talked about the problem.")],1),e._v(" "),t("p",[e._v("In the following "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"}},[e._v("Part 3")]),e._v(" we are going to talk about the model.")],1),e._v(" "),t("hr",{staticClass:"footnotes-sep"}),e._v(" "),t("section",{staticClass:"footnotes"},[t("ol",{staticClass:"footnotes-list"},[t("li",{staticClass:"footnote-item",attrs:{id:"fn1"}},[t("p",[e._v("In computer science temporal locality refers to the tendency to access recent data more often than older data. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[60],{416:function(e,t,a){"use strict";a.r(t);var o=a(7),n=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 2 of 3 of a series. ("),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(", "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"}},[e._v("Part 3")]),e._v(")")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-dataset"}},[e._v("The dataset")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-mempool"}},[e._v("The mempool")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-outliers"}},[e._v("The outliers")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#recap"}},[e._v("Recap")])])])])]),e._v(" "),t("h2",{attrs:{id:"the-dataset"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-dataset"}},[e._v("#")]),e._v(" The dataset")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://storage.googleapis.com/bitcoin_log/dataset_18.csv.gz",target:"_blank",rel:"noopener noreferrer"}},[e._v("dataset"),t("OutboundLink")],1),e._v(" is publicly available (~500MB gzip compressed, ~2GB as plain CSV).")]),e._v(" "),t("p",[e._v("The output of the model is the fee rate, expressed in "),t("code",[e._v("[satoshi/vbytes]")]),e._v(".")]),e._v(" "),t("p",[e._v("What about the inputs? Generally speaking, we have two main requirements for what can be included as input for our model:")]),e._v(" "),t("ul",[t("li",[e._v("It must be correlated to the output, even with a non-linear relation.")]),e._v(" "),t("li",[e._v("It must be available to a light client: for instance, assuming to have knowledge and an index of the last 1000 blocks is considered too much.")])]),e._v(" "),t("p",[e._v("To evaluate the approach we are taking, we also want to compare our model's results with another available estimation: for this reason the dataset includes data to compute the error agains Bitcoin Core's "),t("code",[e._v("estimatesmartfee")]),e._v(" results, even though we are not going to use it for this model.")]),e._v(" "),t("p",[e._v("The dataset will contain only transactions that spend already confirmed inputs. If we wanted to include transactions with unconfirmed inputs as well, the fee rate would have to be computed as a whole;\nfor example if transaction "),t("code",[e._v("t2")]),e._v(" spends an unconfirmed input from "),t("code",[e._v("t1")]),e._v(" (while "),t("code",[e._v("t1")]),e._v(" only spends confirmed inputs, and all its other outputs are unspent), the aggregated fee rate would have to be used.\nSupposing "),t("code",[e._v("f()")]),e._v(" is extracts the absolute fee and "),t("code",[e._v("w()")]),e._v(" the transaction weight, the aggregated fee rate would be "),t("code",[e._v("(f(t1) + f(t2)) / (w(t1) + w(t2))")]),e._v(". Thus, as already said previously, to keep things simple the model simply discards all the transaction\nthat would need to perform this computation.")]),e._v(" "),t("p",[e._v("For the same reason the dataset has the "),t("code",[e._v("parent_in_cpfp")]),e._v(" flag. When a transaction has inputs confirmed (so it's not excluded by the previous rule) but one or more of its output have been spent by a transaction confirmed in the same block, "),t("code",[e._v("parent_in_cpfp")]),e._v(" is "),t("code",[e._v("1")]),e._v(".\nTransactions with "),t("code",[e._v("parent_in_cpfp = 1")]),e._v(" are included in the dataset but excluded by the current model, since the miner probably considered an aggregated fee rate while picking the transactions to build a block.")]),e._v(" "),t("h4",{attrs:{id:"the-mempool"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-mempool"}},[e._v("#")]),e._v(" The mempool")]),e._v(" "),t("p",[e._v("The most important input of our model is the current "),t("em",[e._v("status")]),e._v(' of the mempool itself. However, we cannot feed the model with a list of the fee rate of every unconfirmed transaction, because this array would have a variable length.\nTo overcome this, the transaction contained in the mempool are grouped in "buckets" which are basically subsets of the mempool where all the transactions contained in a bucket have a similar fee rate. In particular we only care about the\n'),t("em",[e._v("number")]),e._v(" of transaction in every "),t("em",[e._v("bucket")]),e._v(", not which transactions it contains.")]),e._v(" "),t("p",[e._v("The mempool buckets array is defined by two parameters, the "),t("code",[e._v("percentage_increment")]),e._v(" and the "),t("code",[e._v("array_max")]),e._v(" value.\nStarting from the minimum fee rate value "),t("code",[e._v("min_relay_fee=1.0")]),e._v(", the "),t("code",[e._v("ith")]),e._v(" element is: "),t("code",[e._v("a_i=min_relay_fee * (1+percentage_increment)^(i+1)")])]),e._v(" "),t("p",[e._v("For instance, choosing the mempool buckets array to have parameters "),t("code",[e._v("percentage_increment = 50%")]),e._v(" and "),t("code",[e._v("array_max = 500.0 sat/vbytes")]),e._v(" the buckets would be constructed like so:")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("bucket")]),e._v(" "),t("th",[e._v("bucket min fee rate")]),e._v(" "),t("th",[e._v("bucket max fee rate")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("a_0")]),e._v(" "),t("td",[e._v("1.0")]),e._v(" "),t("td",[e._v("1.5")])]),e._v(" "),t("tr",[t("td",[e._v("a_1")]),e._v(" "),t("td",[e._v("1.5")]),e._v(" "),t("td",[e._v("2.25")])]),e._v(" "),t("tr",[t("td",[e._v("a_2")]),e._v(" "),t("td",[e._v("2.25")]),e._v(" "),t("td",[e._v("3.375")])]),e._v(" "),t("tr",[t("td",[e._v("a_15")]),e._v(" "),t("td",[e._v("437.89")]),e._v(" "),t("td",[e._v("inf")])])])]),e._v(" "),t("p",[e._v("The array stops at "),t("code",[e._v("a15")]),e._v(" because "),t("code",[e._v("a16")]),e._v(" would have a bucket min greater than "),t("code",[e._v("array_max")]),e._v(".")]),e._v(" "),t("p",[e._v("The model is for light-client such as "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("neutrino"),t("OutboundLink")],1),e._v(" based ones. In these clients the mempool is already available (it's needed to check for received transactions) but we can't compute fee rates of this transactions because previous confirmed inputs are not in the mempool!")]),e._v(" "),t("p",[e._v("Luckily, "),t("strong",[e._v("thanks to temporal locality "),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(", an important part of mempool transactions spend outputs created very recently")]),e._v(", for example in the last 6 blocks.\nThe blocks are available through the p2p network, and downloading the last 6 is considered a good compromise between resource consumption and accurate prediction. We need the model to be built with the same data available in the prediction phase, as a consequence "),t("em",[e._v("the mempool data in the dataset refers only to transactions having their inputs in the last 6 blocks")]),e._v(". However the "),t("code",[e._v("bitcoin-csv")]),e._v(" tool inside the "),t("a",{attrs:{href:"https://github.com/RCasatta/bitcoin_logger",target:"_blank",rel:"noopener noreferrer"}},[e._v("data logger"),t("OutboundLink")],1),e._v(" allows to configure this parameter.")]),e._v(" "),t("h4",{attrs:{id:"the-outliers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-outliers"}},[e._v("#")]),e._v(" The outliers")]),e._v(" "),t("p",[e._v("The dataset also contains the block percentile fee rate "),t("code",[e._v("q_k")]),e._v(", considering "),t("code",[e._v("r_i")]),e._v(" to be the rate of the "),t("code",[e._v("ith")]),e._v(" transaction in a block, "),t("code",[e._v("q_k")]),e._v(" is the fee rate value such that for each transaction in a block "),t("code",[e._v("r_i")]),e._v(" < "),t("code",[e._v("q_k")]),e._v(" returns the "),t("code",[e._v("k%")]),e._v(" transactions in the block that are paying lower fees.")]),e._v(" "),t("p",[e._v("Percentiles are not used to feed the model but to filter some outliers tx.\nRemoving this observations is controversial at best and considered cheating at worse. However, it should be considered that Bitcoin Core "),t("code",[e._v("estimatesmartfee")]),e._v(" doesn't even bother to give estimation for the next block, we think this is due to the fact that many transactions that are confirming in the next block are huge overestimation, or clearly errors like "),t("a",{attrs:{href:"https://blockstream.info/tx/33291156ab79e9b4a1019b618b0acfa18cbdf8fa6b71c43a9eed62a849b86f9a",target:"_blank",rel:"noopener noreferrer"}},[e._v("this one"),t("OutboundLink")],1),e._v(" we found when we started logging data.\nThese outliers are several for transactions confirming in the next block ("),t("code",[e._v("confirms_in=1")]),e._v("), less so for "),t("code",[e._v("confirms_in=2")]),e._v(", mostly disappeared for "),t("code",[e._v("confirms_in=3")]),e._v(" or more. It's counterintuitive that overestimation exists for "),t("code",[e._v("confirms_in>1")]),e._v(", by definition an overestimation is a fee rate way higher than needed, so how is possible that an overestimation doesn't enter the very next block? There are a couple of reasons why a block is discovered without containing a transaction with high fee rate:")]),e._v(" "),t("ul",[t("li",[e._v("network latency: my node saw the transaction but the miner didn't see that transaction yet,")]),e._v(" "),t("li",[e._v("block building latency: the miner saw the transaction, but didn't finish to rebuild the block template or decided it's more efficient to finish a cycle on the older block template.")])]),e._v(" "),t("p",[e._v("To keep the model balanced, when overestimation is filtered out, underestimation are filtered out as well. This also has the effect to remove some of the transactions possibly included because a fee is payed out-of-band.\nAnother reason to filter transactions is that the dataset is over-represented by transactions with low "),t("code",[e._v("confirms_in")]),e._v(": more than 50% of transactions get confirmed in the next block, so we think it's good to filter some of these transactions.")]),e._v(" "),t("p",[e._v("The applied filters are the following:")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("confirms_in")]),e._v(" "),t("th",[e._v("lower")]),e._v(" "),t("th",[e._v("higher")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("1")]),e._v(" "),t("td",[e._v("q45")]),e._v(" "),t("td",[e._v("q55")])]),e._v(" "),t("tr",[t("td",[e._v("2")]),e._v(" "),t("td",[e._v("q30")]),e._v(" "),t("td",[e._v("q70")])]),e._v(" "),t("tr",[t("td",[e._v("3")]),e._v(" "),t("td",[e._v("q1")]),e._v(" "),t("td",[e._v("q99")])])])]),e._v(" "),t("p",[e._v("Not yet convinced by the removal of these outliers? The "),t("a",{attrs:{href:"https://storage.googleapis.com/bitcoin_log/dataset_18.csv.gz",target:"_blank",rel:"noopener noreferrer"}},[e._v("dataset"),t("OutboundLink")],1),e._v(" contains all the observations, make your model 😃")]),e._v(" "),t("h4",{attrs:{id:"recap"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#recap"}},[e._v("#")]),e._v(" Recap")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("column")]),e._v(" "),t("th",[e._v("used in the model")]),e._v(" "),t("th",[e._v("description")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("txid")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Transaction hash, useful for debugging")])]),e._v(" "),t("tr",[t("td",[e._v("timestamp")]),e._v(" "),t("td",[e._v("converted")]),e._v(" "),t("td",[e._v("The time when the transaction has been added in the mempool, in the model is used in the form "),t("code",[e._v("day_of_week")]),e._v(" and "),t("code",[e._v("hour")])])]),e._v(" "),t("tr",[t("td",[e._v("current_height")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("The blockchain height seen by the node in this moment")])]),e._v(" "),t("tr",[t("td",[e._v("confirms_in")]),e._v(" "),t("td",[e._v("yes")]),e._v(" "),t("td",[e._v("This transaction confirmed at block height "),t("code",[e._v("current_height+confirms_in")])])]),e._v(" "),t("tr",[t("td",[e._v("fee_rate")]),e._v(" "),t("td",[e._v("target")]),e._v(" "),t("td",[e._v("This transaction fee rate measured in "),t("code",[e._v("[sat/vbytes]")])])]),e._v(" "),t("tr",[t("td",[e._v("fee_rate_bytes")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("fee rate in satoshi / bytes, used to check Bitcoin Core "),t("code",[e._v("estimatesmartfee")]),e._v(" predictions")])]),e._v(" "),t("tr",[t("td",[e._v("block_avg_fee")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("block average fee rate "),t("code",[e._v("[sat/vbytes]")]),e._v(" of block "),t("code",[e._v("current_height+confirms_in")])])]),e._v(" "),t("tr",[t("td",[e._v("core_econ")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("bitcoin "),t("code",[e._v("estimatesmartfee")]),e._v(" result for "),t("code",[e._v("confirms_in")]),e._v(" block target and in economic mode. Could be not available "),t("code",[e._v("?")]),e._v(" when a block is connected more recently than the estimation has been requested, estimation are requested every 10 secs.")])]),e._v(" "),t("tr",[t("td",[e._v("core_cons")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Same as above but with conservative mode")])]),e._v(" "),t("tr",[t("td",[e._v("mempool_len")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Sum of the mempool transactions with fee rate available (sum of every "),t("code",[e._v("a*")]),e._v(" field)")])]),e._v(" "),t("tr",[t("td",[e._v("parent_in_cpfp")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("It's 1 when the transaction has outputs that are spent in the same block in which the transaction is confirmed (they are parent in a CPFP relations).")])]),e._v(" "),t("tr",[t("td",[e._v("q1-q30-...")]),e._v(" "),t("td",[e._v("no")]),e._v(" "),t("td",[e._v("Transaction confirming fast could be outliers, usually paying a lot more than required, this percentiles are used to filter those transactions,")])]),e._v(" "),t("tr",[t("td",[e._v("a1-a2-...")]),e._v(" "),t("td",[e._v("yes")]),e._v(" "),t("td",[e._v("Contains the number of transaction in the mempool with known fee rate in the ith bucket.")])])])]),e._v(" "),t("p",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/the-good-the-bad-the-ugly.jpg",alt:"The good, the bad and the ugly"}})]),t("div",{attrs:{align:"center"}},[e._v('My biological neural network fired this, I think it\'s because a lot of chapters start with "The"')]),e._v(" "),t("br"),t("br"),t("p"),e._v(" "),t("p",[e._v("In the previous "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(" we talked about the problem.")],1),e._v(" "),t("p",[e._v("In the following "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"}},[e._v("Part 3")]),e._v(" we are going to talk about the model.")],1),e._v(" "),t("hr",{staticClass:"footnotes-sep"}),e._v(" "),t("section",{staticClass:"footnotes"},[t("ol",{staticClass:"footnotes-list"},[t("li",{staticClass:"footnote-item",attrs:{id:"fn1"}},[t("p",[e._v("In computer science temporal locality refers to the tendency to access recent data more often than older data. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/61.f6ea4853.js b/assets/js/61.588e1148.js similarity index 99% rename from assets/js/61.f6ea4853.js rename to assets/js/61.588e1148.js index 202ab5eb02..73fcf2a4d5 100644 --- a/assets/js/61.f6ea4853.js +++ b/assets/js/61.588e1148.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[61],{418:function(e,t,a){"use strict";a.r(t);var n=a(7),s=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 3 of 3 of a series. ("),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(", "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(")")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-model"}},[e._v("The model")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#splitting"}},[e._v("Splitting")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#preprocessing"}},[e._v("Preprocessing")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#build"}},[e._v("Build")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#finally--training"}},[e._v("Finally, training")])])])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-prediction-phase"}},[e._v("The prediction phase")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#conclusion-and-future-development"}},[e._v("Conclusion and future development")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#acknowledgements"}},[e._v("Acknowledgements")])])]),e._v(" "),t("h2",{attrs:{id:"the-model"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-model"}},[e._v("#")]),e._v(" The model")]),e._v(" "),t("p",[e._v("The code building and training the model with "),t("a",{attrs:{href:"https://www.tensorflow.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("tensorflow"),t("OutboundLink")],1),e._v(" is available in "),t("a",{attrs:{href:"https://colab.research.google.com/drive/1yamwh8nE4NhmGButep-pfUT-1uRKs49a?usp=sharing",target:"_blank",rel:"noopener noreferrer"}},[e._v("google colab notebook"),t("OutboundLink")],1),e._v(" (jupyter notebook); you can also download the file as plain python and run it locally. At least 1 hour is needed to train the full model, but it heavily depends on the hardware available.")]),e._v(" "),t("p",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-confirms_in-fee_rate.png",alt:"graph confirm_in blocks vs fee_rate"}})]),t("div",{attrs:{align:"center"}},[e._v("Do you want to choose the fee without a model? In the last 5 weeks a ~50 sat/vbyte transaction never took more than a day to confirm and a ~10 sat/vbyte never took more than a week")]),t("br"),t("p"),e._v(" "),t("p",[e._v("As a reference, in the code we have a calculation of the bitcoin core "),t("code",[e._v("estimatesmartfee")]),e._v(" MAE"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(" and drift"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn2",id:"fnref2"}},[e._v("[2]")])]),e._v(".\nMAE is computed as "),t("code",[e._v("avg(abs(fee_rate - core_econ))")]),e._v(" when "),t("code",[e._v("core_econ")]),e._v(" is available (about 1.2M observations, sometime the value is not available when considered too old).")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("estimatesmartfee mode")]),e._v(" "),t("th",[e._v("MAE [satoshi/vbytes]")]),e._v(" "),t("th",[e._v("drift")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("economic")]),e._v(" "),t("td",[e._v("28.77")]),e._v(" "),t("td",[e._v("20.79")])]),e._v(" "),t("tr",[t("td",[e._v("conservative")]),e._v(" "),t("td",[e._v("46.49")]),e._v(" "),t("td",[e._v("44.73")])])])]),e._v(" "),t("p",[e._v("As seen from the table, the error is quite high, but the positive drift suggests "),t("code",[e._v("estimatesmartfee")]),e._v(" prefers to overestimate to avoid transactions not confirming.")]),e._v(" "),t("p",[e._v('As we said in the introduction, network traffic is correlated with time and we have the timestamp of when the transaction has been first seen, however a ML model doesn\'t like plain numbers too much, but it behaves better with "number that repeats", like categories, so we are converting the timestamp in '),t("code",[e._v("day_of_week")]),e._v(" a number from 0 to 6, and "),t("code",[e._v("hours")]),e._v(" a number from 0 to 24.")]),e._v(" "),t("h4",{attrs:{id:"splitting"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#splitting"}},[e._v("#")]),e._v(" Splitting")]),e._v(" "),t("p",[e._v("The dataset is splitted in training and test data with a 80/20 proportion. As the name suggest the training part is used to train the model, the test is composed of other observations to test if the model is good with observations that has never seen (proving the model can generalize, not just memorizing the answer).")]),e._v(" "),t("p",[e._v("During the training the data is splitted again in 80/20 for training and validation respectively, validation is basically testing during training.")]),e._v(" "),t("p",[e._v("During splitting, the dataset is converted from a pandas data frame to tensorflow dataset, decreasing training times.")]),e._v(" "),t("h4",{attrs:{id:"preprocessing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#preprocessing"}},[e._v("#")]),e._v(" Preprocessing")]),e._v(" "),t("p",[e._v("The preprocessing phase is part of the model however it contains transformations without parameters trained by the model.\nThis transformations are useful because model trains better if data are in some format, and having this phase inside the model helps to avoid to prepare the data before feeding the model at prediction phase.")]),e._v(" "),t("p",[e._v("Our model performs 2 kind of preprocessing:")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("Normalization: model trains faster if numerical features have mean 0 and standard deviation equal to 1, so this layer is built by computing the "),t("code",[e._v("mean")]),e._v(" and "),t("code",[e._v("std")]),e._v(" from the series of a feature before training, and the model is feed with "),t("code",[e._v("(feature - mean)/std")]),e._v(". Our model normalize "),t("code",[e._v("confirms_in")]),e._v(" feature and all the buckets "),t("code",[e._v("a*")])])]),e._v(" "),t("li",[t("p",[e._v("one-hot vector: Numerical categories having a small number of different unique values like our "),t("code",[e._v("day_of_week")]),e._v(" and "),t("code",[e._v("hours")]),e._v(" could be trained better/faster by being converted in one hot vector. For example "),t("code",[e._v("day_of_week=6")]),e._v(" (Sunday) is converted in a vector "),t("code",[e._v("['0', '0', '0', '0', '0', '0', '1']")]),e._v(" while "),t("code",[e._v("day_of_week=5")]),e._v(" (Saturday) is converted in the vector "),t("code",[e._v("['0', '0', '0', '0', '0', '1', '0']")])])])]),e._v(" "),t("h4",{attrs:{id:"build"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#build"}},[e._v("#")]),e._v(" Build")]),e._v(" "),t("div",{staticClass:"language-python extra-class"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[e._v("all_features "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("concatenate"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("encoded_features"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nx "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"relu"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("all_features"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nx "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"relu"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\noutput "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("clip"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nmodel "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Model"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("all_inputs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" output"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\noptimizer "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("optimizers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Adam"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("learning_rate"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("0.01")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nmodel"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token builtin"}},[e._v("compile")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("loss"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mse'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n optimizer"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("optimizer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n metrics"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mae'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mse'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-model.png",alt:"model graph"}})]),e._v(" "),t("p",[e._v("The model is fed with the "),t("code",[e._v("encoded_features")]),e._v(" coming from the processing phase, then there are 2 layers with 64 neurons each followed by one neuron giving the "),t("code",[e._v("fee_rate")]),e._v(" as output.")]),e._v(" "),t("p",[e._v("With this configurations the model has:")]),e._v(" "),t("ul",[t("li",[e._v("Total params: "),t("code",[e._v("7,412")])]),e._v(" "),t("li",[e._v("Trainable params: "),t("code",[e._v("7,361")])]),e._v(" "),t("li",[e._v("Non-trainable params: "),t("code",[e._v("51")])])]),e._v(" "),t("p",[e._v("Non-trainable params comes from the normalization layer and are computed in the pre-processing phase (it contains, for example, the mean of a series). Trainable parameters are values initialized randomly and changed during the training phase. The trainable parameters are "),t("code",[e._v("7,361")]),e._v(", this number comes from the following, every neuron has an associated bias and a weight for every element in the inputs, thus:")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("48")]),e._v(" input_values_weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" * "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" first_layer_neurons"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n+ "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" input_values_weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" * "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" second layer neurons"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n+ "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" input values weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("49")]),e._v("*64+65*64+65 "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("7361")]),e._v("\n")])])]),t("p",[e._v("Honestly, neural network parameters are mostly the one taken from this tensorflow "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/regression",target:"_blank",rel:"noopener noreferrer"}},[e._v("example"),t("OutboundLink")],1),e._v(", we even tried to "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/keras_tuner",target:"_blank",rel:"noopener noreferrer"}},[e._v("tune hyperparameters"),t("OutboundLink")],1),e._v(", however, we decided to follow this "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/overfit_and_underfit#demonstrate_overfitting",target:"_blank",rel:"noopener noreferrer"}},[e._v("advice"),t("OutboundLink")],1),e._v(": "),t("em",[e._v('"The simplest way to prevent overfitting is to start with a small model:"')]),e._v(". We hope this work will attract other data scientists to this bitcoin problem, improving the model. We also think that a longer time for the data collection is needed to capture various situations.")]),e._v(" "),t("p",[e._v("A significant part of a ML model are the activation functions, "),t("code",[e._v("relu")]),e._v(" (Rectified Linear Unit) is one of the most used lately, because it's simple and works well as we learned in this "),t("a",{attrs:{href:"https://youtu.be/aircAruvnKk?t=1035",target:"_blank",rel:"noopener noreferrer"}},[e._v("introducing neural network video"),t("OutboundLink")],1),e._v(". "),t("code",[e._v("relu")]),e._v(" it's equal to zero for negative values and equal to the input for positive values. Being non-linear allows the whole model to be non-linear.")]),e._v(" "),t("p",[e._v("For the last layer it is different: we want to enforce a minimum for the output, which is the minimum relay fee "),t("code",[e._v("1.0")]),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn3",id:"fnref3"}},[e._v("[3]")])]),e._v(". One could not simply cut the output of the model after prediction because all the training would not consider this constraint. So we need to build a custom activation function that the model training will be able to use for the "),t("a",{attrs:{href:"https://en.wikipedia.org/wiki/Gradient_descent#:~:text=Gradient%20descent%20is%20a%20first,the%20direction%20of%20steepest%20descent.",target:"_blank",rel:"noopener noreferrer"}},[e._v("gradient descent"),t("OutboundLink")],1),e._v(" optimization step. Luckily this is very simple using tensorflow primitives:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("def clip(x):\n min = tf.constant(1.0)\n return tf.where(tf.less(x, min), min, x)\n")])])]),t("p",[e._v("Another important part is the optimizer, when we first read the aforementioned "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/regression",target:"_blank",rel:"noopener noreferrer"}},[e._v("example"),t("OutboundLink")],1),e._v(" the optimizer used was "),t("code",[e._v("RMSProp")]),e._v(" however the example updated lately and we noticed the optimizer changed in favor of "),t("code",[e._v("Adam")]),e._v(" which we read is the "),t("a",{attrs:{href:"https://towardsdatascience.com/adam-latest-trends-in-deep-learning-optimization-6be9a291375c",target:"_blank",rel:"noopener noreferrer"}},[e._v("latest trend"),t("OutboundLink")],1),e._v(" in data science. We changed the model to use "),t("code",[e._v("Adam")]),e._v(" and effectively the training is faster with "),t("code",[e._v("Adam")]),e._v(" and even slightly lower error is achieved.\nAnother important parameter is the learning rate, which we set to "),t("code",[e._v("0.01")]),e._v(" after manual trials; however there might be space for improvements such as using "),t("a",{attrs:{href:"https://www.tensorflow.org/api_docs/python/tf/compat/v1/train/exponential_decay",target:"_blank",rel:"noopener noreferrer"}},[e._v("exponential decay"),t("OutboundLink")],1),e._v(", starting with an high learning rate and decreasing it through training epochs.")]),e._v(" "),t("p",[e._v('The last part of the model configuration is the loss function: the objective of the training is to find the minimum of this function. Usually for regression problem (the ones having a number as output, not a category) the most used is the Mean squared error (MSE). MSE is measured as the average of squared difference between predictions and actual observations, giving larger penalties to large difference because of the square. An interesting property is that the bigger the error the faster the changes is good at the beginning of the training, while slowing down when the model predicts better is desirable to avoid "jumping out" the local minimum.')]),e._v(" "),t("h4",{attrs:{id:"finally-the-model-training"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#finally-the-model-training"}},[e._v("#")]),e._v(" Finally, the model training")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("PATIENCE = 20\nMAX_EPOCHS = 200\n\ndef train():\n early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=PATIENCE)\n history = model.fit(train_ds, epochs=MAX_EPOCHS, validation_data=val_ds, verbose=1, callbacks=[early_stop])\n return history\n\nhistory = train()\n")])])]),t("p",[e._v("This steps is the core of the neural network, it takes a while, let's analyze the output:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("Epoch 1/200\n7559/7559 [==============================] - 34s 3ms/step - loss: 547.8023 - mae: 16.9547 - mse: 547.8023 - val_loss: 300.5965 - val_ma\ne: 11.9202 - val_mse: 300.5965\n...\nEpoch 158/200\n7559/7559 [==============================] - 31s 3ms/step - loss: 163.2548 - mae: 8.3126 - mse: 163.2548 - val_loss: 164.8296 - val_mae: 8.3402 - val_mse: 164.8296\n")])])]),t("p",[e._v("Training is done in epochs, under every epoch all the training data is iterated and model parameters updated to minimize the loss function.")]),e._v(" "),t("p",[e._v("The number "),t("code",[e._v("7559")]),e._v(" represent the number of steps. Theoretically the whole training data should be processed at once and parameters updated accordingly, however in practice this is infeasible for example for memory resource, thus the training happens in batch. In our case we have "),t("code",[e._v("1,934,999")]),e._v(" observations in the training set and our batch size is "),t("code",[e._v("256")]),e._v(", thus we have "),t("code",[e._v("1,437,841/256=7,558.58")]),e._v(" which by excess result in "),t("code",[e._v("7559")]),e._v(" steps.")]),e._v(" "),t("p",[e._v("The "),t("code",[e._v("~31s")]),e._v(" is the time it takes to process the epoch on a threadripper CPU but GPU or TPU could do better.")]),e._v(" "),t("p",[e._v("The value "),t("code",[e._v("loss")]),e._v(" is the MSE on the training data while "),t("code",[e._v("val_loss")]),e._v(" is the MSE value on the validation data. As far as we understand the separated validation data helps to detect the machine learning enemy, overfitting. Because in case of overfitting the value "),t("code",[e._v("loss")]),e._v(" continue to improve (almost indefinitely) while "),t("code",[e._v("val_loss")]),e._v(" start improving with the loss but a certain point diverge, indicating the network is memorizing the training data to improve "),t("code",[e._v("loss")]),e._v(" but in doing so losing generalizing capabilities.")]),e._v(" "),t("p",[e._v("Our model doesn't look to suffer overfitting cause "),t("code",[e._v("loss")]),e._v(" and "),t("code",[e._v("val_loss")]),e._v(" doesn't diverge during training")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-train-history.png",alt:"train history"}})]),e._v(" "),t("p",[e._v("While we told the training to do 200 epochs, the training stopped at 158 because we added an "),t("code",[e._v("early_stop")]),e._v(" call back with "),t("code",[e._v("20")]),e._v(" as "),t("code",[e._v("PATIENCE")]),e._v(", meaning that after 20 epoch and no improvement in "),t("code",[e._v("val_loss")]),e._v(" the training is halted, saving time and potentially avoiding overfitting.")]),e._v(" "),t("h2",{attrs:{id:"the-prediction-phase"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-prediction-phase"}},[e._v("#")]),e._v(" The prediction phase")]),e._v(" "),t("p",[e._v("A "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" is available on github. At the moment it uses a bitcoin core node to provide network data for simplicity, but it queries it only for the mempool and the last 6 blocks, so it's something that also a light-client could do"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn4",id:"fnref4"}},[e._v("[4]")])]),e._v(".")]),e._v(" "),t("p",[e._v("The following chart is probably the best visualization to evaluate the model, on the x axis there is the real fee rate while on the y axis there is the prediction, the more the points are centered on the bisection, the more the model is good.\nWe can see the model is doing quite well, the MAE is 8 which is way lower than "),t("code",[e._v("estimatesmartfee")]),e._v(". However, there are big errors some times, in particular for prediction for fast confirmation ("),t("code",[e._v("confirms_in=1 or confirms_in=2")]),e._v(") as shown by the orange points. Creating a model only for blocks target greater than 2 instead of simply remove some observations may be an option.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-true-and-predictions.png",alt:"prediction results"}})]),e._v(" "),t("p",[e._v("The following chart is instead a distribution of the errors, which for good model should resemble the normal distribution centered in 0, and it loooks like the model is respecting that.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-error-distribution.png",alt:"error distribution"}})]),e._v(" "),t("h2",{attrs:{id:"conclusion-and-future-development"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion-and-future-development"}},[e._v("#")]),e._v(" Conclusion and future development")]),e._v(" "),t("p",[e._v("The results have shown deep neural network are a tool capable of good bitcoin transaction fee estimations; this suggests that further ML research in this area might be promising.")]),e._v(" "),t("p",[e._v("This is just a starting point, there are many future improvements such as:")]),e._v(" "),t("ul",[t("li",[e._v("Build a separate model with full knowledge, thus for full, always-connected nodes could be interesting and improve network resource allocation with respect to current estimators.")]),e._v(" "),t("li",[e._v("Tensorflow is a huge dependency, and since it contains all the feature to build and train a model, most of the feature are not needed in the prediction phase. In fact tensorflow lite exists which is specifically created for embedded and mobile devices; the "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" and the final integration in "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" should use it.")]),e._v(" "),t("li",[e._v("Explore other fields to improve model predictions such as:\n"),t("ul",[t("li",[e._v("A bucket array of the transactions in the last 6 blocks with known fee rates. This should in particular help estimations with almost empty mempool.")]),e._v(" "),t("li",[e._v("Transaction weight")]),e._v(" "),t("li",[e._v("Time from last block")])])]),e._v(" "),t("li",[e._v("Some fields are very important and could benefit from pre-processing expansion, for instance applying "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/structured_data/feature_columns#hashed_feature_columns",target:"_blank",rel:"noopener noreferrer"}},[e._v("hashed feature columns"),t("OutboundLink")],1),e._v(" to "),t("code",[e._v("confirms_in")]),e._v(".")]),e._v(" "),t("li",[e._v("Bitcoin logger could be improved by a merge command to unify raw logs files, reducing redundancy and consequently disk occupation.")]),e._v(" "),t("li",[e._v("The dataset could be created in multiple files to allow more parallelism and use less memory during training.")]),e._v(" "),t("li",[e._v("Saving the dataset in "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/load_data/tfrecord",target:"_blank",rel:"noopener noreferrer"}},[e._v("TFRecord format"),t("OutboundLink")],1),e._v(" instead of CSV")]),e._v(" "),t("li",[e._v("At the moment we are training the model on a threadripper CPU, training the code on GPU or even TPU will be needed to decrease training time, especially because input data will grow.")]),e._v(" "),t("li",[e._v("The "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" should estimate only using the p2p bitcoin network, without requiring a node. This work would be propedeutic for "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" integration")]),e._v(" "),t("li",[e._v("At the moment mempool buckets are multiple inputs "),t("code",[e._v("a*")]),e._v(" as show in the model graph; since they are related, is it possible to merge them in one TensorArray?")]),e._v(" "),t("li",[e._v("Sometimes the model does not learn and "),t("a",{attrs:{href:"https://github.com/RCasatta/bitcoin_logger/blob/master/notes.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("gets stuck"),t("OutboundLink")],1),e._v(". The reason is the "),t("code",[e._v("clip")]),e._v(" function applied in the last layer is constant for a value lower than 1. In this case, the derivative is 0 and the gradient descent doesn't know where to go. Instead of using the "),t("code",[e._v("clip")]),e._v(" function apply penalties to the loss function for values lower than 1.")]),e._v(" "),t("li",[e._v("There are issues regarding dead neurons (going to 0) or neurons with big weight, weight results should be monitored for this events, and also weight decay and L2 regularization should be explored.")]),e._v(" "),t("li",[e._v("Tune hyper-parameters technique should be re-tested.")]),e._v(" "),t("li",[e._v("Predictions should be monotonic decreasing for growing "),t("code",[e._v("confirms_in")]),e._v(" parameter; for obvious reason it doesn't make sense that an higher fee rate will result in a higher confirmation time. But since this is not enforced anywhere in the model, at the moment this could happen.")]),e._v(" "),t("li",[e._v("Since nodes with bloom filter disabled doesn't serve the mempool anymore, a model based only on last blocks should be evaluated.")])]),e._v(" "),t("h2",{attrs:{id:"acknowledgements"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#acknowledgements"}},[e._v("#")]),e._v(" Acknowledgements")]),e._v(" "),t("p",[e._v("Thanks to "),t("a",{attrs:{href:"https://squarecrypto.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Square crypto"),t("OutboundLink")],1),e._v(" for sponsoring this work and thanks to the reviewers: "),t("a",{attrs:{href:"https://twitter.com/LeoComandini",target:"_blank",rel:"noopener noreferrer"}},[e._v("Leonardo Comandini"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/domegabri",target:"_blank",rel:"noopener noreferrer"}},[e._v("Domenico Gabriele"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/afilini",target:"_blank",rel:"noopener noreferrer"}},[e._v("Alekos Filini"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/Ferdinando1970",target:"_blank",rel:"noopener noreferrer"}},[e._v("Ferdinando Ametrano"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("And also this tweet that remembered me "),t("a",{attrs:{href:"https://twitter.com/RCasatta",target:"_blank",rel:"noopener noreferrer"}},[e._v("I"),t("OutboundLink")],1),e._v(" had this work in my TODO list")]),e._v(" "),t("blockquote",{staticClass:"twitter-tweet"},[t("p",{attrs:{lang:"en",dir:"ltr"}},[e._v("I don't understand Machine Learning(ML), but is it horrible to use ML to predict bitcoin fees? "),t("br"),t("br"),e._v('I have heard tales of this "Deep Learning" thing where you throw a bunch of data at it and it gives you good results with high accuracy.')]),e._v("— sanket1729 (@sanket1729) "),t("a",{attrs:{href:"https://twitter.com/sanket1729/status/1336624662365822977?ref_src=twsrc%5Etfw"}},[e._v("December 9, 2020")])]),e._v(" "),t("script",{attrs:{async:"",src:"https://platform.twitter.com/widgets.js",charset:"utf-8"}}),e._v(" "),t("p",[e._v("This is the final part of the series. In the previous "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(" we talked about the problem and in "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(" we talked about the dataset.")],1),e._v(" "),t("hr",{staticClass:"footnotes-sep"}),e._v(" "),t("section",{staticClass:"footnotes"},[t("ol",{staticClass:"footnotes-list"},[t("li",{staticClass:"footnote-item",attrs:{id:"fn1"}},[t("p",[e._v("MAE is Mean Absolute Error, which is the average of the series built by the absolute difference between the real value and the estimation. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn2"}},[t("p",[e._v("drift like MAE, but without the absolute value "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref2"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn3"}},[t("p",[e._v("Most node won't relay transactions with fee lower than the min relay fee, which has a default of "),t("code",[e._v("1.0")]),e._v(" "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref3"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn4"}},[t("p",[e._v("An important issue emerged after the article came out, a bitcoin core client with bloom filter disabled (default as of 0.21) doesn't serve the mempool via p2p. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref4"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[61],{417:function(e,t,a){"use strict";a.r(t);var n=a(7),s=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 3 of 3 of a series. ("),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(", "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(")")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-model"}},[e._v("The model")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#splitting"}},[e._v("Splitting")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#preprocessing"}},[e._v("Preprocessing")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#build"}},[e._v("Build")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#finally--training"}},[e._v("Finally, training")])])])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-prediction-phase"}},[e._v("The prediction phase")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#conclusion-and-future-development"}},[e._v("Conclusion and future development")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#acknowledgements"}},[e._v("Acknowledgements")])])]),e._v(" "),t("h2",{attrs:{id:"the-model"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-model"}},[e._v("#")]),e._v(" The model")]),e._v(" "),t("p",[e._v("The code building and training the model with "),t("a",{attrs:{href:"https://www.tensorflow.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("tensorflow"),t("OutboundLink")],1),e._v(" is available in "),t("a",{attrs:{href:"https://colab.research.google.com/drive/1yamwh8nE4NhmGButep-pfUT-1uRKs49a?usp=sharing",target:"_blank",rel:"noopener noreferrer"}},[e._v("google colab notebook"),t("OutboundLink")],1),e._v(" (jupyter notebook); you can also download the file as plain python and run it locally. At least 1 hour is needed to train the full model, but it heavily depends on the hardware available.")]),e._v(" "),t("p",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-confirms_in-fee_rate.png",alt:"graph confirm_in blocks vs fee_rate"}})]),t("div",{attrs:{align:"center"}},[e._v("Do you want to choose the fee without a model? In the last 5 weeks a ~50 sat/vbyte transaction never took more than a day to confirm and a ~10 sat/vbyte never took more than a week")]),t("br"),t("p"),e._v(" "),t("p",[e._v("As a reference, in the code we have a calculation of the bitcoin core "),t("code",[e._v("estimatesmartfee")]),e._v(" MAE"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(" and drift"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn2",id:"fnref2"}},[e._v("[2]")])]),e._v(".\nMAE is computed as "),t("code",[e._v("avg(abs(fee_rate - core_econ))")]),e._v(" when "),t("code",[e._v("core_econ")]),e._v(" is available (about 1.2M observations, sometime the value is not available when considered too old).")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("estimatesmartfee mode")]),e._v(" "),t("th",[e._v("MAE [satoshi/vbytes]")]),e._v(" "),t("th",[e._v("drift")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("economic")]),e._v(" "),t("td",[e._v("28.77")]),e._v(" "),t("td",[e._v("20.79")])]),e._v(" "),t("tr",[t("td",[e._v("conservative")]),e._v(" "),t("td",[e._v("46.49")]),e._v(" "),t("td",[e._v("44.73")])])])]),e._v(" "),t("p",[e._v("As seen from the table, the error is quite high, but the positive drift suggests "),t("code",[e._v("estimatesmartfee")]),e._v(" prefers to overestimate to avoid transactions not confirming.")]),e._v(" "),t("p",[e._v('As we said in the introduction, network traffic is correlated with time and we have the timestamp of when the transaction has been first seen, however a ML model doesn\'t like plain numbers too much, but it behaves better with "number that repeats", like categories, so we are converting the timestamp in '),t("code",[e._v("day_of_week")]),e._v(" a number from 0 to 6, and "),t("code",[e._v("hours")]),e._v(" a number from 0 to 24.")]),e._v(" "),t("h4",{attrs:{id:"splitting"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#splitting"}},[e._v("#")]),e._v(" Splitting")]),e._v(" "),t("p",[e._v("The dataset is splitted in training and test data with a 80/20 proportion. As the name suggest the training part is used to train the model, the test is composed of other observations to test if the model is good with observations that has never seen (proving the model can generalize, not just memorizing the answer).")]),e._v(" "),t("p",[e._v("During the training the data is splitted again in 80/20 for training and validation respectively, validation is basically testing during training.")]),e._v(" "),t("p",[e._v("During splitting, the dataset is converted from a pandas data frame to tensorflow dataset, decreasing training times.")]),e._v(" "),t("h4",{attrs:{id:"preprocessing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#preprocessing"}},[e._v("#")]),e._v(" Preprocessing")]),e._v(" "),t("p",[e._v("The preprocessing phase is part of the model however it contains transformations without parameters trained by the model.\nThis transformations are useful because model trains better if data are in some format, and having this phase inside the model helps to avoid to prepare the data before feeding the model at prediction phase.")]),e._v(" "),t("p",[e._v("Our model performs 2 kind of preprocessing:")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("Normalization: model trains faster if numerical features have mean 0 and standard deviation equal to 1, so this layer is built by computing the "),t("code",[e._v("mean")]),e._v(" and "),t("code",[e._v("std")]),e._v(" from the series of a feature before training, and the model is feed with "),t("code",[e._v("(feature - mean)/std")]),e._v(". Our model normalize "),t("code",[e._v("confirms_in")]),e._v(" feature and all the buckets "),t("code",[e._v("a*")])])]),e._v(" "),t("li",[t("p",[e._v("one-hot vector: Numerical categories having a small number of different unique values like our "),t("code",[e._v("day_of_week")]),e._v(" and "),t("code",[e._v("hours")]),e._v(" could be trained better/faster by being converted in one hot vector. For example "),t("code",[e._v("day_of_week=6")]),e._v(" (Sunday) is converted in a vector "),t("code",[e._v("['0', '0', '0', '0', '0', '0', '1']")]),e._v(" while "),t("code",[e._v("day_of_week=5")]),e._v(" (Saturday) is converted in the vector "),t("code",[e._v("['0', '0', '0', '0', '0', '1', '0']")])])])]),e._v(" "),t("h4",{attrs:{id:"build"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#build"}},[e._v("#")]),e._v(" Build")]),e._v(" "),t("div",{staticClass:"language-python extra-class"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[e._v("all_features "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("concatenate"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("encoded_features"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nx "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"relu"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("all_features"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nx "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"relu"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\noutput "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("clip"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nmodel "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Model"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("all_inputs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" output"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\noptimizer "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("optimizers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Adam"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("learning_rate"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("0.01")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nmodel"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token builtin"}},[e._v("compile")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("loss"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mse'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n optimizer"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("optimizer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n metrics"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mae'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mse'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-model.png",alt:"model graph"}})]),e._v(" "),t("p",[e._v("The model is fed with the "),t("code",[e._v("encoded_features")]),e._v(" coming from the processing phase, then there are 2 layers with 64 neurons each followed by one neuron giving the "),t("code",[e._v("fee_rate")]),e._v(" as output.")]),e._v(" "),t("p",[e._v("With this configurations the model has:")]),e._v(" "),t("ul",[t("li",[e._v("Total params: "),t("code",[e._v("7,412")])]),e._v(" "),t("li",[e._v("Trainable params: "),t("code",[e._v("7,361")])]),e._v(" "),t("li",[e._v("Non-trainable params: "),t("code",[e._v("51")])])]),e._v(" "),t("p",[e._v("Non-trainable params comes from the normalization layer and are computed in the pre-processing phase (it contains, for example, the mean of a series). Trainable parameters are values initialized randomly and changed during the training phase. The trainable parameters are "),t("code",[e._v("7,361")]),e._v(", this number comes from the following, every neuron has an associated bias and a weight for every element in the inputs, thus:")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("48")]),e._v(" input_values_weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" * "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" first_layer_neurons"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n+ "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" input_values_weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" * "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" second layer neurons"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n+ "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" input values weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("49")]),e._v("*64+65*64+65 "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("7361")]),e._v("\n")])])]),t("p",[e._v("Honestly, neural network parameters are mostly the one taken from this tensorflow "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/regression",target:"_blank",rel:"noopener noreferrer"}},[e._v("example"),t("OutboundLink")],1),e._v(", we even tried to "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/keras_tuner",target:"_blank",rel:"noopener noreferrer"}},[e._v("tune hyperparameters"),t("OutboundLink")],1),e._v(", however, we decided to follow this "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/overfit_and_underfit#demonstrate_overfitting",target:"_blank",rel:"noopener noreferrer"}},[e._v("advice"),t("OutboundLink")],1),e._v(": "),t("em",[e._v('"The simplest way to prevent overfitting is to start with a small model:"')]),e._v(". We hope this work will attract other data scientists to this bitcoin problem, improving the model. We also think that a longer time for the data collection is needed to capture various situations.")]),e._v(" "),t("p",[e._v("A significant part of a ML model are the activation functions, "),t("code",[e._v("relu")]),e._v(" (Rectified Linear Unit) is one of the most used lately, because it's simple and works well as we learned in this "),t("a",{attrs:{href:"https://youtu.be/aircAruvnKk?t=1035",target:"_blank",rel:"noopener noreferrer"}},[e._v("introducing neural network video"),t("OutboundLink")],1),e._v(". "),t("code",[e._v("relu")]),e._v(" it's equal to zero for negative values and equal to the input for positive values. Being non-linear allows the whole model to be non-linear.")]),e._v(" "),t("p",[e._v("For the last layer it is different: we want to enforce a minimum for the output, which is the minimum relay fee "),t("code",[e._v("1.0")]),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn3",id:"fnref3"}},[e._v("[3]")])]),e._v(". One could not simply cut the output of the model after prediction because all the training would not consider this constraint. So we need to build a custom activation function that the model training will be able to use for the "),t("a",{attrs:{href:"https://en.wikipedia.org/wiki/Gradient_descent#:~:text=Gradient%20descent%20is%20a%20first,the%20direction%20of%20steepest%20descent.",target:"_blank",rel:"noopener noreferrer"}},[e._v("gradient descent"),t("OutboundLink")],1),e._v(" optimization step. Luckily this is very simple using tensorflow primitives:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("def clip(x):\n min = tf.constant(1.0)\n return tf.where(tf.less(x, min), min, x)\n")])])]),t("p",[e._v("Another important part is the optimizer, when we first read the aforementioned "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/regression",target:"_blank",rel:"noopener noreferrer"}},[e._v("example"),t("OutboundLink")],1),e._v(" the optimizer used was "),t("code",[e._v("RMSProp")]),e._v(" however the example updated lately and we noticed the optimizer changed in favor of "),t("code",[e._v("Adam")]),e._v(" which we read is the "),t("a",{attrs:{href:"https://towardsdatascience.com/adam-latest-trends-in-deep-learning-optimization-6be9a291375c",target:"_blank",rel:"noopener noreferrer"}},[e._v("latest trend"),t("OutboundLink")],1),e._v(" in data science. We changed the model to use "),t("code",[e._v("Adam")]),e._v(" and effectively the training is faster with "),t("code",[e._v("Adam")]),e._v(" and even slightly lower error is achieved.\nAnother important parameter is the learning rate, which we set to "),t("code",[e._v("0.01")]),e._v(" after manual trials; however there might be space for improvements such as using "),t("a",{attrs:{href:"https://www.tensorflow.org/api_docs/python/tf/compat/v1/train/exponential_decay",target:"_blank",rel:"noopener noreferrer"}},[e._v("exponential decay"),t("OutboundLink")],1),e._v(", starting with an high learning rate and decreasing it through training epochs.")]),e._v(" "),t("p",[e._v('The last part of the model configuration is the loss function: the objective of the training is to find the minimum of this function. Usually for regression problem (the ones having a number as output, not a category) the most used is the Mean squared error (MSE). MSE is measured as the average of squared difference between predictions and actual observations, giving larger penalties to large difference because of the square. An interesting property is that the bigger the error the faster the changes is good at the beginning of the training, while slowing down when the model predicts better is desirable to avoid "jumping out" the local minimum.')]),e._v(" "),t("h4",{attrs:{id:"finally-the-model-training"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#finally-the-model-training"}},[e._v("#")]),e._v(" Finally, the model training")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("PATIENCE = 20\nMAX_EPOCHS = 200\n\ndef train():\n early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=PATIENCE)\n history = model.fit(train_ds, epochs=MAX_EPOCHS, validation_data=val_ds, verbose=1, callbacks=[early_stop])\n return history\n\nhistory = train()\n")])])]),t("p",[e._v("This steps is the core of the neural network, it takes a while, let's analyze the output:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("Epoch 1/200\n7559/7559 [==============================] - 34s 3ms/step - loss: 547.8023 - mae: 16.9547 - mse: 547.8023 - val_loss: 300.5965 - val_ma\ne: 11.9202 - val_mse: 300.5965\n...\nEpoch 158/200\n7559/7559 [==============================] - 31s 3ms/step - loss: 163.2548 - mae: 8.3126 - mse: 163.2548 - val_loss: 164.8296 - val_mae: 8.3402 - val_mse: 164.8296\n")])])]),t("p",[e._v("Training is done in epochs, under every epoch all the training data is iterated and model parameters updated to minimize the loss function.")]),e._v(" "),t("p",[e._v("The number "),t("code",[e._v("7559")]),e._v(" represent the number of steps. Theoretically the whole training data should be processed at once and parameters updated accordingly, however in practice this is infeasible for example for memory resource, thus the training happens in batch. In our case we have "),t("code",[e._v("1,934,999")]),e._v(" observations in the training set and our batch size is "),t("code",[e._v("256")]),e._v(", thus we have "),t("code",[e._v("1,437,841/256=7,558.58")]),e._v(" which by excess result in "),t("code",[e._v("7559")]),e._v(" steps.")]),e._v(" "),t("p",[e._v("The "),t("code",[e._v("~31s")]),e._v(" is the time it takes to process the epoch on a threadripper CPU but GPU or TPU could do better.")]),e._v(" "),t("p",[e._v("The value "),t("code",[e._v("loss")]),e._v(" is the MSE on the training data while "),t("code",[e._v("val_loss")]),e._v(" is the MSE value on the validation data. As far as we understand the separated validation data helps to detect the machine learning enemy, overfitting. Because in case of overfitting the value "),t("code",[e._v("loss")]),e._v(" continue to improve (almost indefinitely) while "),t("code",[e._v("val_loss")]),e._v(" start improving with the loss but a certain point diverge, indicating the network is memorizing the training data to improve "),t("code",[e._v("loss")]),e._v(" but in doing so losing generalizing capabilities.")]),e._v(" "),t("p",[e._v("Our model doesn't look to suffer overfitting cause "),t("code",[e._v("loss")]),e._v(" and "),t("code",[e._v("val_loss")]),e._v(" doesn't diverge during training")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-train-history.png",alt:"train history"}})]),e._v(" "),t("p",[e._v("While we told the training to do 200 epochs, the training stopped at 158 because we added an "),t("code",[e._v("early_stop")]),e._v(" call back with "),t("code",[e._v("20")]),e._v(" as "),t("code",[e._v("PATIENCE")]),e._v(", meaning that after 20 epoch and no improvement in "),t("code",[e._v("val_loss")]),e._v(" the training is halted, saving time and potentially avoiding overfitting.")]),e._v(" "),t("h2",{attrs:{id:"the-prediction-phase"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-prediction-phase"}},[e._v("#")]),e._v(" The prediction phase")]),e._v(" "),t("p",[e._v("A "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" is available on github. At the moment it uses a bitcoin core node to provide network data for simplicity, but it queries it only for the mempool and the last 6 blocks, so it's something that also a light-client could do"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn4",id:"fnref4"}},[e._v("[4]")])]),e._v(".")]),e._v(" "),t("p",[e._v("The following chart is probably the best visualization to evaluate the model, on the x axis there is the real fee rate while on the y axis there is the prediction, the more the points are centered on the bisection, the more the model is good.\nWe can see the model is doing quite well, the MAE is 8 which is way lower than "),t("code",[e._v("estimatesmartfee")]),e._v(". However, there are big errors some times, in particular for prediction for fast confirmation ("),t("code",[e._v("confirms_in=1 or confirms_in=2")]),e._v(") as shown by the orange points. Creating a model only for blocks target greater than 2 instead of simply remove some observations may be an option.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-true-and-predictions.png",alt:"prediction results"}})]),e._v(" "),t("p",[e._v("The following chart is instead a distribution of the errors, which for good model should resemble the normal distribution centered in 0, and it loooks like the model is respecting that.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-error-distribution.png",alt:"error distribution"}})]),e._v(" "),t("h2",{attrs:{id:"conclusion-and-future-development"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion-and-future-development"}},[e._v("#")]),e._v(" Conclusion and future development")]),e._v(" "),t("p",[e._v("The results have shown deep neural network are a tool capable of good bitcoin transaction fee estimations; this suggests that further ML research in this area might be promising.")]),e._v(" "),t("p",[e._v("This is just a starting point, there are many future improvements such as:")]),e._v(" "),t("ul",[t("li",[e._v("Build a separate model with full knowledge, thus for full, always-connected nodes could be interesting and improve network resource allocation with respect to current estimators.")]),e._v(" "),t("li",[e._v("Tensorflow is a huge dependency, and since it contains all the feature to build and train a model, most of the feature are not needed in the prediction phase. In fact tensorflow lite exists which is specifically created for embedded and mobile devices; the "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" and the final integration in "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" should use it.")]),e._v(" "),t("li",[e._v("Explore other fields to improve model predictions such as:\n"),t("ul",[t("li",[e._v("A bucket array of the transactions in the last 6 blocks with known fee rates. This should in particular help estimations with almost empty mempool.")]),e._v(" "),t("li",[e._v("Transaction weight")]),e._v(" "),t("li",[e._v("Time from last block")])])]),e._v(" "),t("li",[e._v("Some fields are very important and could benefit from pre-processing expansion, for instance applying "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/structured_data/feature_columns#hashed_feature_columns",target:"_blank",rel:"noopener noreferrer"}},[e._v("hashed feature columns"),t("OutboundLink")],1),e._v(" to "),t("code",[e._v("confirms_in")]),e._v(".")]),e._v(" "),t("li",[e._v("Bitcoin logger could be improved by a merge command to unify raw logs files, reducing redundancy and consequently disk occupation.")]),e._v(" "),t("li",[e._v("The dataset could be created in multiple files to allow more parallelism and use less memory during training.")]),e._v(" "),t("li",[e._v("Saving the dataset in "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/load_data/tfrecord",target:"_blank",rel:"noopener noreferrer"}},[e._v("TFRecord format"),t("OutboundLink")],1),e._v(" instead of CSV")]),e._v(" "),t("li",[e._v("At the moment we are training the model on a threadripper CPU, training the code on GPU or even TPU will be needed to decrease training time, especially because input data will grow.")]),e._v(" "),t("li",[e._v("The "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" should estimate only using the p2p bitcoin network, without requiring a node. This work would be propedeutic for "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" integration")]),e._v(" "),t("li",[e._v("At the moment mempool buckets are multiple inputs "),t("code",[e._v("a*")]),e._v(" as show in the model graph; since they are related, is it possible to merge them in one TensorArray?")]),e._v(" "),t("li",[e._v("Sometimes the model does not learn and "),t("a",{attrs:{href:"https://github.com/RCasatta/bitcoin_logger/blob/master/notes.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("gets stuck"),t("OutboundLink")],1),e._v(". The reason is the "),t("code",[e._v("clip")]),e._v(" function applied in the last layer is constant for a value lower than 1. In this case, the derivative is 0 and the gradient descent doesn't know where to go. Instead of using the "),t("code",[e._v("clip")]),e._v(" function apply penalties to the loss function for values lower than 1.")]),e._v(" "),t("li",[e._v("There are issues regarding dead neurons (going to 0) or neurons with big weight, weight results should be monitored for this events, and also weight decay and L2 regularization should be explored.")]),e._v(" "),t("li",[e._v("Tune hyper-parameters technique should be re-tested.")]),e._v(" "),t("li",[e._v("Predictions should be monotonic decreasing for growing "),t("code",[e._v("confirms_in")]),e._v(" parameter; for obvious reason it doesn't make sense that an higher fee rate will result in a higher confirmation time. But since this is not enforced anywhere in the model, at the moment this could happen.")]),e._v(" "),t("li",[e._v("Since nodes with bloom filter disabled doesn't serve the mempool anymore, a model based only on last blocks should be evaluated.")])]),e._v(" "),t("h2",{attrs:{id:"acknowledgements"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#acknowledgements"}},[e._v("#")]),e._v(" Acknowledgements")]),e._v(" "),t("p",[e._v("Thanks to "),t("a",{attrs:{href:"https://squarecrypto.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Square crypto"),t("OutboundLink")],1),e._v(" for sponsoring this work and thanks to the reviewers: "),t("a",{attrs:{href:"https://twitter.com/LeoComandini",target:"_blank",rel:"noopener noreferrer"}},[e._v("Leonardo Comandini"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/domegabri",target:"_blank",rel:"noopener noreferrer"}},[e._v("Domenico Gabriele"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/afilini",target:"_blank",rel:"noopener noreferrer"}},[e._v("Alekos Filini"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/Ferdinando1970",target:"_blank",rel:"noopener noreferrer"}},[e._v("Ferdinando Ametrano"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("And also this tweet that remembered me "),t("a",{attrs:{href:"https://twitter.com/RCasatta",target:"_blank",rel:"noopener noreferrer"}},[e._v("I"),t("OutboundLink")],1),e._v(" had this work in my TODO list")]),e._v(" "),t("blockquote",{staticClass:"twitter-tweet"},[t("p",{attrs:{lang:"en",dir:"ltr"}},[e._v("I don't understand Machine Learning(ML), but is it horrible to use ML to predict bitcoin fees? "),t("br"),t("br"),e._v('I have heard tales of this "Deep Learning" thing where you throw a bunch of data at it and it gives you good results with high accuracy.')]),e._v("— sanket1729 (@sanket1729) "),t("a",{attrs:{href:"https://twitter.com/sanket1729/status/1336624662365822977?ref_src=twsrc%5Etfw"}},[e._v("December 9, 2020")])]),e._v(" "),t("script",{attrs:{async:"",src:"https://platform.twitter.com/widgets.js",charset:"utf-8"}}),e._v(" "),t("p",[e._v("This is the final part of the series. In the previous "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(" we talked about the problem and in "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(" we talked about the dataset.")],1),e._v(" "),t("hr",{staticClass:"footnotes-sep"}),e._v(" "),t("section",{staticClass:"footnotes"},[t("ol",{staticClass:"footnotes-list"},[t("li",{staticClass:"footnote-item",attrs:{id:"fn1"}},[t("p",[e._v("MAE is Mean Absolute Error, which is the average of the series built by the absolute difference between the real value and the estimation. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn2"}},[t("p",[e._v("drift like MAE, but without the absolute value "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref2"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn3"}},[t("p",[e._v("Most node won't relay transactions with fee lower than the min relay fee, which has a default of "),t("code",[e._v("1.0")]),e._v(" "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref3"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn4"}},[t("p",[e._v("An important issue emerged after the article came out, a bitcoin core client with bloom filter disabled (default as of 0.21) doesn't serve the mempool via p2p. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref4"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/65.a538fc82.js b/assets/js/65.728ab52c.js similarity index 99% rename from assets/js/65.a538fc82.js rename to assets/js/65.728ab52c.js index 7d532bda61..78f803fc78 100644 --- a/assets/js/65.a538fc82.js +++ b/assets/js/65.728ab52c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[65],{423:function(t,a,e){"use strict";e.r(a);var s=e(7),n=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[t._v('This article should serve as a "getting started" guide for developers who are considering integrating BDK in their projects: it tries to introduce the reader to the basic concepts behind the library and some of its modules and components that can be used to build a very simple functioning Bitcoin wallet. All the information written in this article are valid for the latest '),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/",target:"_blank",rel:"noopener noreferrer"}},[t._v("published version"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"design-goals"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#design-goals"}},[t._v("#")]),t._v(" Design Goals")]),t._v(" "),a("p",[t._v("The main goal of the library is to be a solid foundation for Bitcoin wallets of any kind, on any platform: in practice, this means that the library should be:")]),t._v(" "),a("ul",[a("li",[t._v("Very "),a("em",[t._v("well-reviewed")]),t._v(" and tested")]),t._v(" "),a("li",[a("em",[t._v("Lightweight")]),t._v(", so that it can be used easily on mobile devices as well")]),t._v(" "),a("li",[a("em",[t._v("Extendable")]),t._v(", so that it can be adapted to perfectly suit different use-cases")]),t._v(" "),a("li",[a("em",[t._v("Generalized")]),t._v(", meaning that it supports different types of Bitcoin scripts and wallets through the use of "),a("a",{attrs:{href:"/descriptors"}},[t._v("descriptors")])]),t._v(" "),a("li",[a("em",[t._v("Reasonably easy")]),t._v(' to use, exposing a "high level" interface to the user and hiding all the complexity inside')])]),t._v(" "),a("p",[t._v("These goals have a direct impact on the design of the internal components of the library, and as a consequence on the APIs that are exposed to the final user, which might in some cases feel counter-intuitive at first.\nThroughout the article, we will try to focus on those points and try to explain them as best as we can.")]),t._v(" "),a("h2",{attrs:{id:"the-wallet-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#the-wallet-structure"}},[t._v("#")]),t._v(" The "),a("code",[t._v("Wallet")]),t._v(" Structure")]),t._v(" "),a("p",[t._v("The "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet")]),a("OutboundLink")],1),t._v(" structure is in many ways the heart of the library: it represents an instance of a wallet and exposes some APIs to perform all the typical operations one might want to do with a Bitcoin wallet, such as generating a new address, listing the transactions received, creating a transaction, etc.")]),t._v(" "),a("p",[t._v("A "),a("code",[t._v("Wallet")]),t._v(" instance can be constructed given at least one "),a("a",{attrs:{href:"/descriptors"}},[t._v("descriptor")]),t._v(" which would be used to derive both "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/enum.KeychainKind.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("External")]),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/enum.KeychainKind.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Internal")]),a("OutboundLink")],1),t._v(" addresses, or two if one prefers to keep them separated. "),a("code",[t._v("External")]),t._v(" addresses are the ones returned by the generic "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html#method.get_address",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet::get_address()")]),a("OutboundLink")],1),t._v(" call, while "),a("code",[t._v("Internal")]),t._v(" addresses are generated internally to receive the change whenever a new transaction is created. But they can be generated on demand too using "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html#method.get_internal_address",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet::get_internal_address()")]),a("OutboundLink")],1),t._v(" call.")]),t._v(" "),a("p",[t._v("A "),a("code",[t._v("Wallet")]),t._v(" also needs at least one other component to function properly, its "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/trait.Database.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Database")]),a("OutboundLink")],1),t._v(": it will be used as a "),a("em",[t._v("cache")]),t._v(" to store the list of transactions synchronized with the blockchain, the UTXOs, the addresses generated, and a few other things. It's important to note that the "),a("code",[t._v("Database")]),t._v(" will never store any secret. Securely storing keys is explicitly left to the user of the library to implement, mainly because there isn't really one good way to do it, that would work reliably on every platform. On\nmobile devices, for instance, the OS' keychain could be used, to allow unlocking the secrets with the use of biometric data (FaceID or fingerprint), while on desktop platform there isn't generally a similar framework available and the user would have to implement something that meets their needs. It's not excluded that in the future we could provide a \"reference implementation\" of secure multi-platform storage for keys, but that would very likely be released as a separate module outside of the "),a("code",[t._v("Wallet")]),t._v(" structure, or potentially even as a separate library that could be reused for other applications as well.")]),t._v(" "),a("p",[t._v("Going back to our "),a("code",[t._v("Wallet")]),t._v(": given a descriptor and a "),a("code",[t._v("Database")]),t._v(' we can build an "air-gapped" or "Offline" wallet. Basically, we can make a wallet that physically can\'t connect to the Bitcoin network. It will still be able to generate addresses and sign '),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("PSBTs"),a("OutboundLink")],1),t._v(", but with a greatly reduced attack surface because a sizable part of the code that handles the logic to synchronize with the network would be entirely omitted in the final executable binary.")]),t._v(" "),a("p",[t._v("This is how a "),a("code",[t._v("Wallet")]),t._v(" can be created. Notice that we are using "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/memory/struct.MemoryDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("MemoryDatabase")]),a("OutboundLink")],1),t._v(" as our "),a("code",[t._v("Database")]),t._v(". We'll get to that in a second.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("database"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" external_descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/0'/0'/0/*)\"")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" internal_descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/0'/0'/1/*)\"")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n external_descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("internal_descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Once we have our "),a("code",[t._v("Wallet")]),t._v(" instance we can generate a new address and print it out:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Generated Address: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Building and running this code will print out:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("Generated Address: tb1q7w0t936xp5p994qx506xj53gjdcmzjr2mkqghn\n")])])]),a("p",[t._v("Before we've talked about the benefits of an air-gapped wallet, but we should also talk about the disadvantages: the biggest one is the fact that it cannot create new transactions because it doesn't know which UTXOs belong to the wallet. To get this information we generally need to "),a("code",[t._v("sync")]),t._v(" with the network, but this wallet can't physically do that.")]),t._v(" "),a("p",[t._v("To fix this we can add one more component in our code: a "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" backend. In particular, we are going to use the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/electrum/struct.ElectrumBlockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ElectrumBlockchain")]),a("OutboundLink")],1),t._v(" which syncs with an "),a("code",[t._v("Electrum")]),t._v(" server, and then we will use this blockchain to "),a("code",[t._v("sync")]),t._v(" our wallet database with current state of the network since that's available out of the box in BDK and is pretty fast.")]),t._v(" "),a("p",[t._v("We can update our code to look something like this:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("database"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("electrum_client"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("client"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Specifically here, we create an "),a("code",[t._v("ElectrumBlockchain")]),t._v(" and connect to Blockstream's public Electrum Testnet servers over SSL.")]),t._v(" "),a("p",[t._v("Now, since we are running in the "),a("code",[t._v("Testnet")]),t._v(" network, we can try to get some funds from a faucet online to this address we've generated. Once we have an incoming transaction we can do the first "),a("code",[t._v("sync")]),t._v(" of our wallet.\nThis is again something that might seem counterintuitive at first: why do we have to manually ask the "),a("code",[t._v("Wallet")]),t._v(" to "),a("em",[t._v("sync")]),t._v(" itself? Can't it do it periodically in background? The answer is that yes, that would definitely be possible, but it would remove some control on what's happening inside the wallet from the user. This can be especially problematic on mobile platforms, where the OS tries very aggressively to suspend apps in background to save battery. Having a thread running and trying to make network requests while the app is in background would very likely cause errors or potentially crashes somewhere. So, for this reason this operation has to be performed manually, to allow the user to call that function only at the right time.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\nwallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The "),a("code",[t._v("SyncOptions")]),t._v(" determines some sync time behaviors, like progress update, etc. For this case the "),a("code",[t._v("default")]),t._v(" sync option with no progress update is adequate. This will make queries to the Electrum server and store the list of transactions and UTXOs in our "),a("code",[t._v("Database")]),t._v(". In this case, we are using a "),a("code",[t._v("MemoryDatabase")]),t._v(", so those data are only going to be kept in RAM and dropped once our "),a("code",[t._v("Wallet")]),t._v(" is dropped. This is very useful for playing around and experimenting, but not so great for real-world wallets: for that, you can use "),a("a",{attrs:{href:"https://docs.rs/sled/",target:"_blank",rel:"noopener noreferrer"}},[t._v("sled"),a("OutboundLink")],1),t._v(" which is supported out of the box, or even use a custom database. More on that later!")]),t._v(" "),a("p",[t._v("So, now that we've synced with the blockchain we can create our first transaction. First of all, we will print out the balance of our wallet to make sure that our wallet has seen the incoming transaction. Then we will create the actual transaction and we will specify some flags using the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/tx_builder/index.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("TxBuilder")]),a("OutboundLink")],1),t._v(". To finish it off, we will ask the wallet to sign the transaction and then broadcast it to the network.")]),t._v(" "),a("p",[t._v("Right now we will not get into details of all the available options in "),a("code",[t._v("TxBuilder")]),t._v(' since that is definitely out of the scope of a "getting started" guide. For now, you can just imagine the builder as your way to tell the library how to build transactions. We\'ll come back to this in a future article.')]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet balance in SAT: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" faucet_address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tx_builder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntx_builder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("faucet_address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("trusted_pending "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("confirmed"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("enable_rbf")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tx_details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tx_builder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction details: {:#?}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tx_details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("In this case, we are sending back half the balance to the faucet's address and we are also enabling RBF since the default fees are at 1 satoshi/vbyte. With RBF we will be able to "),a("em",[t._v("bump the fees")]),t._v(" of the transaction, should it get stuck in the mempool due to the low fee rate.")]),t._v(" "),a("p",[t._v("All that's left to do once we have our unsigned PSBT is to sign it:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("finalized"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tx has not been finalized"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction Signed: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" finalized"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And then broadcast it:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" raw_transaction "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" txid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" raw_transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("txid")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nblockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("raw_transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction sent! TXID: {txid}.\\nExplorer URL: https://blockstream.info/testnet/tx/{txid}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" txid\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"custom-database-and-blockchain-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#custom-database-and-blockchain-types"}},[t._v("#")]),t._v(" Custom Database and Blockchain types")]),t._v(" "),a("p",[t._v("We briefly mentioned before that for our example we used the "),a("code",[t._v("MemoryDatabase")]),t._v(", but that it could also be swapped for a different one: this is one example of the "),a("em",[t._v("modularity")]),t._v(" of BDK. By default, some database types are already implemented in the library, namely the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/memory/struct.MemoryDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("MemoryDatabase"),a("OutboundLink")],1),t._v(" which only keeps data in RAM, the "),a("a",{attrs:{href:"https://docs.rs/sled/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sled"),a("OutboundLink")],1),t._v(" database that can store data on a filesystem, and the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/struct.SqliteDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("SqliteDatabase"),a("OutboundLink")],1),t._v(" that can store data into a SQLite database. But since the "),a("code",[t._v("Database")]),t._v(" trait is public, users of the library can also implement different database types more suitable for their use-case.")]),t._v(" "),a("p",[t._v("The same is true for the "),a("code",[t._v("Blockchain")]),t._v(" types: the library provides (through the use of opt-in features) implementations for the "),a("code",[t._v("Electrum")]),t._v(", "),a("code",[t._v("Esplora")]),t._v(", "),a("code",[t._v("CompactFilters")]),t._v(" ("),a("em",[t._v("Neutrino")]),t._v(") and Bitcoin Core "),a("code",[t._v("rpc")]),t._v(" backends. Those again can also be\nswapped with custom types if the user desires to do so.")]),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("Hopefully, this article will help you get started with BDK! This is just a very quick and gentle introduction to the library, and only barely scratches the surface of what's inside: we will keep publishing more articles in the future to explain some of the more advanced features of BDK, like key generation, using complex "),a("a",{attrs:{href:"/descriptors"}},[t._v("descriptors")]),t._v(" with multiple keys and/or timelocks, using external signers, etc.")]),t._v(" "),a("p",[t._v("If you'd like to learn more about the library feel free to ask any questions in the comment section down below, or join our "),a("a",{attrs:{href:"https://discord.gg/d7NkDKm",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord Community"),a("OutboundLink")],1),t._v(" to chat with us directly!")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[65],{422:function(t,a,e){"use strict";e.r(a);var s=e(7),n=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[t._v('This article should serve as a "getting started" guide for developers who are considering integrating BDK in their projects: it tries to introduce the reader to the basic concepts behind the library and some of its modules and components that can be used to build a very simple functioning Bitcoin wallet. All the information written in this article are valid for the latest '),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/",target:"_blank",rel:"noopener noreferrer"}},[t._v("published version"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"design-goals"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#design-goals"}},[t._v("#")]),t._v(" Design Goals")]),t._v(" "),a("p",[t._v("The main goal of the library is to be a solid foundation for Bitcoin wallets of any kind, on any platform: in practice, this means that the library should be:")]),t._v(" "),a("ul",[a("li",[t._v("Very "),a("em",[t._v("well-reviewed")]),t._v(" and tested")]),t._v(" "),a("li",[a("em",[t._v("Lightweight")]),t._v(", so that it can be used easily on mobile devices as well")]),t._v(" "),a("li",[a("em",[t._v("Extendable")]),t._v(", so that it can be adapted to perfectly suit different use-cases")]),t._v(" "),a("li",[a("em",[t._v("Generalized")]),t._v(", meaning that it supports different types of Bitcoin scripts and wallets through the use of "),a("a",{attrs:{href:"/descriptors"}},[t._v("descriptors")])]),t._v(" "),a("li",[a("em",[t._v("Reasonably easy")]),t._v(' to use, exposing a "high level" interface to the user and hiding all the complexity inside')])]),t._v(" "),a("p",[t._v("These goals have a direct impact on the design of the internal components of the library, and as a consequence on the APIs that are exposed to the final user, which might in some cases feel counter-intuitive at first.\nThroughout the article, we will try to focus on those points and try to explain them as best as we can.")]),t._v(" "),a("h2",{attrs:{id:"the-wallet-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#the-wallet-structure"}},[t._v("#")]),t._v(" The "),a("code",[t._v("Wallet")]),t._v(" Structure")]),t._v(" "),a("p",[t._v("The "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet")]),a("OutboundLink")],1),t._v(" structure is in many ways the heart of the library: it represents an instance of a wallet and exposes some APIs to perform all the typical operations one might want to do with a Bitcoin wallet, such as generating a new address, listing the transactions received, creating a transaction, etc.")]),t._v(" "),a("p",[t._v("A "),a("code",[t._v("Wallet")]),t._v(" instance can be constructed given at least one "),a("a",{attrs:{href:"/descriptors"}},[t._v("descriptor")]),t._v(" which would be used to derive both "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/enum.KeychainKind.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("External")]),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/enum.KeychainKind.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Internal")]),a("OutboundLink")],1),t._v(" addresses, or two if one prefers to keep them separated. "),a("code",[t._v("External")]),t._v(" addresses are the ones returned by the generic "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html#method.get_address",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet::get_address()")]),a("OutboundLink")],1),t._v(" call, while "),a("code",[t._v("Internal")]),t._v(" addresses are generated internally to receive the change whenever a new transaction is created. But they can be generated on demand too using "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/struct.Wallet.html#method.get_internal_address",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet::get_internal_address()")]),a("OutboundLink")],1),t._v(" call.")]),t._v(" "),a("p",[t._v("A "),a("code",[t._v("Wallet")]),t._v(" also needs at least one other component to function properly, its "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/trait.Database.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Database")]),a("OutboundLink")],1),t._v(": it will be used as a "),a("em",[t._v("cache")]),t._v(" to store the list of transactions synchronized with the blockchain, the UTXOs, the addresses generated, and a few other things. It's important to note that the "),a("code",[t._v("Database")]),t._v(" will never store any secret. Securely storing keys is explicitly left to the user of the library to implement, mainly because there isn't really one good way to do it, that would work reliably on every platform. On\nmobile devices, for instance, the OS' keychain could be used, to allow unlocking the secrets with the use of biometric data (FaceID or fingerprint), while on desktop platform there isn't generally a similar framework available and the user would have to implement something that meets their needs. It's not excluded that in the future we could provide a \"reference implementation\" of secure multi-platform storage for keys, but that would very likely be released as a separate module outside of the "),a("code",[t._v("Wallet")]),t._v(" structure, or potentially even as a separate library that could be reused for other applications as well.")]),t._v(" "),a("p",[t._v("Going back to our "),a("code",[t._v("Wallet")]),t._v(": given a descriptor and a "),a("code",[t._v("Database")]),t._v(' we can build an "air-gapped" or "Offline" wallet. Basically, we can make a wallet that physically can\'t connect to the Bitcoin network. It will still be able to generate addresses and sign '),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("PSBTs"),a("OutboundLink")],1),t._v(", but with a greatly reduced attack surface because a sizable part of the code that handles the logic to synchronize with the network would be entirely omitted in the final executable binary.")]),t._v(" "),a("p",[t._v("This is how a "),a("code",[t._v("Wallet")]),t._v(" can be created. Notice that we are using "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/memory/struct.MemoryDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("MemoryDatabase")]),a("OutboundLink")],1),t._v(" as our "),a("code",[t._v("Database")]),t._v(". We'll get to that in a second.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("database"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" external_descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/0'/0'/0/*)\"")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" internal_descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/0'/0'/1/*)\"")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n external_descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("internal_descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Once we have our "),a("code",[t._v("Wallet")]),t._v(" instance we can generate a new address and print it out:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Generated Address: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Building and running this code will print out:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("Generated Address: tb1q7w0t936xp5p994qx506xj53gjdcmzjr2mkqghn\n")])])]),a("p",[t._v("Before we've talked about the benefits of an air-gapped wallet, but we should also talk about the disadvantages: the biggest one is the fact that it cannot create new transactions because it doesn't know which UTXOs belong to the wallet. To get this information we generally need to "),a("code",[t._v("sync")]),t._v(" with the network, but this wallet can't physically do that.")]),t._v(" "),a("p",[t._v("To fix this we can add one more component in our code: a "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" backend. In particular, we are going to use the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/electrum/struct.ElectrumBlockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ElectrumBlockchain")]),a("OutboundLink")],1),t._v(" which syncs with an "),a("code",[t._v("Electrum")]),t._v(" server, and then we will use this blockchain to "),a("code",[t._v("sync")]),t._v(" our wallet database with current state of the network since that's available out of the box in BDK and is pretty fast.")]),t._v(" "),a("p",[t._v("We can update our code to look something like this:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("database"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("electrum_client"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("client"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Specifically here, we create an "),a("code",[t._v("ElectrumBlockchain")]),t._v(" and connect to Blockstream's public Electrum Testnet servers over SSL.")]),t._v(" "),a("p",[t._v("Now, since we are running in the "),a("code",[t._v("Testnet")]),t._v(" network, we can try to get some funds from a faucet online to this address we've generated. Once we have an incoming transaction we can do the first "),a("code",[t._v("sync")]),t._v(" of our wallet.\nThis is again something that might seem counterintuitive at first: why do we have to manually ask the "),a("code",[t._v("Wallet")]),t._v(" to "),a("em",[t._v("sync")]),t._v(" itself? Can't it do it periodically in background? The answer is that yes, that would definitely be possible, but it would remove some control on what's happening inside the wallet from the user. This can be especially problematic on mobile platforms, where the OS tries very aggressively to suspend apps in background to save battery. Having a thread running and trying to make network requests while the app is in background would very likely cause errors or potentially crashes somewhere. So, for this reason this operation has to be performed manually, to allow the user to call that function only at the right time.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\nwallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The "),a("code",[t._v("SyncOptions")]),t._v(" determines some sync time behaviors, like progress update, etc. For this case the "),a("code",[t._v("default")]),t._v(" sync option with no progress update is adequate. This will make queries to the Electrum server and store the list of transactions and UTXOs in our "),a("code",[t._v("Database")]),t._v(". In this case, we are using a "),a("code",[t._v("MemoryDatabase")]),t._v(", so those data are only going to be kept in RAM and dropped once our "),a("code",[t._v("Wallet")]),t._v(" is dropped. This is very useful for playing around and experimenting, but not so great for real-world wallets: for that, you can use "),a("a",{attrs:{href:"https://docs.rs/sled/",target:"_blank",rel:"noopener noreferrer"}},[t._v("sled"),a("OutboundLink")],1),t._v(" which is supported out of the box, or even use a custom database. More on that later!")]),t._v(" "),a("p",[t._v("So, now that we've synced with the blockchain we can create our first transaction. First of all, we will print out the balance of our wallet to make sure that our wallet has seen the incoming transaction. Then we will create the actual transaction and we will specify some flags using the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/wallet/tx_builder/index.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("TxBuilder")]),a("OutboundLink")],1),t._v(". To finish it off, we will ask the wallet to sign the transaction and then broadcast it to the network.")]),t._v(" "),a("p",[t._v("Right now we will not get into details of all the available options in "),a("code",[t._v("TxBuilder")]),t._v(' since that is definitely out of the scope of a "getting started" guide. For now, you can just imagine the builder as your way to tell the library how to build transactions. We\'ll come back to this in a future article.')]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet balance in SAT: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" faucet_address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tx_builder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntx_builder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("faucet_address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("trusted_pending "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("confirmed"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("enable_rbf")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tx_details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tx_builder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction details: {:#?}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tx_details"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("In this case, we are sending back half the balance to the faucet's address and we are also enabling RBF since the default fees are at 1 satoshi/vbyte. With RBF we will be able to "),a("em",[t._v("bump the fees")]),t._v(" of the transaction, should it get stuck in the mempool due to the low fee rate.")]),t._v(" "),a("p",[t._v("All that's left to do once we have our unsigned PSBT is to sign it:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("finalized"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tx has not been finalized"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction Signed: {}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" finalized"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And then broadcast it:")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" raw_transaction "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" txid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" raw_transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("txid")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nblockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("raw_transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction sent! TXID: {txid}.\\nExplorer URL: https://blockstream.info/testnet/tx/{txid}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n txid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" txid\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"custom-database-and-blockchain-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#custom-database-and-blockchain-types"}},[t._v("#")]),t._v(" Custom Database and Blockchain types")]),t._v(" "),a("p",[t._v("We briefly mentioned before that for our example we used the "),a("code",[t._v("MemoryDatabase")]),t._v(", but that it could also be swapped for a different one: this is one example of the "),a("em",[t._v("modularity")]),t._v(" of BDK. By default, some database types are already implemented in the library, namely the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/memory/struct.MemoryDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("MemoryDatabase"),a("OutboundLink")],1),t._v(" which only keeps data in RAM, the "),a("a",{attrs:{href:"https://docs.rs/sled/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sled"),a("OutboundLink")],1),t._v(" database that can store data on a filesystem, and the "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/struct.SqliteDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("SqliteDatabase"),a("OutboundLink")],1),t._v(" that can store data into a SQLite database. But since the "),a("code",[t._v("Database")]),t._v(" trait is public, users of the library can also implement different database types more suitable for their use-case.")]),t._v(" "),a("p",[t._v("The same is true for the "),a("code",[t._v("Blockchain")]),t._v(" types: the library provides (through the use of opt-in features) implementations for the "),a("code",[t._v("Electrum")]),t._v(", "),a("code",[t._v("Esplora")]),t._v(", "),a("code",[t._v("CompactFilters")]),t._v(" ("),a("em",[t._v("Neutrino")]),t._v(") and Bitcoin Core "),a("code",[t._v("rpc")]),t._v(" backends. Those again can also be\nswapped with custom types if the user desires to do so.")]),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("Hopefully, this article will help you get started with BDK! This is just a very quick and gentle introduction to the library, and only barely scratches the surface of what's inside: we will keep publishing more articles in the future to explain some of the more advanced features of BDK, like key generation, using complex "),a("a",{attrs:{href:"/descriptors"}},[t._v("descriptors")]),t._v(" with multiple keys and/or timelocks, using external signers, etc.")]),t._v(" "),a("p",[t._v("If you'd like to learn more about the library feel free to ask any questions in the comment section down below, or join our "),a("a",{attrs:{href:"https://discord.gg/d7NkDKm",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord Community"),a("OutboundLink")],1),t._v(" to chat with us directly!")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/66.a99413d8.js b/assets/js/66.6ebad210.js similarity index 99% rename from assets/js/66.a99413d8.js rename to assets/js/66.6ebad210.js index 48cceb13fb..40ffc548d4 100644 --- a/assets/js/66.a99413d8.js +++ b/assets/js/66.6ebad210.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[66],{422:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"introduction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),e("p",[t._v("To send people BTC - we simply scan a QR Code "),e("em",[t._v("(or paste an address)")]),t._v(", enter some amount and "),e("em",[t._v("whoosh")]),t._v(" - sent!\nUsers might think, just like traditional currency, we can only exchange money using Bitcoin.\nAs it so happens, the underlying technology Bitcoin supports specify outputs not as addresses, but as programming scripts.\nThis opens us to a world of possibilities using Bitcoin.")]),t._v(" "),e("h2",{attrs:{id:"script"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#script"}},[t._v("#")]),t._v(" Script")]),t._v(" "),e("p",[t._v("Bitcoin supports "),e("a",{attrs:{href:"https://en.bitcoin.it/wiki/Script",target:"_blank",rel:"noopener noreferrer"}},[t._v("Script"),e("OutboundLink")],1),t._v(", a "),e("strong",[t._v("stack-based")]),t._v(" lightweight programming language.\nAny script written in "),e("strong",[t._v("Script")]),t._v(" "),e("em",[t._v("(pun intended)")]),t._v(" contains "),e("code",[t._v("OP_*")]),t._v(" codes and raw byte arrays that Bitcoin Full Nodes understand and process.\nCurrently, there are "),e("code",[t._v("117")]),t._v(" op-codes in use.\nYou can read more about these op-codes straight "),e("a",{attrs:{href:"https://en.bitcoin.it/wiki/Script",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("Script is intentionally left "),e("a",{attrs:{href:"https://en.wikipedia.org/wiki/Turing_completeness",target:"_blank",rel:"noopener noreferrer"}},[t._v("Turing incomplete"),e("OutboundLink")],1),t._v(" which is why there is no "),e("a",{attrs:{href:"https://en.wikipedia.org/wiki/Halting_problem",target:"_blank",rel:"noopener noreferrer"}},[t._v("halting problem"),e("OutboundLink")],1),t._v(" with scripts.\nThere are no loops and overall, it's a very constrained programming language.")]),t._v(" "),e("p",[t._v("A transaction is considered valid only when the Script returns "),e("code",[t._v("true")]),t._v(" at the end of execution.\nOutput 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 "),e("code",[t._v("scriptsig + scriptpubkey")]),t._v(" evaluates to "),e("code",[t._v("true")]),t._v(".")]),t._v(" "),e("p",[t._v("For example, a basic legacy "),e("code",[t._v("Pay-to-PubKey-Hash")]),t._v(" transaction would look like:")]),t._v(" "),e("div",{staticClass:"language-script extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("scriptPubKey: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG\nscriptSig: \n")])])]),e("h4",{attrs:{id:"examples-of-things-achievable-using-bitcoin-script"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#examples-of-things-achievable-using-bitcoin-script"}},[t._v("#")]),t._v(" Examples of things achievable using Bitcoin Script:")]),t._v(" "),e("ol",[e("li",[e("code",[t._v("Pay Someone (p2pkh/p2wpkh)")]),t._v(" - A specific public key must sign to spend the coins.")]),t._v(" "),e("li",[e("code",[t._v("Escrow (2-of-3-multisig)")]),t._v(" - Two parties need to sign together to spend the coins.")]),t._v(" "),e("li",[e("code",[t._v("Vault (locked)")]),t._v(" - 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.")]),t._v(" "),e("li",[e("code",[t._v("HTLC")]),t._v(" - The receiver needs disclose a secret before a timeout, else the coins are transferred back to the payee.")])]),t._v(" "),e("h4",{attrs:{id:"motivation-for-policies"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#motivation-for-policies"}},[t._v("#")]),t._v(" Motivation for Policies")]),t._v(" "),e("p",[t._v("Unfortunately, due to its low-level and unusual stack-based nature, Script is pretty hard to reason about and use.\nDespite being around since Bitcoin's creation, writing and understanding Script is not trivial.\nThis is why the scripts for the above few examples are pretty lengthy and might not make sense at the first glance.\nWhen writing a script, we would want to know that if the logic we wrote is "),e("strong",[t._v("correct")]),t._v(", "),e("strong",[t._v("optimal")]),t._v(" and "),e("strong",[t._v("efficient in size")]),t._v(" (use lower "),e("a",{attrs:{href:"https://en.bitcoin.it/wiki/Weight_units",target:"_blank",rel:"noopener noreferrer"}},[t._v("weight"),e("OutboundLink")],1),t._v(").")]),t._v(" "),e("p",[t._v("The community wanted an easy alternative way of writing Script that would create the most optimized Script code.\nThis gave rise to "),e("strong",[t._v("Miniscript")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"miniscript"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#miniscript"}},[t._v("#")]),t._v(" Miniscript")]),t._v(" "),e("p",[e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Miniscript"),e("OutboundLink")],1),t._v(" tackles the above problems head-on.\nIt is an expressive way to create policies on Bitcoin Scripts in a structured and simple fashion.\nUsing Miniscript, it's difficult to go wrong.")]),t._v(" "),e("p",[t._v("Another very important goal of Miniscript is to replace any key used in a policy with another policy.\nThis is important because people might have multiple keys and complicated timelocks in their existing setup.\nWhile signing a new policy, they would want to use their existing setup to also generate addresses for this new setup.\nThis is accomplished using something called "),e("strong",[t._v("Output Descriptors")]),t._v(" which we will get into in next section.")]),t._v(" "),e("p",[t._v("Miniscript compiler compiles a "),e("strong",[t._v("spending policy")]),t._v(" down to Miniscript.\nIt doesn't contain any signature, it's mainly a combinator language for designing spending conditions.\nYou can try out the compiler online by using "),e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/#:~:text=Policy%20to%20Miniscript%20compiler",target:"_blank",rel:"noopener noreferrer"}},[t._v("this link"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"fragments"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fragments"}},[t._v("#")]),t._v(" Fragments")]),t._v(" "),e("p",[t._v("Here are some fragments which can be combined to create powerful expressions.")]),t._v(" "),e("ol",[e("li",[e("code",[t._v("pk(key)")]),t._v(" - Specifies a given public key")]),t._v(" "),e("li",[e("code",[t._v("thresh(k, expr_1, expr_2, ..., expr_n)")]),t._v(" - Specifies k of n multisig using expressions.")]),t._v(" "),e("li",[e("code",[t._v("older(T)")]),t._v(" - Timelock for T blocks")]),t._v(" "),e("li",[e("code",[t._v("and(expr_1, expr_2)")]),t._v(" - Both expressions should evaluate to true.")]),t._v(" "),e("li",[e("code",[t._v("or(expr_1, expr_2)")]),t._v(" - Any one of the expressions should evaluate to true.")]),t._v(" "),e("li",[e("code",[t._v("aor(expr_1, expr_2)")]),t._v(" - Similar to "),e("code",[t._v("or")]),t._v(" but "),e("code",[t._v("expr_1")]),t._v(" has a more probability to evaluate to true.")])]),t._v(" "),e("p",[t._v("Bitcoin Script allows us to use another alternate stack. The combinator functions use this second stack to evaluate expressions of "),e("code",[t._v("thresh")]),t._v(", "),e("code",[t._v("and")]),t._v(", "),e("code",[t._v("aor")]),t._v(" and "),e("code",[t._v("or")]),t._v(".\nThe complete Miniscript Reference can be found "),e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/#:~:text=Miniscript%20reference",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"example-policies"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#example-policies"}},[t._v("#")]),t._v(" Example Policies")]),t._v(" "),e("p",[t._v("Here are the Miniscript Policies for the examples we looked at earlier.\nNote "),e("code",[t._v("A")]),t._v(", "),e("code",[t._v("B")]),t._v(", "),e("code",[t._v("C")]),t._v(" are placeholders for keys "),e("em",[t._v("("),e("code",[t._v("xpub")]),t._v("/"),e("code",[t._v("xprv")]),t._v(")")]),t._v(" involved in the tx.\nDescriptors are high level description of scriptpubkey (p2pkh, p2sh etc).\nAnd miniscripts are semantics that describes the actual redeemscript.\nIn general you have Descriptor(Miniscript) format.")]),t._v(" "),e("ol",[e("li",[t._v("Pay A (pay-to-public-key)")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("pk(A)\n")])])]),e("ol",{attrs:{start:"2"}},[e("li",[t._v("Escrow Account between A, B and third-party C.")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("thresh(2,pk(A),pk(B),pk(C))\n")])])]),e("ol",{attrs:{start:"3"}},[e("li",[t._v("Vault for A time-locked for T blocks with B as the master key.")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("aor(and(pk(A),time(T)),pk(B))\n")])])]),e("ol",{attrs:{start:"4"}},[e("li",[t._v("HTLC payment to B, which, if unspent for T blocks, returns to A.")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("aor(and(pk(A),time(T)),and(pk(B),hash(H))))\n")])])]),e("p",[t._v("The Miniscript Policy Compiler is written in Rust and is present in "),e("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[t._v("this repository"),e("OutboundLink")],1),t._v(".\nIn this blog, we will later use the same using "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[t._v("bitcoindevkit/bdk"),e("OutboundLink")],1),t._v(", a lightweight descriptor-based wallet library\nwith a "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("cli"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[t._v("#")]),t._v(" Descriptors")]),t._v(" "),e("p",[t._v('The Bitcoin scriptpubkey supports various schemes like P2PKH, P2SH, P2WPKH, P2TR (Segwit v1) etc.\nA Descriptor is a simple "description" of what scriptpubkey to be used for a given policy.\nIt can inclue a single pubkey within itself, or an entire miniscript policy.\nOn 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.')]),t._v(" "),e("p",[t._v('In other words, a descriptor "describes" the procedure to create an '),e("em",[t._v("address")]),t._v(", given a "),e("em",[t._v("spending condition")]),t._v(".")]),t._v(" "),e("p",[t._v("They make it easier to deal with Multisig or complicated key setups.\nDescriptors 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.\nThis feature creates a common stage for all Bitcoin apps and software.")]),t._v(" "),e("p",[t._v("The concept of descriptor came into existence in 2018 and since then, a lot of wallets have added support for descriptors.\nYou can read the descriptor doc from "),e("code",[t._v("bitcoin-core")]),t._v(" "),e("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v('According to Bitcoin Core, Output Descriptors are "a simple language which can be used to describe collections of output scripts".\nThey bring in themselves, derivation paths, master xpub/xprv fingerprints and paths to generate addresses from.\nLet\'s understand this with an example of an Output Descriptor:')]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("\nDescriptor: pkh([d34db33f/44'/0'/0']xpub6ERaJH[...]LJRcEL/1/*)#ml40v0wf\n <1> <--------2---------\x3e<----------3---------\x3e<4> <---5---\x3e\n\nSections:\n1 - address type specifier (here, describing P2PK type addresses)\n2 - master key fingerprint and derivation path from master\n3 - xpub at m/44'/0'/0\n4 - path to deriving keys/addresses at\n5 - checksum for the descriptor\n")])])]),e("p",[t._v("A descriptor have three parts:")]),t._v(" "),e("ul",[e("li",[e("em",[t._v("address type specifier")]),t._v(" (item 1) : describes the type of address created by this descriptor.")]),t._v(" "),e("li",[e("em",[t._v("policy")]),t._v(" : the spending condition that locks funds into this address.")]),t._v(" "),e("li",[e("em",[t._v("checksum")]),t._v(" : for quick verification.")])]),t._v(" "),e("p",[t._v("The address type specifiers currently supported are "),e("code",[t._v("pk")]),t._v(", "),e("code",[t._v("pkh")]),t._v(", "),e("code",[t._v("sh")]),t._v(", "),e("code",[t._v("wpkh")]),t._v(", "),e("code",[t._v("wsh")]),t._v(" for corresponding address type and recently added "),e("code",[t._v("tr")]),t._v(" for taproot addresses.")]),t._v(" "),e("p",[t._v("There is a special address specifier called "),e("code",[t._v("combo")]),t._v(" that creates addresses of all types from spending policy policy.")]),t._v(" "),e("p",[t._v("After the address specifier, comes the "),e("em",[t._v("policy")]),t._v(' that describes how the funds in the address can be spent. The descriptor\nabove in the example has a simple spending policy of "spend by the correct private key". There can be more complicated policies,\nand we will touch them in later sections.')]),t._v(" "),e("p",[e("code",[t._v("multi")]),t._v(" is a special keyword that can be used as both "),e("em",[t._v("address type")]),t._v(" and "),e("em",[t._v("policy")]),t._v(".\nWhen used as an "),e("em",[t._v("address type")]),t._v(" like "),e("code",[t._v("multi(...)")]),t._v(", it will create an address from the raw multisig scriptpubkey.\nWhile when used as a "),e("em",[t._v("policy")]),t._v(" like "),e("code",[t._v("wsh(multi(...))")]),t._v(" it will create that specific address type from the multisig script.\nOf course we cannot use "),e("code",[t._v("pk(multi(...))")]),t._v(", "),e("code",[t._v("pkh(multi(...))")]),t._v(" or "),e("code",[t._v("wpkh(multi(...))")]),t._v(", because these address types cannot hold scripts (any scripts) inside them.")]),t._v(" "),e("p",[t._v("For example a descriptor like "),e("code",[t._v("wsh(multi(2, PKA, PKB, PKC))")]),t._v(" describes a P2WSH type address created by a "),e("code",[t._v("2-of-3")]),t._v(" multisig\nscript using "),e("code",[t._v("PKA")]),t._v(", "),e("code",[t._v("PKB")]),t._v(" and "),e("code",[t._v("PKC")]),t._v(" pubkeys.")]),t._v(" "),e("h2",{attrs:{id:"where-it-all-comes-together"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#where-it-all-comes-together"}},[t._v("#")]),t._v(" Where it all comes together...")]),t._v(" "),e("p",[t._v("In this section, we are going to make a descriptor-based wallet and derive addresses from "),e("code",[t._v("bitcoin-cli")]),t._v(" and then use "),e("code",[t._v("bdk-cli")]),t._v(" to confirm that the addresses generated for descriptor wallets are deterministic for a given descriptor.")]),t._v(" "),e("p",[t._v("We will also try to create a vault miniscript policy and push funds to the vault with a lock time of 2 months.\nDuring this time, we will try to break our vault and see our transactions failing.")]),t._v(" "),e("h4",{attrs:{id:"tools-and-armor"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tools-and-armor"}},[t._v("#")]),t._v(" Tools and Armor")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://docs.docker.com/engine/install/",target:"_blank",rel:"noopener noreferrer"}},[t._v("docker"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-cli"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-cli/compiler/#installation",target:"_blank",rel:"noopener noreferrer"}},[t._v("miniscriptc"),e("OutboundLink")],1)])]),t._v(" "),e("h4",{attrs:{id:"setting-up"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),e("p",[t._v("We require "),e("code",[t._v("bitcoind")]),t._v(" to run in "),e("code",[t._v("regtest")]),t._v(" mode. Use the following config file, or any other config\nthat you are familiar with.")]),t._v(" "),e("div",{staticClass:"language-txt extra-class"},[e("pre",{pre:!0,attrs:{class:"language-txt"}},[e("code",[t._v("regtest=1\nfallbackfee=0.0001\nserver=1\n\nrpcuser=user\nrpcpassword=password\n")])])]),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Start Bitcoin Core")]),t._v("\nbitcoind\n")])])]),e("h3",{attrs:{id:"keys-and-generating-addresses"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#keys-and-generating-addresses"}},[t._v("#")]),t._v(" Keys and Generating Addresses")]),t._v(" "),e("p",[t._v("Quick installation for "),e("code",[t._v("bdk-cli")]),t._v(" and "),e("code",[t._v("miniscriptc")]),t._v(":")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--features")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("rpc,compiler\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" bdk "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--features")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compiler"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--example")]),t._v(" miniscriptc\n")])])]),e("p",[t._v("Let us first generate an XPRV and create the wpkh wallet descriptor")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("EX_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh('),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$XPRV")]),t._v("/86'/1'/0'/0/*)\"")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("EX_DESC_CS")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("elcli getdescriptorinfo $EX_DESC "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.checksum'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("EX_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#$EX_DESC_CS")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Set this descriptor in a wallet in bitcoin-cli")]),t._v("\nbitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-named")]),t._v(" createwallet "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("wallet_name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mywallet"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("descriptors")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("true\nbitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-rpcwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mywallet"')]),t._v(" importdescriptors "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"[{'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("desc"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(", "),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("timestamp"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("now"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(", "),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("active"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(": true, "),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("range"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(': [0,100]}]"')]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("echo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),t._v("\n")])])]),e("p",[t._v("It should look something like this:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("wpkh(tprv8ZgxMBicQKsPeuazF16EdPZw84eHj55AU8ZKgZgdhu3sXcHnFgjzskfDvZdTaAFHYNCbKqrurFo9onSaT7zGT1i3u3j7LKhVZF5sJA39WPN/86'/1'/0'/0/*)#40hv8z77\n")])])]),e("p",[t._v("Now, we will generate 10 addresses using "),e("code",[t._v("bitcoin-cli")]),t._v(" and thereafter "),e("code",[t._v("bdk-cli")]),t._v(" using this above descriptor.\nNotice how both of them output the same set of addresses.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Generation via bdk-cli")]),t._v("\nrepeat "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-n")]),t._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--descriptor")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-w")]),t._v(" mywallet get_new_address "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".address"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nbcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp\nbcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur\nbcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez\nbcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99\nbcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv\nbcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy\nbcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j\nbcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp\nbcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67\nbcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Generation via bitcoin-cli")]),t._v("\nrepeat "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-rpcwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mywallet"')]),t._v(" getnewaddress "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nbcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp\nbcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur\nbcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez\nbcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99\nbcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv\nbcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy\nbcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j\nbcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp\nbcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67\nbcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz\n")])])]),e("p",[t._v("Notes:")]),t._v(" "),e("ul",[e("li",[t._v("The "),e("code",[t._v("repeat n {}")]),t._v(" syntax will only work in "),e("code",[t._v("zsh")]),t._v(", you can use other loops for your shell, or just manually repeat the code 10 times.")]),t._v(" "),e("li",[t._v("In case you get different outputs in either of the cases, try deleting "),e("code",[t._v("~/.bdk-bitcoin")]),t._v(" and retrying (thanks "),e("a",{attrs:{href:"https://twitter.com/notmandatory",target:"_blank",rel:"noopener noreferrer"}},[t._v("@Steve"),e("OutboundLink")],1),t._v(" for this tip!)")])]),t._v(" "),e("p",[t._v("Note that both "),e("code",[t._v("bdk-cli")]),t._v(" and "),e("code",[t._v("bitcoin-cli")]),t._v(" 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!")]),t._v(" "),e("h3",{attrs:{id:"making-a-multisig-descriptor-for-funds"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#making-a-multisig-descriptor-for-funds"}},[t._v("#")]),t._v(" Making a MultiSig Descriptor for Funds")]),t._v(" "),e("p",[t._v("In the real-life, most of us hold two kinds of savings accounts - one to store huge funds saved throughout our lifetime "),e("em",[t._v("(probably without internet banking functionalities)")]),t._v("\nand another for regular expenses.")]),t._v(" "),e("p",[t._v("In the Bitcoin world, to store huge funds, most people prefer to use a Multisig descriptor with a "),e("code",[t._v("2-of-3")]),t._v(" or "),e("code",[t._v("3-of-4")]),t._v(" setup.\nThey 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.\nIn 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.")]),t._v(" "),e("p",[t._v("Here's how a secure "),e("code",[t._v("2-of-3")]),t._v(" descriptor generation would look like:")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xprv generation")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K2_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K3_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xpub generation")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $K1_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K2_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $K2_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K3_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $K3_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Descriptors for each key - Since we used BIP-84 generation paths for xpubs,")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# we need to append the same to the xprvs so that our wallet can understand ")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# which path to generate addresses and xpubs from")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wsh(multi(2,'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_XPRV")]),t._v("/84'/1'/0'/0/*,"),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K2_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K3_XPUB")]),t._v('))"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K2_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wsh(multi(2,'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K2_XPRV")]),t._v("/84'/1'/0'/0/*,"),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K3_XPUB")]),t._v('))"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K3_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wsh(multi(2,'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K2_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K3_XPRV")]),t._v("/84'/1'/0'/0/*))\"")]),t._v("\n")])])]),e("p",[t._v("Lets create three bdk wallets aliases with above descriptors for easy future use\nand do initial sync to create the wallet files")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("k1wallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w K1 -d $K1_DESC'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("k2wallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w K2 -d $K2_DESC'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("k3wallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w K3 -d $K3_DESC'")]),t._v("\n\nk1wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk2wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk3wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Now, let us send some funds to an address generated by "),e("code",[t._v("k1wallet")]),t._v(".")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('# ask regtest to generate 101 blocks, so we get 50 regtest coins to play with.\n# because coinbase amounts are only spendable after 100 blocks, we generate\n# 101 blocks, to use the first block\'s coinbase amount.\nCORE_ADDR=$(bitcoin-cli getnewaddress)\nbitcoin-cli generatetoaddress 101 $CORE_ADDR\nbitcoin-cli getbalance\n50.00000000\n\n# And then send 10 btc to an address generated by `K1` descriptor\nBDK_ADDR=$(k1wallet get_new_address | jq -r ".address")\nbitcoin-cli -rpcwallet=mywallet sendtoaddress $BDK_ADDR 10\n\n# Confirm the transaction by creating one more block\nbitcoin-cli generatetoaddress 1 $CORE_ADDR\n')])])]),e("p",[t._v("Now sync the wallets and check balances in each")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[t._v("k1wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk1wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nk2wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk2wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nk3wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk3wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Everyone has the same amount of balance.\nThis happened because it was a multisig wallet.\nNow, let's try to spend some balance.\nWe will give back some balance to the wallet maintained by "),e("code",[t._v("bitcoin-cli")]),t._v(".\nBut remember, this is a "),e("code",[t._v("2-of-3")]),t._v(" multisig wallet.\nThat's why we will need at least two keys to sign to make a transaction.")]),t._v(" "),e("p",[t._v("Here's where we will require to use a "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("PSBT"),e("OutboundLink")],1),t._v(" or a "),e("em",[t._v("partially signed bitcoin transaction")]),t._v(".\nBitcoin uses PSBTs as the standard protocol to create a transaction and add one or more signatures to it before broadcasting the same to\nthe network which finally can become a proper valid "),e("em",[t._v("transaction")]),t._v(".")]),t._v(" "),e("p",[t._v("We will aks "),e("code",[t._v("k2wallet")]),t._v(" to create and sign the transaction then "),e("code",[t._v("k1wallet")]),t._v(" and "),e("code",[t._v("k3wallet")]),t._v(" will co-sign it.\nNote that "),e("code",[t._v("k2wallet")]),t._v(" even if it creates the transaction, doesn't need to sign it, because its a "),e("code",[t._v("2-of-3")]),t._v(" multisig!")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# create the transaction, can be started by anyone")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("k2wallet create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--to")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v(':100000000"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sign the transaction by K1 and look at the output")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# it should say the psbt is not finalized since only one party has signed")]),t._v("\nk1wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"is_finalized"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" false,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"[...]"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Saving the PSBT signed by K1")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("k1wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sign by K3 - should be finalized this time")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Notice that this time, the input psbt was the signed PSBT of K1")]),t._v("\nk3wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"is_finalized"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" true,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"[...]"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Saving the PSBT signed by K3")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("k3wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $K1_SIGNED_PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Broadcast the transaction, again doesn't really matter who broadcasts")]),t._v("\nk2wallet broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"49e2706fc73c49605692bf1b9ce58baf1eb0307ea39b3118628994fd56c9b642"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Confirm the transaction by generating one block")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sync and check balance - it should have gone down by 100000000 + tx fees")]),t._v("\nk1wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\nk1wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("899999810")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Check similarly for `k2wallet` and `k3wallet` and they should all have same balance")]),t._v("\n")])])]),e("p",[t._v("So this proves we can definitely do transactions with multisig wallets with complicated descriptors.\nSince for Bitcoin, having keys equal having access to the accounts, we need to keep our keys safe.\nFor legacy single key wallets, we used to keep backups of the mnemonic codes in multiple places.\nIt was pretty insecure because in case any one of those backups leaks, our entire account would be compromised.\nComplicated 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.")]),t._v(" "),e("p",[t._v("Another problem with multisig was syncing between wallets to always create consistent addresses. How would\none wallet know whats the next address to create without talking to other wallets? The answer is "),e("code",[t._v("descriptors + PSBT")]),t._v(".\nIf all the wallet shares the correct descriptor string they will always create the exact sequence of addresses and\nby 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.")]),t._v(" "),e("h2",{attrs:{id:"retention-bonus-smart-contract-with-bitcoin"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#retention-bonus-smart-contract-with-bitcoin"}},[t._v("#")]),t._v(" Retention Bonus - Smart Contract with Bitcoin")]),t._v(" "),e("p",[t._v("Let us consider that a company wants to give its employees a retention bonus for two months.\nIf an employee stays with that company for over 2 months, the employee would get 1 BTC as a reward.\nThis would be a smart contract between the company and an employee.\nThe employee should be able to see that he would get his funds after two months.\nThe company would require confidence that the employee would not be able to withdraw the reward before two months have passed.")]),t._v(" "),e("p",[t._v("The Miniscript policy for this contract would be as follows:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("or(99@and(pk(E),older(8640)),pk(C))\n")])])]),e("p",[t._v("where "),e("code",[t._v("E")]),t._v(" is the employee and "),e("code",[t._v("C")]),t._v(" is the company.")]),t._v(" "),e("p",[t._v("I should emphasize over here that this policy will let the company still transfer funds after the designated 2 months.\nIt's not possible to block them after the lock time has passed, atleast not in a single policy.")]),t._v(" "),e("p",[t._v("Surely, after two months, the funds can be unlocked by the employee but before that, the company can revoke the funds.\nLet us compile this policy down to a descriptor. And this time we will ask help from the "),e("code",[t._v("miniscript")]),t._v(" program.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# The Descriptor will be on the log, the E and C are placeholders")]),t._v("\nminiscriptc "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"or(99@and(pk(E),older(8640)),pk(C))"')]),t._v(" sh-wsh\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2021")]),t._v("-08-05T12:25:40Z INFO miniscriptc"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" Compiling policy: or"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("99")]),t._v("@and"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",older"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8640")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v(",pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2021")]),t._v("-08-05T12:25:40Z INFO miniscriptc"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". Descriptor: sh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wsh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("andor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",older"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8640")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#55wzucxa")]),t._v("\nError: Descriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Miniscript"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Unexpected"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Key too short (<66 char), doesn\'t match any format"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("So the compiled descriptor is")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("sh(wsh(andor(pk(E),older(8640),pk(C))))\n")])])]),e("p",[t._v("Let's make the keys, generate addresses using the above descriptor and fund it.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xprvs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xpubs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $E_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $C_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# descriptors using the compiled miniscript")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# please note in case company or the employee was using a complicated multisig descriptor,")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# it may as well have been added here like we did in the example before")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sh(wsh(andor(pk('),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$E_XPRV")]),t._v("/84'/1'/0'/0/*),older(8640),pk("),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$C_XPUB")]),t._v('))))"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sh(wsh(andor(pk('),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$E_XPUB")]),t._v("),older(8640),pk("),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$C_XPRV")]),t._v("/84'/1'/0'/0/*))))\"")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Create wallet aliases for easy access and sync the wallet to create initial wallet files")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("Cwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w C -d $C_DESC'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("Ewallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w E -d $E_DESC'")]),t._v("\n\nCwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nEwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# get some funds in Cwallet's address")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_ADDR")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Cwallet get_new_address "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".address"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\nbitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-rpcwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("mywallet sendtoaddress "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$C_ADDR")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Confirm the transaction")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sync and check balance")]),t._v("\nCwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nCwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Just as before, the employe can also see the fund in their wallet")]),t._v("\nEwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nEwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("According to the spending policy, for "),e("code",[t._v("E")]),t._v(" has to wait for 8640 blocks before he can spend the coins.\nBut let's check what happens if "),e("code",[t._v("E")]),t._v(" tries to transact before the designated 2 months anyway.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# address to send the transaction to")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_ADDR")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet getnewaddress "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".address"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# get external_policy id - this identifies which policy the wallet will try to sign against")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("POLICY_ID")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet policies "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".external | .id"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# create the tx (external_policy id from last step in my case is j7ncy3au")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--to")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$E_ADDR")]),t._v(':100000000"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--external_policy")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$POLICY_ID")]),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(':[0]}"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# sign and save the signed psbt")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# now let's try to broadcast - and see it failing")]),t._v("\nEwallet broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2021")]),t._v("-08-05T17:48:45Z ERROR bdk_cli"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" Electrum"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Protocol"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"code"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" Number"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(", "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"message"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" String"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sendrawtransaction RPC error: {'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("code"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":-26,"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("message"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("non-BIP68-final"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v('}"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("We get an error saying the transaction we sent is "),e("strong",[t._v("Not BIP68 Final")]),t._v(".\n"),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP68"),e("OutboundLink")],1),t._v(" 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.\nSo that's an expected error.")]),t._v(" "),e("p",[t._v("Now let's simulate two months passing and retry.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# simulate two months")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# this will take around 1 mins to complete")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8640")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# create, sign and broadcast tx")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--to")]),t._v(" $E_ADDR:100000000 "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--external_policy")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$POLICY_ID")]),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(':[0]}"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\nEwallet broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2a0919bb3ce6e26018698ad1169965301a9ceab6d3da2a3dcb41343dc48e0dba"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Confirm the transaction")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sync and check balances")]),t._v("\nCwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nCwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("999999810")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nEwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nEwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("999999810")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("So this time it worked, because we have simulated 2 months passing by generating 8640 blocks. And both the Company\nand Employe wallet gets updated.\nHence, we saw that we can generate some smart contracts using Bitcoin.")]),t._v(" "),e("h2",{attrs:{id:"inspirations"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#inspirations"}},[t._v("#")]),t._v(" Inspirations")]),t._v(" "),e("ol",[e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Descriptors from Bitcoin Core"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript",target:"_blank",rel:"noopener noreferrer"}},[t._v("Miniscript"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors",target:"_blank",rel:"noopener noreferrer"}},[t._v("Output Script Descriptors"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoindevkit.org/descriptors",target:"_blank",rel:"noopener noreferrer"}},[t._v("Descriptors in Bitcoin Dev Kit"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/#the-role-of-descriptors",target:"_blank",rel:"noopener noreferrer"}},[t._v("Role of Descriptors"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://gist.github.com/notmandatory/483c7edd098550c235da75d5babcf255",target:"_blank",rel:"noopener noreferrer"}},[t._v("Making a Taproot Descriptor Wallet using bitcoin-cli"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=XM1lzN4Zfks",target:"_blank",rel:"noopener noreferrer"}},[t._v("Miniscripts SBC '19 - Video"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=xC25NzIjzog",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rethinking Wallet Architecture: Native Descriptor Wallets - Video"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("Special thanks to my mentor "),e("a",{attrs:{href:"https://twitter.com/notmandatory",target:"_blank",rel:"noopener noreferrer"}},[t._v("Steve Myers"),e("OutboundLink")],1),t._v(" for the constant motivation and support he gave me and for clearing so many doubts!\nImmense thanks to "),e("a",{attrs:{href:"https://github.com/rajarshimaitra",target:"_blank",rel:"noopener noreferrer"}},[t._v("Raj"),e("OutboundLink")],1),t._v(" for reviewing this blog and giving such detailed suggestions.\nMany of the lines added here are his.\nAlso, thanks to the folks at the "),e("code",[t._v("#miniscript")]),t._v(" IRC channel to help me out with the Retention Bonus policy.")]),t._v(" "),e("p",[t._v("This blog was written during "),e("a",{attrs:{href:"https://summerofbitcoin.org",target:"_blank",rel:"noopener noreferrer"}},[t._v("Summer of Bitcoin 2021"),e("OutboundLink")],1),t._v(" by "),e("a",{attrs:{href:"https://twitter.com/@sandipndev",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sandipan Dey"),e("OutboundLink")],1),t._v(".")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[66],{423:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"introduction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),e("p",[t._v("To send people BTC - we simply scan a QR Code "),e("em",[t._v("(or paste an address)")]),t._v(", enter some amount and "),e("em",[t._v("whoosh")]),t._v(" - sent!\nUsers might think, just like traditional currency, we can only exchange money using Bitcoin.\nAs it so happens, the underlying technology Bitcoin supports specify outputs not as addresses, but as programming scripts.\nThis opens us to a world of possibilities using Bitcoin.")]),t._v(" "),e("h2",{attrs:{id:"script"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#script"}},[t._v("#")]),t._v(" Script")]),t._v(" "),e("p",[t._v("Bitcoin supports "),e("a",{attrs:{href:"https://en.bitcoin.it/wiki/Script",target:"_blank",rel:"noopener noreferrer"}},[t._v("Script"),e("OutboundLink")],1),t._v(", a "),e("strong",[t._v("stack-based")]),t._v(" lightweight programming language.\nAny script written in "),e("strong",[t._v("Script")]),t._v(" "),e("em",[t._v("(pun intended)")]),t._v(" contains "),e("code",[t._v("OP_*")]),t._v(" codes and raw byte arrays that Bitcoin Full Nodes understand and process.\nCurrently, there are "),e("code",[t._v("117")]),t._v(" op-codes in use.\nYou can read more about these op-codes straight "),e("a",{attrs:{href:"https://en.bitcoin.it/wiki/Script",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("Script is intentionally left "),e("a",{attrs:{href:"https://en.wikipedia.org/wiki/Turing_completeness",target:"_blank",rel:"noopener noreferrer"}},[t._v("Turing incomplete"),e("OutboundLink")],1),t._v(" which is why there is no "),e("a",{attrs:{href:"https://en.wikipedia.org/wiki/Halting_problem",target:"_blank",rel:"noopener noreferrer"}},[t._v("halting problem"),e("OutboundLink")],1),t._v(" with scripts.\nThere are no loops and overall, it's a very constrained programming language.")]),t._v(" "),e("p",[t._v("A transaction is considered valid only when the Script returns "),e("code",[t._v("true")]),t._v(" at the end of execution.\nOutput 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 "),e("code",[t._v("scriptsig + scriptpubkey")]),t._v(" evaluates to "),e("code",[t._v("true")]),t._v(".")]),t._v(" "),e("p",[t._v("For example, a basic legacy "),e("code",[t._v("Pay-to-PubKey-Hash")]),t._v(" transaction would look like:")]),t._v(" "),e("div",{staticClass:"language-script extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("scriptPubKey: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG\nscriptSig: \n")])])]),e("h4",{attrs:{id:"examples-of-things-achievable-using-bitcoin-script"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#examples-of-things-achievable-using-bitcoin-script"}},[t._v("#")]),t._v(" Examples of things achievable using Bitcoin Script:")]),t._v(" "),e("ol",[e("li",[e("code",[t._v("Pay Someone (p2pkh/p2wpkh)")]),t._v(" - A specific public key must sign to spend the coins.")]),t._v(" "),e("li",[e("code",[t._v("Escrow (2-of-3-multisig)")]),t._v(" - Two parties need to sign together to spend the coins.")]),t._v(" "),e("li",[e("code",[t._v("Vault (locked)")]),t._v(" - 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.")]),t._v(" "),e("li",[e("code",[t._v("HTLC")]),t._v(" - The receiver needs disclose a secret before a timeout, else the coins are transferred back to the payee.")])]),t._v(" "),e("h4",{attrs:{id:"motivation-for-policies"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#motivation-for-policies"}},[t._v("#")]),t._v(" Motivation for Policies")]),t._v(" "),e("p",[t._v("Unfortunately, due to its low-level and unusual stack-based nature, Script is pretty hard to reason about and use.\nDespite being around since Bitcoin's creation, writing and understanding Script is not trivial.\nThis is why the scripts for the above few examples are pretty lengthy and might not make sense at the first glance.\nWhen writing a script, we would want to know that if the logic we wrote is "),e("strong",[t._v("correct")]),t._v(", "),e("strong",[t._v("optimal")]),t._v(" and "),e("strong",[t._v("efficient in size")]),t._v(" (use lower "),e("a",{attrs:{href:"https://en.bitcoin.it/wiki/Weight_units",target:"_blank",rel:"noopener noreferrer"}},[t._v("weight"),e("OutboundLink")],1),t._v(").")]),t._v(" "),e("p",[t._v("The community wanted an easy alternative way of writing Script that would create the most optimized Script code.\nThis gave rise to "),e("strong",[t._v("Miniscript")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"miniscript"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#miniscript"}},[t._v("#")]),t._v(" Miniscript")]),t._v(" "),e("p",[e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Miniscript"),e("OutboundLink")],1),t._v(" tackles the above problems head-on.\nIt is an expressive way to create policies on Bitcoin Scripts in a structured and simple fashion.\nUsing Miniscript, it's difficult to go wrong.")]),t._v(" "),e("p",[t._v("Another very important goal of Miniscript is to replace any key used in a policy with another policy.\nThis is important because people might have multiple keys and complicated timelocks in their existing setup.\nWhile signing a new policy, they would want to use their existing setup to also generate addresses for this new setup.\nThis is accomplished using something called "),e("strong",[t._v("Output Descriptors")]),t._v(" which we will get into in next section.")]),t._v(" "),e("p",[t._v("Miniscript compiler compiles a "),e("strong",[t._v("spending policy")]),t._v(" down to Miniscript.\nIt doesn't contain any signature, it's mainly a combinator language for designing spending conditions.\nYou can try out the compiler online by using "),e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/#:~:text=Policy%20to%20Miniscript%20compiler",target:"_blank",rel:"noopener noreferrer"}},[t._v("this link"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"fragments"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fragments"}},[t._v("#")]),t._v(" Fragments")]),t._v(" "),e("p",[t._v("Here are some fragments which can be combined to create powerful expressions.")]),t._v(" "),e("ol",[e("li",[e("code",[t._v("pk(key)")]),t._v(" - Specifies a given public key")]),t._v(" "),e("li",[e("code",[t._v("thresh(k, expr_1, expr_2, ..., expr_n)")]),t._v(" - Specifies k of n multisig using expressions.")]),t._v(" "),e("li",[e("code",[t._v("older(T)")]),t._v(" - Timelock for T blocks")]),t._v(" "),e("li",[e("code",[t._v("and(expr_1, expr_2)")]),t._v(" - Both expressions should evaluate to true.")]),t._v(" "),e("li",[e("code",[t._v("or(expr_1, expr_2)")]),t._v(" - Any one of the expressions should evaluate to true.")]),t._v(" "),e("li",[e("code",[t._v("aor(expr_1, expr_2)")]),t._v(" - Similar to "),e("code",[t._v("or")]),t._v(" but "),e("code",[t._v("expr_1")]),t._v(" has a more probability to evaluate to true.")])]),t._v(" "),e("p",[t._v("Bitcoin Script allows us to use another alternate stack. The combinator functions use this second stack to evaluate expressions of "),e("code",[t._v("thresh")]),t._v(", "),e("code",[t._v("and")]),t._v(", "),e("code",[t._v("aor")]),t._v(" and "),e("code",[t._v("or")]),t._v(".\nThe complete Miniscript Reference can be found "),e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/#:~:text=Miniscript%20reference",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"example-policies"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#example-policies"}},[t._v("#")]),t._v(" Example Policies")]),t._v(" "),e("p",[t._v("Here are the Miniscript Policies for the examples we looked at earlier.\nNote "),e("code",[t._v("A")]),t._v(", "),e("code",[t._v("B")]),t._v(", "),e("code",[t._v("C")]),t._v(" are placeholders for keys "),e("em",[t._v("("),e("code",[t._v("xpub")]),t._v("/"),e("code",[t._v("xprv")]),t._v(")")]),t._v(" involved in the tx.\nDescriptors are high level description of scriptpubkey (p2pkh, p2sh etc).\nAnd miniscripts are semantics that describes the actual redeemscript.\nIn general you have Descriptor(Miniscript) format.")]),t._v(" "),e("ol",[e("li",[t._v("Pay A (pay-to-public-key)")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("pk(A)\n")])])]),e("ol",{attrs:{start:"2"}},[e("li",[t._v("Escrow Account between A, B and third-party C.")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("thresh(2,pk(A),pk(B),pk(C))\n")])])]),e("ol",{attrs:{start:"3"}},[e("li",[t._v("Vault for A time-locked for T blocks with B as the master key.")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("aor(and(pk(A),time(T)),pk(B))\n")])])]),e("ol",{attrs:{start:"4"}},[e("li",[t._v("HTLC payment to B, which, if unspent for T blocks, returns to A.")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("aor(and(pk(A),time(T)),and(pk(B),hash(H))))\n")])])]),e("p",[t._v("The Miniscript Policy Compiler is written in Rust and is present in "),e("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[t._v("this repository"),e("OutboundLink")],1),t._v(".\nIn this blog, we will later use the same using "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[t._v("bitcoindevkit/bdk"),e("OutboundLink")],1),t._v(", a lightweight descriptor-based wallet library\nwith a "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("cli"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[t._v("#")]),t._v(" Descriptors")]),t._v(" "),e("p",[t._v('The Bitcoin scriptpubkey supports various schemes like P2PKH, P2SH, P2WPKH, P2TR (Segwit v1) etc.\nA Descriptor is a simple "description" of what scriptpubkey to be used for a given policy.\nIt can inclue a single pubkey within itself, or an entire miniscript policy.\nOn 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.')]),t._v(" "),e("p",[t._v('In other words, a descriptor "describes" the procedure to create an '),e("em",[t._v("address")]),t._v(", given a "),e("em",[t._v("spending condition")]),t._v(".")]),t._v(" "),e("p",[t._v("They make it easier to deal with Multisig or complicated key setups.\nDescriptors 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.\nThis feature creates a common stage for all Bitcoin apps and software.")]),t._v(" "),e("p",[t._v("The concept of descriptor came into existence in 2018 and since then, a lot of wallets have added support for descriptors.\nYou can read the descriptor doc from "),e("code",[t._v("bitcoin-core")]),t._v(" "),e("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v('According to Bitcoin Core, Output Descriptors are "a simple language which can be used to describe collections of output scripts".\nThey bring in themselves, derivation paths, master xpub/xprv fingerprints and paths to generate addresses from.\nLet\'s understand this with an example of an Output Descriptor:')]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("\nDescriptor: pkh([d34db33f/44'/0'/0']xpub6ERaJH[...]LJRcEL/1/*)#ml40v0wf\n <1> <--------2---------\x3e<----------3---------\x3e<4> <---5---\x3e\n\nSections:\n1 - address type specifier (here, describing P2PK type addresses)\n2 - master key fingerprint and derivation path from master\n3 - xpub at m/44'/0'/0\n4 - path to deriving keys/addresses at\n5 - checksum for the descriptor\n")])])]),e("p",[t._v("A descriptor have three parts:")]),t._v(" "),e("ul",[e("li",[e("em",[t._v("address type specifier")]),t._v(" (item 1) : describes the type of address created by this descriptor.")]),t._v(" "),e("li",[e("em",[t._v("policy")]),t._v(" : the spending condition that locks funds into this address.")]),t._v(" "),e("li",[e("em",[t._v("checksum")]),t._v(" : for quick verification.")])]),t._v(" "),e("p",[t._v("The address type specifiers currently supported are "),e("code",[t._v("pk")]),t._v(", "),e("code",[t._v("pkh")]),t._v(", "),e("code",[t._v("sh")]),t._v(", "),e("code",[t._v("wpkh")]),t._v(", "),e("code",[t._v("wsh")]),t._v(" for corresponding address type and recently added "),e("code",[t._v("tr")]),t._v(" for taproot addresses.")]),t._v(" "),e("p",[t._v("There is a special address specifier called "),e("code",[t._v("combo")]),t._v(" that creates addresses of all types from spending policy policy.")]),t._v(" "),e("p",[t._v("After the address specifier, comes the "),e("em",[t._v("policy")]),t._v(' that describes how the funds in the address can be spent. The descriptor\nabove in the example has a simple spending policy of "spend by the correct private key". There can be more complicated policies,\nand we will touch them in later sections.')]),t._v(" "),e("p",[e("code",[t._v("multi")]),t._v(" is a special keyword that can be used as both "),e("em",[t._v("address type")]),t._v(" and "),e("em",[t._v("policy")]),t._v(".\nWhen used as an "),e("em",[t._v("address type")]),t._v(" like "),e("code",[t._v("multi(...)")]),t._v(", it will create an address from the raw multisig scriptpubkey.\nWhile when used as a "),e("em",[t._v("policy")]),t._v(" like "),e("code",[t._v("wsh(multi(...))")]),t._v(" it will create that specific address type from the multisig script.\nOf course we cannot use "),e("code",[t._v("pk(multi(...))")]),t._v(", "),e("code",[t._v("pkh(multi(...))")]),t._v(" or "),e("code",[t._v("wpkh(multi(...))")]),t._v(", because these address types cannot hold scripts (any scripts) inside them.")]),t._v(" "),e("p",[t._v("For example a descriptor like "),e("code",[t._v("wsh(multi(2, PKA, PKB, PKC))")]),t._v(" describes a P2WSH type address created by a "),e("code",[t._v("2-of-3")]),t._v(" multisig\nscript using "),e("code",[t._v("PKA")]),t._v(", "),e("code",[t._v("PKB")]),t._v(" and "),e("code",[t._v("PKC")]),t._v(" pubkeys.")]),t._v(" "),e("h2",{attrs:{id:"where-it-all-comes-together"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#where-it-all-comes-together"}},[t._v("#")]),t._v(" Where it all comes together...")]),t._v(" "),e("p",[t._v("In this section, we are going to make a descriptor-based wallet and derive addresses from "),e("code",[t._v("bitcoin-cli")]),t._v(" and then use "),e("code",[t._v("bdk-cli")]),t._v(" to confirm that the addresses generated for descriptor wallets are deterministic for a given descriptor.")]),t._v(" "),e("p",[t._v("We will also try to create a vault miniscript policy and push funds to the vault with a lock time of 2 months.\nDuring this time, we will try to break our vault and see our transactions failing.")]),t._v(" "),e("h4",{attrs:{id:"tools-and-armor"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tools-and-armor"}},[t._v("#")]),t._v(" Tools and Armor")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://docs.docker.com/engine/install/",target:"_blank",rel:"noopener noreferrer"}},[t._v("docker"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-cli"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-cli/compiler/#installation",target:"_blank",rel:"noopener noreferrer"}},[t._v("miniscriptc"),e("OutboundLink")],1)])]),t._v(" "),e("h4",{attrs:{id:"setting-up"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),e("p",[t._v("We require "),e("code",[t._v("bitcoind")]),t._v(" to run in "),e("code",[t._v("regtest")]),t._v(" mode. Use the following config file, or any other config\nthat you are familiar with.")]),t._v(" "),e("div",{staticClass:"language-txt extra-class"},[e("pre",{pre:!0,attrs:{class:"language-txt"}},[e("code",[t._v("regtest=1\nfallbackfee=0.0001\nserver=1\n\nrpcuser=user\nrpcpassword=password\n")])])]),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Start Bitcoin Core")]),t._v("\nbitcoind\n")])])]),e("h3",{attrs:{id:"keys-and-generating-addresses"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#keys-and-generating-addresses"}},[t._v("#")]),t._v(" Keys and Generating Addresses")]),t._v(" "),e("p",[t._v("Quick installation for "),e("code",[t._v("bdk-cli")]),t._v(" and "),e("code",[t._v("miniscriptc")]),t._v(":")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--features")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("rpc,compiler\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" bdk "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--features")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compiler"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--example")]),t._v(" miniscriptc\n")])])]),e("p",[t._v("Let us first generate an XPRV and create the wpkh wallet descriptor")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("EX_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh('),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$XPRV")]),t._v("/86'/1'/0'/0/*)\"")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("EX_DESC_CS")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("elcli getdescriptorinfo $EX_DESC "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.checksum'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("EX_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#$EX_DESC_CS")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Set this descriptor in a wallet in bitcoin-cli")]),t._v("\nbitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-named")]),t._v(" createwallet "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("wallet_name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mywallet"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("descriptors")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("true\nbitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-rpcwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mywallet"')]),t._v(" importdescriptors "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"[{'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("desc"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(", "),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("timestamp"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("now"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(", "),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("active"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(": true, "),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("range"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(': [0,100]}]"')]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("echo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),t._v("\n")])])]),e("p",[t._v("It should look something like this:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("wpkh(tprv8ZgxMBicQKsPeuazF16EdPZw84eHj55AU8ZKgZgdhu3sXcHnFgjzskfDvZdTaAFHYNCbKqrurFo9onSaT7zGT1i3u3j7LKhVZF5sJA39WPN/86'/1'/0'/0/*)#40hv8z77\n")])])]),e("p",[t._v("Now, we will generate 10 addresses using "),e("code",[t._v("bitcoin-cli")]),t._v(" and thereafter "),e("code",[t._v("bdk-cli")]),t._v(" using this above descriptor.\nNotice how both of them output the same set of addresses.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Generation via bdk-cli")]),t._v("\nrepeat "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-n")]),t._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--descriptor")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$EX_DESC")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-w")]),t._v(" mywallet get_new_address "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".address"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nbcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp\nbcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur\nbcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez\nbcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99\nbcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv\nbcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy\nbcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j\nbcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp\nbcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67\nbcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Generation via bitcoin-cli")]),t._v("\nrepeat "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-rpcwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mywallet"')]),t._v(" getnewaddress "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nbcrt1qc9wzxf8pthyexl00m23ug92pqrthagnzzf33wp\nbcrt1qgnh7e72q92fqujwg3qxlg5kplxkm6rep0nerur\nbcrt1qea6r8yvd0peupk29p94wm0xasvydgdsnyzkhez\nbcrt1qm99230tpqflq0f8kpkn5d2tee02hgqcsw5sd99\nbcrt1qd0afjfnl5udrsfkrj72rl34pss34yluma752qv\nbcrt1qj2aymplrzxcp4m7vcxrzq93g58pmgm4fpluesy\nbcrt1q4p4k63xglftez0h8yc7d4kmhsn5j5kecguu34j\nbcrt1q29z2uanskweur7qrzr43gyv3l028s0pnd9ptvp\nbcrt1qkzpeqz8sd73sucfythjxftez0e3ee30yhp9w67\nbcrt1qptwd6ggy8ttryck2f6yjf4la68apruc3fs7elz\n")])])]),e("p",[t._v("Notes:")]),t._v(" "),e("ul",[e("li",[t._v("The "),e("code",[t._v("repeat n {}")]),t._v(" syntax will only work in "),e("code",[t._v("zsh")]),t._v(", you can use other loops for your shell, or just manually repeat the code 10 times.")]),t._v(" "),e("li",[t._v("In case you get different outputs in either of the cases, try deleting "),e("code",[t._v("~/.bdk-bitcoin")]),t._v(" and retrying (thanks "),e("a",{attrs:{href:"https://twitter.com/notmandatory",target:"_blank",rel:"noopener noreferrer"}},[t._v("@Steve"),e("OutboundLink")],1),t._v(" for this tip!)")])]),t._v(" "),e("p",[t._v("Note that both "),e("code",[t._v("bdk-cli")]),t._v(" and "),e("code",[t._v("bitcoin-cli")]),t._v(" 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!")]),t._v(" "),e("h3",{attrs:{id:"making-a-multisig-descriptor-for-funds"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#making-a-multisig-descriptor-for-funds"}},[t._v("#")]),t._v(" Making a MultiSig Descriptor for Funds")]),t._v(" "),e("p",[t._v("In the real-life, most of us hold two kinds of savings accounts - one to store huge funds saved throughout our lifetime "),e("em",[t._v("(probably without internet banking functionalities)")]),t._v("\nand another for regular expenses.")]),t._v(" "),e("p",[t._v("In the Bitcoin world, to store huge funds, most people prefer to use a Multisig descriptor with a "),e("code",[t._v("2-of-3")]),t._v(" or "),e("code",[t._v("3-of-4")]),t._v(" setup.\nThey 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.\nIn 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.")]),t._v(" "),e("p",[t._v("Here's how a secure "),e("code",[t._v("2-of-3")]),t._v(" descriptor generation would look like:")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xprv generation")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K2_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K3_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xpub generation")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $K1_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K2_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $K2_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K3_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $K3_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Descriptors for each key - Since we used BIP-84 generation paths for xpubs,")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# we need to append the same to the xprvs so that our wallet can understand ")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# which path to generate addresses and xpubs from")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wsh(multi(2,'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_XPRV")]),t._v("/84'/1'/0'/0/*,"),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K2_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K3_XPUB")]),t._v('))"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K2_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wsh(multi(2,'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K2_XPRV")]),t._v("/84'/1'/0'/0/*,"),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K3_XPUB")]),t._v('))"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K3_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wsh(multi(2,'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K2_XPUB")]),t._v(","),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K3_XPRV")]),t._v("/84'/1'/0'/0/*))\"")]),t._v("\n")])])]),e("p",[t._v("Lets create three bdk wallets aliases with above descriptors for easy future use\nand do initial sync to create the wallet files")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("k1wallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w K1 -d $K1_DESC'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("k2wallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w K2 -d $K2_DESC'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("k3wallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w K3 -d $K3_DESC'")]),t._v("\n\nk1wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk2wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk3wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Now, let us send some funds to an address generated by "),e("code",[t._v("k1wallet")]),t._v(".")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('# ask regtest to generate 101 blocks, so we get 50 regtest coins to play with.\n# because coinbase amounts are only spendable after 100 blocks, we generate\n# 101 blocks, to use the first block\'s coinbase amount.\nCORE_ADDR=$(bitcoin-cli getnewaddress)\nbitcoin-cli generatetoaddress 101 $CORE_ADDR\nbitcoin-cli getbalance\n50.00000000\n\n# And then send 10 btc to an address generated by `K1` descriptor\nBDK_ADDR=$(k1wallet get_new_address | jq -r ".address")\nbitcoin-cli -rpcwallet=mywallet sendtoaddress $BDK_ADDR 10\n\n# Confirm the transaction by creating one more block\nbitcoin-cli generatetoaddress 1 $CORE_ADDR\n')])])]),e("p",[t._v("Now sync the wallets and check balances in each")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[t._v("k1wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk1wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nk2wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk2wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nk3wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nk3wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Everyone has the same amount of balance.\nThis happened because it was a multisig wallet.\nNow, let's try to spend some balance.\nWe will give back some balance to the wallet maintained by "),e("code",[t._v("bitcoin-cli")]),t._v(".\nBut remember, this is a "),e("code",[t._v("2-of-3")]),t._v(" multisig wallet.\nThat's why we will need at least two keys to sign to make a transaction.")]),t._v(" "),e("p",[t._v("Here's where we will require to use a "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("PSBT"),e("OutboundLink")],1),t._v(" or a "),e("em",[t._v("partially signed bitcoin transaction")]),t._v(".\nBitcoin uses PSBTs as the standard protocol to create a transaction and add one or more signatures to it before broadcasting the same to\nthe network which finally can become a proper valid "),e("em",[t._v("transaction")]),t._v(".")]),t._v(" "),e("p",[t._v("We will aks "),e("code",[t._v("k2wallet")]),t._v(" to create and sign the transaction then "),e("code",[t._v("k1wallet")]),t._v(" and "),e("code",[t._v("k3wallet")]),t._v(" will co-sign it.\nNote that "),e("code",[t._v("k2wallet")]),t._v(" even if it creates the transaction, doesn't need to sign it, because its a "),e("code",[t._v("2-of-3")]),t._v(" multisig!")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# create the transaction, can be started by anyone")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("k2wallet create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--to")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v(':100000000"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sign the transaction by K1 and look at the output")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# it should say the psbt is not finalized since only one party has signed")]),t._v("\nk1wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"is_finalized"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" false,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"[...]"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Saving the PSBT signed by K1")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("K1_SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("k1wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sign by K3 - should be finalized this time")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Notice that this time, the input psbt was the signed PSBT of K1")]),t._v("\nk3wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$K1_SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"is_finalized"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" true,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"psbt"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"[...]"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Saving the PSBT signed by K3")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("k3wallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $K1_SIGNED_PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Broadcast the transaction, again doesn't really matter who broadcasts")]),t._v("\nk2wallet broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"49e2706fc73c49605692bf1b9ce58baf1eb0307ea39b3118628994fd56c9b642"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Confirm the transaction by generating one block")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sync and check balance - it should have gone down by 100000000 + tx fees")]),t._v("\nk1wallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\nk1wallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("899999810")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Check similarly for `k2wallet` and `k3wallet` and they should all have same balance")]),t._v("\n")])])]),e("p",[t._v("So this proves we can definitely do transactions with multisig wallets with complicated descriptors.\nSince for Bitcoin, having keys equal having access to the accounts, we need to keep our keys safe.\nFor legacy single key wallets, we used to keep backups of the mnemonic codes in multiple places.\nIt was pretty insecure because in case any one of those backups leaks, our entire account would be compromised.\nComplicated 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.")]),t._v(" "),e("p",[t._v("Another problem with multisig was syncing between wallets to always create consistent addresses. How would\none wallet know whats the next address to create without talking to other wallets? The answer is "),e("code",[t._v("descriptors + PSBT")]),t._v(".\nIf all the wallet shares the correct descriptor string they will always create the exact sequence of addresses and\nby 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.")]),t._v(" "),e("h2",{attrs:{id:"retention-bonus-smart-contract-with-bitcoin"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#retention-bonus-smart-contract-with-bitcoin"}},[t._v("#")]),t._v(" Retention Bonus - Smart Contract with Bitcoin")]),t._v(" "),e("p",[t._v("Let us consider that a company wants to give its employees a retention bonus for two months.\nIf an employee stays with that company for over 2 months, the employee would get 1 BTC as a reward.\nThis would be a smart contract between the company and an employee.\nThe employee should be able to see that he would get his funds after two months.\nThe company would require confidence that the employee would not be able to withdraw the reward before two months have passed.")]),t._v(" "),e("p",[t._v("The Miniscript policy for this contract would be as follows:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("or(99@and(pk(E),older(8640)),pk(C))\n")])])]),e("p",[t._v("where "),e("code",[t._v("E")]),t._v(" is the employee and "),e("code",[t._v("C")]),t._v(" is the company.")]),t._v(" "),e("p",[t._v("I should emphasize over here that this policy will let the company still transfer funds after the designated 2 months.\nIt's not possible to block them after the lock time has passed, atleast not in a single policy.")]),t._v(" "),e("p",[t._v("Surely, after two months, the funds can be unlocked by the employee but before that, the company can revoke the funds.\nLet us compile this policy down to a descriptor. And this time we will ask help from the "),e("code",[t._v("miniscript")]),t._v(" program.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# The Descriptor will be on the log, the E and C are placeholders")]),t._v("\nminiscriptc "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"or(99@and(pk(E),older(8640)),pk(C))"')]),t._v(" sh-wsh\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2021")]),t._v("-08-05T12:25:40Z INFO miniscriptc"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" Compiling policy: or"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("99")]),t._v("@and"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",older"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8640")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v(",pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2021")]),t._v("-08-05T12:25:40Z INFO miniscriptc"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". Descriptor: sh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wsh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("andor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",older"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8640")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#55wzucxa")]),t._v("\nError: Descriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Miniscript"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Unexpected"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Key too short (<66 char), doesn\'t match any format"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("So the compiled descriptor is")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("sh(wsh(andor(pk(E),older(8640),pk(C))))\n")])])]),e("p",[t._v("Let's make the keys, generate addresses using the above descriptor and fund it.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xprvs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_XPRV")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xprv"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# xpubs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $E_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_XPUB")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--xprv")]),t._v(" $C_XPRV "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--path")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"m/84'/1'/0'/0\"")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".xpub"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# descriptors using the compiled miniscript")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# please note in case company or the employee was using a complicated multisig descriptor,")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# it may as well have been added here like we did in the example before")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sh(wsh(andor(pk('),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$E_XPRV")]),t._v("/84'/1'/0'/0/*),older(8640),pk("),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$C_XPUB")]),t._v('))))"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_DESC")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sh(wsh(andor(pk('),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$E_XPUB")]),t._v("),older(8640),pk("),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$C_XPRV")]),t._v("/84'/1'/0'/0/*))))\"")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Create wallet aliases for easy access and sync the wallet to create initial wallet files")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("Cwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w C -d $C_DESC'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("alias")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("Ewallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-cli -n regtest wallet -w E -d $E_DESC'")]),t._v("\n\nCwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nEwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# get some funds in Cwallet's address")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("C_ADDR")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Cwallet get_new_address "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".address"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\nbitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-rpcwallet")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("mywallet sendtoaddress "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$C_ADDR")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Confirm the transaction")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sync and check balance")]),t._v("\nCwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nCwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Just as before, the employe can also see the fund in their wallet")]),t._v("\nEwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nEwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000000")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("According to the spending policy, for "),e("code",[t._v("E")]),t._v(" has to wait for 8640 blocks before he can spend the coins.\nBut let's check what happens if "),e("code",[t._v("E")]),t._v(" tries to transact before the designated 2 months anyway.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# address to send the transaction to")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("E_ADDR")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet getnewaddress "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".address"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# get external_policy id - this identifies which policy the wallet will try to sign against")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("POLICY_ID")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet policies "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".external | .id"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# create the tx (external_policy id from last step in my case is j7ncy3au")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--to")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$E_ADDR")]),t._v(':100000000"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--external_policy")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$POLICY_ID")]),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(':[0]}"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# sign and save the signed psbt")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# now let's try to broadcast - and see it failing")]),t._v("\nEwallet broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2021")]),t._v("-08-05T17:48:45Z ERROR bdk_cli"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" Electrum"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Protocol"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Object"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"code"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" Number"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(", "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"message"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" String"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sendrawtransaction RPC error: {'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("code"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":-26,"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("message"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(":"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v("non-BIP68-final"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v('}"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("We get an error saying the transaction we sent is "),e("strong",[t._v("Not BIP68 Final")]),t._v(".\n"),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP68"),e("OutboundLink")],1),t._v(" 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.\nSo that's an expected error.")]),t._v(" "),e("p",[t._v("Now let's simulate two months passing and retry.")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# simulate two months")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# this will take around 1 mins to complete")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8640")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# create, sign and broadcast tx")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--to")]),t._v(" $E_ADDR:100000000 "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--external_policy")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{'),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$POLICY_ID")]),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(':[0]}"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("SIGNED_PSBT")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),t._v("Ewallet sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" $PSBT "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-r")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".psbt"')]),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\nEwallet broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--psbt")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$SIGNED_PSBT")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2a0919bb3ce6e26018698ad1169965301a9ceab6d3da2a3dcb41343dc48e0dba"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Confirm the transaction")]),t._v("\nbitcoin-cli generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CORE_ADDR")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Sync and check balances")]),t._v("\nCwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nCwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("999999810")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nEwallet "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nEwallet get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("999999810")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("So this time it worked, because we have simulated 2 months passing by generating 8640 blocks. And both the Company\nand Employe wallet gets updated.\nHence, we saw that we can generate some smart contracts using Bitcoin.")]),t._v(" "),e("h2",{attrs:{id:"inspirations"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#inspirations"}},[t._v("#")]),t._v(" Inspirations")]),t._v(" "),e("ol",[e("li",[e("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Descriptors from Bitcoin Core"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript",target:"_blank",rel:"noopener noreferrer"}},[t._v("Miniscript"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoinops.org/en/topics/output-script-descriptors",target:"_blank",rel:"noopener noreferrer"}},[t._v("Output Script Descriptors"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoindevkit.org/descriptors",target:"_blank",rel:"noopener noreferrer"}},[t._v("Descriptors in Bitcoin Dev Kit"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/#the-role-of-descriptors",target:"_blank",rel:"noopener noreferrer"}},[t._v("Role of Descriptors"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://gist.github.com/notmandatory/483c7edd098550c235da75d5babcf255",target:"_blank",rel:"noopener noreferrer"}},[t._v("Making a Taproot Descriptor Wallet using bitcoin-cli"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=XM1lzN4Zfks",target:"_blank",rel:"noopener noreferrer"}},[t._v("Miniscripts SBC '19 - Video"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=xC25NzIjzog",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rethinking Wallet Architecture: Native Descriptor Wallets - Video"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("Special thanks to my mentor "),e("a",{attrs:{href:"https://twitter.com/notmandatory",target:"_blank",rel:"noopener noreferrer"}},[t._v("Steve Myers"),e("OutboundLink")],1),t._v(" for the constant motivation and support he gave me and for clearing so many doubts!\nImmense thanks to "),e("a",{attrs:{href:"https://github.com/rajarshimaitra",target:"_blank",rel:"noopener noreferrer"}},[t._v("Raj"),e("OutboundLink")],1),t._v(" for reviewing this blog and giving such detailed suggestions.\nMany of the lines added here are his.\nAlso, thanks to the folks at the "),e("code",[t._v("#miniscript")]),t._v(" IRC channel to help me out with the Retention Bonus policy.")]),t._v(" "),e("p",[t._v("This blog was written during "),e("a",{attrs:{href:"https://summerofbitcoin.org",target:"_blank",rel:"noopener noreferrer"}},[t._v("Summer of Bitcoin 2021"),e("OutboundLink")],1),t._v(" by "),e("a",{attrs:{href:"https://twitter.com/@sandipndev",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sandipan Dey"),e("OutboundLink")],1),t._v(".")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/69.c92f69ce.js b/assets/js/69.3d319207.js similarity index 99% rename from assets/js/69.c92f69ce.js rename to assets/js/69.3d319207.js index 84c34e9a16..650678ff8e 100644 --- a/assets/js/69.c92f69ce.js +++ b/assets/js/69.3d319207.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[69],{426:function(t,a,e){"use strict";e.r(a);var s=e(7),n=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("p",[t._v("A new release of BDK is finally out! The "),a("code",[t._v("v0.2.0")]),t._v(" release contains many exciting new features, bug fixes and overall improvements. This release also marks the beginning of our new regular "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/7d6cd6d4f5a26194830f90e6460e0b82bddf9594/DEVELOPMENT_CYCLE.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("release schedule"),a("OutboundLink")],1),t._v(", which will see us pushing\nout a new release every four weeks. We think this is a good compromise to ensure that developers using BDK have access to all the new features and fixes as soon as possible, at least while the library is still evolving very fast as it is\nright now. After "),a("code",[t._v("v1.0.0")]),t._v(" we will increase this time to a more relaxed 6 weeks.")]),t._v(" "),a("p",[t._v("You can find the full "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/7d6cd6d4f5a26194830f90e6460e0b82bddf9594/CHANGELOG.md#v020---010-beta1",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.2.0 changelog"),a("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),a("h2",{attrs:{id:"whats-new-in-v020"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v020"}},[t._v("#")]),t._v(" What's new in v0.2.0")]),t._v(" "),a("p",[t._v("Considering the sheer amount of new things being added we don't have room here to explain every new feature in detail, but below is a quick overview of some you could find useful in your projects.")]),t._v(" "),a("h3",{attrs:{id:"a-new-name"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#a-new-name"}},[t._v("#")]),t._v(" A new name")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("0.1.0-beta.1")]),t._v(" release was tagged right before the project was renamed "),a("code",[t._v("bdk")]),t._v(': at that time the library was still called "Magical Bitcoin Library", or '),a("code",[t._v("magical")]),t._v(" for short. With this release we have now renamed it to "),a("code",[t._v("bdk")]),t._v(". If you were using the library\nbefore, it should only be a matter of renaming the imports to match the new name. Alternatively you can also rename "),a("code",[t._v("bdk")]),t._v(" to "),a("code",[t._v("magical")]),t._v(" in your Cargo.toml, but you'll still have to do some changes here and there because the APIs have been changed in a few\nplaces.")]),t._v(" "),a("p",[t._v("This release being particularly large contains a few different API-breaking changes: going forward we expect to make the interface more and more stable, which in turn will make applying updates easier.")]),t._v(" "),a("h3",{attrs:{id:"branch-and-bound-coin-selection"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#branch-and-bound-coin-selection"}},[t._v("#")]),t._v(" Branch and Bound coin selection")]),t._v(" "),a("p",[t._v('We now support the state-of-the-art coin selection algorithm called "branch and bound", with an implementation derived straight from Bitcoin Core. This algorithm is now enabled by default, but it can be replaced with a different one (either\nthe old default, '),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/coin_selection/struct.LargestFirstCoinSelection.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("LargestFirstCoinSelection")]),a("OutboundLink")],1),t._v(" or a custom "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("CoinSelectionAlgorithm")]),a("OutboundLink")],1),t._v(") by using the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/tx_builder/struct.TxBuilder.html#method.coin_selection",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("TxBuilder::coin_selection()")]),a("OutboundLink")],1),t._v(" option.")]),t._v(" "),a("p",[t._v("Branch and bound works by trying to find a set of inputs that perfectly matches the amount being sent by a transaction, to avoid making an extra change output which takes up more space in the transaction, requires more fees, and in general lowers the privacy\nof a user if the change is later spent together with other outputs.")]),t._v(" "),a("h3",{attrs:{id:"key-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#key-generation"}},[t._v("#")]),t._v(" Key generation")]),t._v(" "),a("p",[t._v("If you need to generate a new "),a("code",[t._v("bip32::ExtendedPrivKey")]),t._v(", or perhaps a new BIP39 mnemonic, you can use the unified "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.GeneratableKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GeneratableKey")]),a("OutboundLink")],1),t._v(" trait to do so: paired with "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.GeneratableDefaultOptions.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GeneratableDefaultOptions")]),a("OutboundLink")],1),t._v(" they provide many different ways to generate keys,\nwith or without a custom source of entropy, and with or without customized options.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableDefaultOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKeyGenerateOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" default_options_key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" custom_options_key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKeyGenerateOptions")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" compressed"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"generic-key-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#generic-key-types"}},[t._v("#")]),t._v(" Generic key types")]),t._v(" "),a("p",[t._v("With this update there's now a generalized trait for keys that can be used in descriptors, which is called "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ToDescriptorKey")]),a("OutboundLink")],1),t._v(". This trait is already implemented for the native "),a("code",[t._v("rust-bitcoin")]),t._v(" key types, like "),a("code",[t._v("PrivateKey")]),t._v(", "),a("code",[t._v("PublicKey")]),t._v(", "),a("code",[t._v("bip32::ExtendedPrivKey")]),t._v("\nand "),a("code",[t._v("bip32::ExtendedPubKey")]),t._v(". It's also implemented for BIP39 mnemonic and seeds, when the the opt-in "),a("code",[t._v("keys-bip39")]),t._v(" feature is enabled. As always, being this a public trait, you can also implement it for custom types to better suit your needs.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScriptContext")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ToDescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyKeyType")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("to_descriptor_key")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Custom conversion to `bitcoin::PrivateKey`")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" privkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n privkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_descriptor_key")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("If your custom key type is simply a different representation of an "),a("code",[t._v("xprv")]),t._v(" or "),a("code",[t._v("xpub")]),t._v(", you can also consider implementing the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.DerivableKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("DerivableKey")]),a("OutboundLink")],1),t._v(" trait instead: for a type "),a("code",[t._v("K")]),t._v(" that implements "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.DerivableKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("DerivableKey")]),a("OutboundLink")],1),t._v(", the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ToDescriptorKey")]),a("OutboundLink")],1),t._v(" trait is automatically\nimplemented for the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html#impl-ToDescriptorKey%3CCtx%3E-for-(T%2C%20DerivationPath)",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("(K, bip32::DerivationPath)")]),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html#impl-ToDescriptorKey%3CCtx%3E-for-(T%2C%20KeySource%2C%20DerivationPath)",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("(K, bip32::KeySource, bip32::DerivationPath)")]),a("OutboundLink")],1),t._v(" tuples.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScriptContext")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivableKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyKeyType")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("add_metadata")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n derivation_path"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Custom conversion to `bip32::ExtendedPrivKey`")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n xprv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_metadata")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" derivation_path"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h3",{attrs:{id:"descriptor-templates"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#descriptor-templates"}},[t._v("#")]),t._v(" Descriptor templates")]),t._v(" "),a("p",[t._v("Instead of having to serialize keys to strings using "),a("code",[t._v("format!()")]),t._v(" just to place them somewhere inside a descriptor, you can now use descriptor templates to build a descriptor starting from a key and some other options\nin a couple of lines of code. You can use one of the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/descriptor/template/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("provided templates"),a("OutboundLink")],1),t._v(" or make a custom one by implementing the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/descriptor/template/trait.DescriptorTemplate.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("DescriptorTemplate")]),a("OutboundLink")],1),t._v(" trait on a "),a("code",[t._v("struct")]),t._v(" or "),a("code",[t._v("enum")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"..."')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OfflineWallet")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_offline")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BIP84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BIP84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Internal")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"easier-creation-of-blockchain-and-database"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#easier-creation-of-blockchain-and-database"}},[t._v("#")]),t._v(" Easier creation of "),a("code",[t._v("Blockchain")]),t._v(" and "),a("code",[t._v("Database")])]),t._v(" "),a("p",[t._v("We've added a new way to create a "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" instance from a configuration, with the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.ConfigurableBlockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ConfigurableBlockchain")]),a("OutboundLink")],1),t._v(" trait. All the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" types provided by the library implement this trait, which allows you to easily build an\ninstance of them starting from a configuration "),a("code",[t._v("struct")]),t._v(": moreover, the configuration structures implement "),a("code",[t._v("Serialize")]),t._v(" and "),a("code",[t._v("Deserialize")]),t._v(", so that they can be easily stored/loaded using "),a("code",[t._v("serde")]),t._v(".")]),t._v(" "),a("p",[t._v("We've also added a new "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" type called "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/any/enum.AnyBlockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("AnyBlockchain")]),a("OutboundLink")],1),t._v(", which is essentially an "),a("code",[t._v("enum")]),t._v(" that wraps all the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" types exposed by the library. This allows you to build a "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/struct.Wallet.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet")]),a("OutboundLink")],1),t._v(" that always has the same\nRust type, but that can internally use different "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" backends chosen at runtime.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnyBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnyBlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('r#"{"Electrum":{"url":"ssl://electrum.blockstream.info:50002","socks5":null,"retry":3,"timeout":5}}"#')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("serde_json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnyBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The same is true for "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/database/trait.Database.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Database")]),a("OutboundLink")],1),t._v(" types, thanks to the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/database/trait.ConfigurableDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ConfigurableDatabase")]),a("OutboundLink")],1),t._v(" trait and the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/database/any/enum.AnyDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("AnyDatabase")]),a("OutboundLink")],1),t._v(" "),a("code",[t._v("enum")]),t._v(". While we think most people generally prefer to choose a single database type and then stick to it, it's still good\nto offer the choice to switch them at runtime, should somebody need that.")]),t._v(" "),a("h3",{attrs:{id:"descriptor-macro"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#descriptor-macro"}},[t._v("#")]),t._v(" "),a("code",[t._v("descriptor!()")]),t._v(" macro")]),t._v(" "),a("p",[t._v("If you start writing complex descriptor templates, you'll soon find yourself with the need of building large descriptor syntax trees: you can very easily do that with the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/macro.descriptor.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("descriptor!()")]),a("OutboundLink")],1),t._v(" macro, with the added bonus that some additional checks on the\nsyntax of your descriptor will be performed at compile-time, rather than at runtime by. You can use any type that implements "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ToDescriptorKey")]),a("OutboundLink")],1),t._v(" (even strings!) as keys in "),a("code",[t._v("pk()")]),t._v(", "),a("code",[t._v("multi()")]),t._v(" and "),a("code",[t._v("sortedmulti()")]),t._v(" fragments, and you can even mix\nthem in the same descriptor.")]),t._v(" "),a("p",[t._v("The syntax supported by the macro is almost exactly the same as the standard descriptor syntax we all know, with the only difference that modifiers should be specified individually rather than\ngrouped in a series of characters (see the example below).")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("TimeDecayingMultisig")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n pk_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n pk_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timelock"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ToDescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplate")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TimeDecayingMultisig")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplateOut")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("descriptor!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("wsh")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("thresh")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("d"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("v"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("older")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timelock"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map_err")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token closure-params"}},[a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Message")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h3",{attrs:{id:"support-for-sortedmulti"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#support-for-sortedmulti"}},[t._v("#")]),t._v(" Support for "),a("code",[t._v("sortedmulti()")])]),t._v(" "),a("p",[t._v("Thanks to the addition of "),a("code",[t._v("sortedmulti()")]),t._v(" in "),a("code",[t._v("rust-miniscript")]),t._v(", we can now also support them in BDK, which means we are getting more and more compatible with other descriptor-based wallets out there like Bitcoin Core.")]),t._v(" "),a("h2",{attrs:{id:"contributors"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),a("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),a("p",[t._v("Since the "),a("code",[t._v("0.1.0-beta.1")]),t._v(" release over three months ago, we've had "),a("code",[t._v("213")]),t._v(" new commits made by "),a("code",[t._v("10")]),t._v(" different contributors for a total of "),a("code",[t._v("9990")]),t._v(" additions and "),a("code",[t._v("2993")]),t._v(" deletions. Here's the "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/0.1.0-beta.1...v0.2.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("p",[t._v("A special thanks to the "),a("code",[t._v("7")]),t._v(" new contributors:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/eupn",target:"_blank",rel:"noopener noreferrer"}},[t._v("@eupn"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/justinmoon",target:"_blank",rel:"noopener noreferrer"}},[t._v("@justinmoon"),a("OutboundLink")],1),t._v(" - Justin Moon")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/Xekyo",target:"_blank",rel:"noopener noreferrer"}},[t._v("@Xekyo"),a("OutboundLink")],1),t._v(" - Mark Erhardt")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/RCasatta",target:"_blank",rel:"noopener noreferrer"}},[t._v("@RCasatta"),a("OutboundLink")],1),t._v(" - Riccardo Casatta")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/ulrichard",target:"_blank",rel:"noopener noreferrer"}},[t._v("@ulrichard"),a("OutboundLink")],1),t._v(" - Richard Ulrich")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/notmandatory",target:"_blank",rel:"noopener noreferrer"}},[t._v("@notmandatory"),a("OutboundLink")],1),t._v(" - Steve Myers")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/willcl-ark",target:"_blank",rel:"noopener noreferrer"}},[t._v("@willcl-ark"),a("OutboundLink")],1),t._v(" - Will Clark")])])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[69],{427:function(t,a,e){"use strict";e.r(a);var s=e(7),n=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("p",[t._v("A new release of BDK is finally out! The "),a("code",[t._v("v0.2.0")]),t._v(" release contains many exciting new features, bug fixes and overall improvements. This release also marks the beginning of our new regular "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/7d6cd6d4f5a26194830f90e6460e0b82bddf9594/DEVELOPMENT_CYCLE.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("release schedule"),a("OutboundLink")],1),t._v(", which will see us pushing\nout a new release every four weeks. We think this is a good compromise to ensure that developers using BDK have access to all the new features and fixes as soon as possible, at least while the library is still evolving very fast as it is\nright now. After "),a("code",[t._v("v1.0.0")]),t._v(" we will increase this time to a more relaxed 6 weeks.")]),t._v(" "),a("p",[t._v("You can find the full "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/7d6cd6d4f5a26194830f90e6460e0b82bddf9594/CHANGELOG.md#v020---010-beta1",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.2.0 changelog"),a("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),a("h2",{attrs:{id:"whats-new-in-v020"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v020"}},[t._v("#")]),t._v(" What's new in v0.2.0")]),t._v(" "),a("p",[t._v("Considering the sheer amount of new things being added we don't have room here to explain every new feature in detail, but below is a quick overview of some you could find useful in your projects.")]),t._v(" "),a("h3",{attrs:{id:"a-new-name"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#a-new-name"}},[t._v("#")]),t._v(" A new name")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("0.1.0-beta.1")]),t._v(" release was tagged right before the project was renamed "),a("code",[t._v("bdk")]),t._v(': at that time the library was still called "Magical Bitcoin Library", or '),a("code",[t._v("magical")]),t._v(" for short. With this release we have now renamed it to "),a("code",[t._v("bdk")]),t._v(". If you were using the library\nbefore, it should only be a matter of renaming the imports to match the new name. Alternatively you can also rename "),a("code",[t._v("bdk")]),t._v(" to "),a("code",[t._v("magical")]),t._v(" in your Cargo.toml, but you'll still have to do some changes here and there because the APIs have been changed in a few\nplaces.")]),t._v(" "),a("p",[t._v("This release being particularly large contains a few different API-breaking changes: going forward we expect to make the interface more and more stable, which in turn will make applying updates easier.")]),t._v(" "),a("h3",{attrs:{id:"branch-and-bound-coin-selection"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#branch-and-bound-coin-selection"}},[t._v("#")]),t._v(" Branch and Bound coin selection")]),t._v(" "),a("p",[t._v('We now support the state-of-the-art coin selection algorithm called "branch and bound", with an implementation derived straight from Bitcoin Core. This algorithm is now enabled by default, but it can be replaced with a different one (either\nthe old default, '),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/coin_selection/struct.LargestFirstCoinSelection.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("LargestFirstCoinSelection")]),a("OutboundLink")],1),t._v(" or a custom "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("CoinSelectionAlgorithm")]),a("OutboundLink")],1),t._v(") by using the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/tx_builder/struct.TxBuilder.html#method.coin_selection",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("TxBuilder::coin_selection()")]),a("OutboundLink")],1),t._v(" option.")]),t._v(" "),a("p",[t._v("Branch and bound works by trying to find a set of inputs that perfectly matches the amount being sent by a transaction, to avoid making an extra change output which takes up more space in the transaction, requires more fees, and in general lowers the privacy\nof a user if the change is later spent together with other outputs.")]),t._v(" "),a("h3",{attrs:{id:"key-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#key-generation"}},[t._v("#")]),t._v(" Key generation")]),t._v(" "),a("p",[t._v("If you need to generate a new "),a("code",[t._v("bip32::ExtendedPrivKey")]),t._v(", or perhaps a new BIP39 mnemonic, you can use the unified "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.GeneratableKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GeneratableKey")]),a("OutboundLink")],1),t._v(" trait to do so: paired with "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.GeneratableDefaultOptions.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GeneratableDefaultOptions")]),a("OutboundLink")],1),t._v(" they provide many different ways to generate keys,\nwith or without a custom source of entropy, and with or without customized options.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("keys"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GeneratableDefaultOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKeyGenerateOptions")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" default_options_key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate_default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" custom_options_key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKeyGenerateOptions")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" compressed"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"generic-key-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#generic-key-types"}},[t._v("#")]),t._v(" Generic key types")]),t._v(" "),a("p",[t._v("With this update there's now a generalized trait for keys that can be used in descriptors, which is called "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ToDescriptorKey")]),a("OutboundLink")],1),t._v(". This trait is already implemented for the native "),a("code",[t._v("rust-bitcoin")]),t._v(" key types, like "),a("code",[t._v("PrivateKey")]),t._v(", "),a("code",[t._v("PublicKey")]),t._v(", "),a("code",[t._v("bip32::ExtendedPrivKey")]),t._v("\nand "),a("code",[t._v("bip32::ExtendedPubKey")]),t._v(". It's also implemented for BIP39 mnemonic and seeds, when the the opt-in "),a("code",[t._v("keys-bip39")]),t._v(" feature is enabled. As always, being this a public trait, you can also implement it for custom types to better suit your needs.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScriptContext")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ToDescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyKeyType")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("to_descriptor_key")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Custom conversion to `bitcoin::PrivateKey`")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" privkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PrivateKey")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n privkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_descriptor_key")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("If your custom key type is simply a different representation of an "),a("code",[t._v("xprv")]),t._v(" or "),a("code",[t._v("xpub")]),t._v(", you can also consider implementing the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.DerivableKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("DerivableKey")]),a("OutboundLink")],1),t._v(" trait instead: for a type "),a("code",[t._v("K")]),t._v(" that implements "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.DerivableKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("DerivableKey")]),a("OutboundLink")],1),t._v(", the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ToDescriptorKey")]),a("OutboundLink")],1),t._v(" trait is automatically\nimplemented for the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html#impl-ToDescriptorKey%3CCtx%3E-for-(T%2C%20DerivationPath)",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("(K, bip32::DerivationPath)")]),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html#impl-ToDescriptorKey%3CCtx%3E-for-(T%2C%20KeySource%2C%20DerivationPath)",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("(K, bip32::KeySource, bip32::DerivationPath)")]),a("OutboundLink")],1),t._v(" tuples.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScriptContext")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivableKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyKeyType")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("add_metadata")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Option")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeySource")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n derivation_path"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivationPath")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ctx")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Custom conversion to `bip32::ExtendedPrivKey`")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n xprv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_metadata")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" derivation_path"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h3",{attrs:{id:"descriptor-templates"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#descriptor-templates"}},[t._v("#")]),t._v(" Descriptor templates")]),t._v(" "),a("p",[t._v("Instead of having to serialize keys to strings using "),a("code",[t._v("format!()")]),t._v(" just to place them somewhere inside a descriptor, you can now use descriptor templates to build a descriptor starting from a key and some other options\nin a couple of lines of code. You can use one of the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/descriptor/template/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("provided templates"),a("OutboundLink")],1),t._v(" or make a custom one by implementing the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/descriptor/template/trait.DescriptorTemplate.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("DescriptorTemplate")]),a("OutboundLink")],1),t._v(" trait on a "),a("code",[t._v("struct")]),t._v(" or "),a("code",[t._v("enum")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" key "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"..."')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OfflineWallet")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_offline")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BIP84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BIP84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Internal")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h3",{attrs:{id:"easier-creation-of-blockchain-and-database"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#easier-creation-of-blockchain-and-database"}},[t._v("#")]),t._v(" Easier creation of "),a("code",[t._v("Blockchain")]),t._v(" and "),a("code",[t._v("Database")])]),t._v(" "),a("p",[t._v("We've added a new way to create a "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" instance from a configuration, with the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.ConfigurableBlockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ConfigurableBlockchain")]),a("OutboundLink")],1),t._v(" trait. All the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" types provided by the library implement this trait, which allows you to easily build an\ninstance of them starting from a configuration "),a("code",[t._v("struct")]),t._v(": moreover, the configuration structures implement "),a("code",[t._v("Serialize")]),t._v(" and "),a("code",[t._v("Deserialize")]),t._v(", so that they can be easily stored/loaded using "),a("code",[t._v("serde")]),t._v(".")]),t._v(" "),a("p",[t._v("We've also added a new "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" type called "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/any/enum.AnyBlockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("AnyBlockchain")]),a("OutboundLink")],1),t._v(", which is essentially an "),a("code",[t._v("enum")]),t._v(" that wraps all the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" types exposed by the library. This allows you to build a "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/wallet/struct.Wallet.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Wallet")]),a("OutboundLink")],1),t._v(" that always has the same\nRust type, but that can internally use different "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Blockchain")]),a("OutboundLink")],1),t._v(" backends chosen at runtime.")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnyBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnyBlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('r#"{"Electrum":{"url":"ssl://electrum.blockstream.info:50002","socks5":null,"retry":3,"timeout":5}}"#')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("serde_json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AnyBlockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The same is true for "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/database/trait.Database.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("Database")]),a("OutboundLink")],1),t._v(" types, thanks to the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/database/trait.ConfigurableDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ConfigurableDatabase")]),a("OutboundLink")],1),t._v(" trait and the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/database/any/enum.AnyDatabase.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("AnyDatabase")]),a("OutboundLink")],1),t._v(" "),a("code",[t._v("enum")]),t._v(". While we think most people generally prefer to choose a single database type and then stick to it, it's still good\nto offer the choice to switch them at runtime, should somebody need that.")]),t._v(" "),a("h3",{attrs:{id:"descriptor-macro"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#descriptor-macro"}},[t._v("#")]),t._v(" "),a("code",[t._v("descriptor!()")]),t._v(" macro")]),t._v(" "),a("p",[t._v("If you start writing complex descriptor templates, you'll soon find yourself with the need of building large descriptor syntax trees: you can very easily do that with the "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/macro.descriptor.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("descriptor!()")]),a("OutboundLink")],1),t._v(" macro, with the added bonus that some additional checks on the\nsyntax of your descriptor will be performed at compile-time, rather than at runtime by. You can use any type that implements "),a("a",{attrs:{href:"https://docs.rs/bdk/0.2.0/bdk/keys/trait.ToDescriptorKey.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("ToDescriptorKey")]),a("OutboundLink")],1),t._v(" (even strings!) as keys in "),a("code",[t._v("pk()")]),t._v(", "),a("code",[t._v("multi()")]),t._v(" and "),a("code",[t._v("sortedmulti()")]),t._v(" fragments, and you can even mix\nthem in the same descriptor.")]),t._v(" "),a("p",[t._v("The syntax supported by the macro is almost exactly the same as the standard descriptor syntax we all know, with the only difference that modifiers should be specified individually rather than\ngrouped in a series of characters (see the example below).")]),t._v(" "),a("div",{staticClass:"language-rust extra-class"},[a("pre",{pre:!0,attrs:{class:"language-rust"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("TimeDecayingMultisig")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n pk_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n pk_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timelock"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ToDescriptorKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplate")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TimeDecayingMultisig")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplateOut")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("descriptor!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("wsh")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("thresh")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("d"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("v"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("older")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timelock"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map_err")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token closure-params"}},[a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeyError")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Message")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h3",{attrs:{id:"support-for-sortedmulti"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#support-for-sortedmulti"}},[t._v("#")]),t._v(" Support for "),a("code",[t._v("sortedmulti()")])]),t._v(" "),a("p",[t._v("Thanks to the addition of "),a("code",[t._v("sortedmulti()")]),t._v(" in "),a("code",[t._v("rust-miniscript")]),t._v(", we can now also support them in BDK, which means we are getting more and more compatible with other descriptor-based wallets out there like Bitcoin Core.")]),t._v(" "),a("h2",{attrs:{id:"contributors"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),a("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),a("p",[t._v("Since the "),a("code",[t._v("0.1.0-beta.1")]),t._v(" release over three months ago, we've had "),a("code",[t._v("213")]),t._v(" new commits made by "),a("code",[t._v("10")]),t._v(" different contributors for a total of "),a("code",[t._v("9990")]),t._v(" additions and "),a("code",[t._v("2993")]),t._v(" deletions. Here's the "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/0.1.0-beta.1...v0.2.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("p",[t._v("A special thanks to the "),a("code",[t._v("7")]),t._v(" new contributors:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/eupn",target:"_blank",rel:"noopener noreferrer"}},[t._v("@eupn"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/justinmoon",target:"_blank",rel:"noopener noreferrer"}},[t._v("@justinmoon"),a("OutboundLink")],1),t._v(" - Justin Moon")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/Xekyo",target:"_blank",rel:"noopener noreferrer"}},[t._v("@Xekyo"),a("OutboundLink")],1),t._v(" - Mark Erhardt")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/RCasatta",target:"_blank",rel:"noopener noreferrer"}},[t._v("@RCasatta"),a("OutboundLink")],1),t._v(" - Riccardo Casatta")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/ulrichard",target:"_blank",rel:"noopener noreferrer"}},[t._v("@ulrichard"),a("OutboundLink")],1),t._v(" - Richard Ulrich")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/notmandatory",target:"_blank",rel:"noopener noreferrer"}},[t._v("@notmandatory"),a("OutboundLink")],1),t._v(" - Steve Myers")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/willcl-ark",target:"_blank",rel:"noopener noreferrer"}},[t._v("@willcl-ark"),a("OutboundLink")],1),t._v(" - Will Clark")])])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/70.4663d7b0.js b/assets/js/70.3bb83c63.js similarity index 99% rename from assets/js/70.4663d7b0.js rename to assets/js/70.3bb83c63.js index 181773c3fa..afdc70c873 100644 --- a/assets/js/70.4663d7b0.js +++ b/assets/js/70.3bb83c63.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[70],{427:function(t,s,e){"use strict";e.r(s);var a=e(7),n=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("p",[t._v("A new release of BDK is out: the "),s("a",{attrs:{href:"https://crates.io/crates/bdk/0.3.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.3.0")]),s("OutboundLink")],1),t._v(" is a relatively small update compared to "),s("code",[t._v("v0.2.0")]),t._v(", but it still brings some nice APIs improvements and general bugfixes.")]),t._v(" "),s("p",[t._v("You can find the full "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/75669049268bbc294564f8c6e0528e07a546258f/CHANGELOG.md#v030---v020",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.3.0 changelog"),s("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),s("h2",{attrs:{id:"whats-new-in-v030"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v030"}},[t._v("#")]),t._v(" What's new in v0.3.0")]),t._v(" "),s("p",[t._v("Below are some highlights of the new improved APIs coming with this release:")]),t._v(" "),s("h3",{attrs:{id:"less-verbosity-when-using-walletnew-offline"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#less-verbosity-when-using-walletnew-offline"}},[t._v("#")]),t._v(" Less verbosity when using "),s("code",[t._v("Wallet::new_offline()")])]),t._v(" "),s("p",[t._v("Now you don't have to explicitly provide the "),s("code",[t._v("OfflineWallet<_>")]),t._v(" type anymore, saving you one import and making it much less verbose to use.")]),t._v(" "),s("p",[t._v("Where before you were doing:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OfflineWallet")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_offline")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Now you can just write:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_offline")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"no-more-error-conversions-in-descriptortemplate"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#no-more-error-conversions-in-descriptortemplate"}},[t._v("#")]),t._v(" No more error conversions in "),s("code",[t._v("DescriptorTemplate")])]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("DescriptorTemplate")]),t._v(" trait has been updated to return a "),s("a",{attrs:{href:"https://docs.rs/bdk/0.3.0/bdk/descriptor/error/enum.Error.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("descriptor::error::Error")]),s("OutboundLink")],1),t._v(" instead of a "),s("code",[t._v("KeyError")]),t._v(". The "),s("a",{attrs:{href:"https://docs.rs/bdk/0.3.0/bdk/macro.descriptor.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("descriptor!()")]),s("OutboundLink")],1),t._v(" macro has been updated as well, which means that now you can use the macro inside a "),s("code",[t._v("DescriptorTemplate::build()")]),t._v(" implementation\nwithout having to "),s("RouterLink",{attrs:{to:"/blog/2020/12/release-v0.2.0/#descriptor-macro"}},[t._v("map the error")]),t._v(", like so:")],1),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("TimeDecayingMultisig")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n pk_a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n pk_b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timelock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ToDescriptorKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplate")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TimeDecayingMultisig")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplateOut")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("descriptor!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("wsh")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("thresh")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("d"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("v"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("older")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timelock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"a-new-repo-for-the-cli"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#a-new-repo-for-the-cli"}},[t._v("#")]),t._v(" A new repo for the CLI")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("cli")]),t._v(" module (and it's related "),s("code",[t._v("cli-utils")]),t._v(" feature) have been removed from the main BDK repo and moved to their new home, the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-cli"),s("OutboundLink")],1),t._v(" repo. The APIs exposed were mainly used internally, for the "),s("code",[t._v("repl")]),t._v(" and the "),s("a",{attrs:{href:"/bdk-cli/playground"}},[t._v("playground")]),t._v("\nin our website, but in case you were using one of those keep that in mind.")]),t._v(" "),s("h2",{attrs:{id:"contributors"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),s("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),s("p",[t._v("Since the "),s("code",[t._v("v0.2.0")]),t._v(" release around a month ago, we've had "),s("code",[t._v("24")]),t._v(" new commits made by "),s("code",[t._v("6")]),t._v(" different contributors for a total of "),s("code",[t._v("404")]),t._v(" additions and "),s("code",[t._v("1243")]),t._v(" deletions. Here's the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.2.0...v0.3.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/tcharding",target:"_blank",rel:"noopener noreferrer"}},[t._v("@tcharding"),s("OutboundLink")],1),t._v(" - Tobin C. Harding")])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[70],{426:function(t,s,e){"use strict";e.r(s);var a=e(7),n=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("p",[t._v("A new release of BDK is out: the "),s("a",{attrs:{href:"https://crates.io/crates/bdk/0.3.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.3.0")]),s("OutboundLink")],1),t._v(" is a relatively small update compared to "),s("code",[t._v("v0.2.0")]),t._v(", but it still brings some nice APIs improvements and general bugfixes.")]),t._v(" "),s("p",[t._v("You can find the full "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/75669049268bbc294564f8c6e0528e07a546258f/CHANGELOG.md#v030---v020",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.3.0 changelog"),s("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),s("h2",{attrs:{id:"whats-new-in-v030"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v030"}},[t._v("#")]),t._v(" What's new in v0.3.0")]),t._v(" "),s("p",[t._v("Below are some highlights of the new improved APIs coming with this release:")]),t._v(" "),s("h3",{attrs:{id:"less-verbosity-when-using-walletnew-offline"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#less-verbosity-when-using-walletnew-offline"}},[t._v("#")]),t._v(" Less verbosity when using "),s("code",[t._v("Wallet::new_offline()")])]),t._v(" "),s("p",[t._v("Now you don't have to explicitly provide the "),s("code",[t._v("OfflineWallet<_>")]),t._v(" type anymore, saving you one import and making it much less verbose to use.")]),t._v(" "),s("p",[t._v("Where before you were doing:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OfflineWallet")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_offline")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Now you can just write:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_offline")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"no-more-error-conversions-in-descriptortemplate"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#no-more-error-conversions-in-descriptortemplate"}},[t._v("#")]),t._v(" No more error conversions in "),s("code",[t._v("DescriptorTemplate")])]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("DescriptorTemplate")]),t._v(" trait has been updated to return a "),s("a",{attrs:{href:"https://docs.rs/bdk/0.3.0/bdk/descriptor/error/enum.Error.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("descriptor::error::Error")]),s("OutboundLink")],1),t._v(" instead of a "),s("code",[t._v("KeyError")]),t._v(". The "),s("a",{attrs:{href:"https://docs.rs/bdk/0.3.0/bdk/macro.descriptor.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("descriptor!()")]),s("OutboundLink")],1),t._v(" macro has been updated as well, which means that now you can use the macro inside a "),s("code",[t._v("DescriptorTemplate::build()")]),t._v(" implementation\nwithout having to "),s("RouterLink",{attrs:{to:"/blog/2020/12/release-v0.2.0/#descriptor-macro"}},[t._v("map the error")]),t._v(", like so:")],1),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("TimeDecayingMultisig")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n pk_a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n pk_b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timelock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("u32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ToDescriptorKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Segwitv0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplate")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TimeDecayingMultisig")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("K")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorTemplateOut")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("descriptor!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("wsh")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("thresh")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pk")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pk_b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("d"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("v"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("older")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("timelock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"a-new-repo-for-the-cli"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#a-new-repo-for-the-cli"}},[t._v("#")]),t._v(" A new repo for the CLI")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("cli")]),t._v(" module (and it's related "),s("code",[t._v("cli-utils")]),t._v(" feature) have been removed from the main BDK repo and moved to their new home, the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-cli"),s("OutboundLink")],1),t._v(" repo. The APIs exposed were mainly used internally, for the "),s("code",[t._v("repl")]),t._v(" and the "),s("a",{attrs:{href:"/bdk-cli/playground"}},[t._v("playground")]),t._v("\nin our website, but in case you were using one of those keep that in mind.")]),t._v(" "),s("h2",{attrs:{id:"contributors"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),s("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),s("p",[t._v("Since the "),s("code",[t._v("v0.2.0")]),t._v(" release around a month ago, we've had "),s("code",[t._v("24")]),t._v(" new commits made by "),s("code",[t._v("6")]),t._v(" different contributors for a total of "),s("code",[t._v("404")]),t._v(" additions and "),s("code",[t._v("1243")]),t._v(" deletions. Here's the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.2.0...v0.3.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/tcharding",target:"_blank",rel:"noopener noreferrer"}},[t._v("@tcharding"),s("OutboundLink")],1),t._v(" - Tobin C. Harding")])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/71.2a8871be.js b/assets/js/71.0e559a1c.js similarity index 99% rename from assets/js/71.2a8871be.js rename to assets/js/71.0e559a1c.js index b6fb81cfb6..421a5bdc03 100644 --- a/assets/js/71.2a8871be.js +++ b/assets/js/71.0e559a1c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[71],{428:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("p",[t._v("A new release of BDK is out: the "),s("a",{attrs:{href:"https://crates.io/crates/bdk/0.4.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.4.0")]),s("OutboundLink")],1),t._v(" release brings updated dependencies, more sanity checks and an overhauled API to build transactions.")]),t._v(" "),s("p",[t._v("You can find the full "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/5e352489a0ac9dd92002a73aa64789a9ae2f0794/CHANGELOG.md#v040---v030",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.4.0 changelog"),s("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),s("h2",{attrs:{id:"whats-new-in-v040"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v040"}},[t._v("#")]),t._v(" What's new in v0.4.0")]),t._v(" "),s("p",[t._v("Below are some highlights of the new improved APIs coming with this release:")]),t._v(" "),s("h3",{attrs:{id:"a-new-api-to-build-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#a-new-api-to-build-transaction"}},[t._v("#")]),t._v(" A new API to build transaction")]),t._v(" "),s("p",[t._v("The star of this release is the new API designed and implemented by "),s("a",{attrs:{href:"https://github.com/llfourn",target:"_blank",rel:"noopener noreferrer"}},[t._v("@llfourn"),s("OutboundLink")],1),t._v(" that brings much more flexibility to the way we create transactions: originally the process of making a transaction involved the creation of a "),s("code",[t._v("TxBuilder")]),t._v(" which was used\nto configure "),s("em",[t._v("how")]),t._v(" the wallet should build the transaction. Things like which outputs to create, what "),s("code",[t._v("nLockTime")]),t._v(" to use, which UTXOs to spend, and much more.")]),t._v(" "),s("p",[t._v("Once fully configured, this builder was then given to the "),s("code",[t._v("Wallet")]),t._v(" itself in a "),s("code",[t._v("Wallet::create_tx()")]),t._v(" or "),s("code",[t._v("Wallet::bump_fee()")]),t._v(" call: the "),s("code",[t._v("Wallet")]),t._v(" would try to follow the "),s("em",[t._v("instructions")]),t._v(" given by the builder, but in\ncase of conflicting or straight-up wrong options it would have to fail and force the user to start over.")]),t._v(" "),s("p",[t._v("The new API maintains the concept of a "),s("em",[t._v("builder")]),t._v(", but it changes the way it's created so that it always contains a reference to the main "),s("code",[t._v("Wallet")]),t._v(" instance. What this means is that most checks can now be performed right\nwhen something is added to the builder, not at the end, allowing the user to recover from errors instead of having to start over.")]),t._v(" "),s("p",[t._v("This also opens the door to even more improvements and additions, such as a way to "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/279",target:"_blank",rel:"noopener noreferrer"}},[t._v("spend foreign utxos"),s("OutboundLink")],1),t._v(" in a transaction, or even a way to "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/280",target:"_blank",rel:"noopener noreferrer"}},[t._v("bump the fees of multiple transactions at once"),s("OutboundLink")],1),t._v(" by batching them together, which\nsaves a bit of space and money.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" send_to "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_new_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" details"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("send_to"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enable_rbf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("do_not_spend_change")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fee_rate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeRate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat_per_vb")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"upgraded-dependencies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#upgraded-dependencies"}},[t._v("#")]),t._v(" Upgraded dependencies")]),t._v(" "),s("p",[t._v("This release also brings many updates to our dependencies, including:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("bitcoin")]),t._v(" to "),s("code",[t._v("v0.26")])]),t._v(" "),s("li",[s("code",[t._v("miniscript")]),t._v(" to "),s("code",[t._v("v5.1")])]),t._v(" "),s("li",[s("code",[t._v("electrum-client")]),t._v(" to "),s("code",[t._v("v0.6")])]),t._v(" "),s("li",[s("code",[t._v("tokio")]),t._v(" to "),s("code",[t._v("v1")])]),t._v(" "),s("li",[s("code",[t._v("reqwest")]),t._v(" to "),s("code",[t._v("v0.11")])]),t._v(" "),s("li",[s("code",[t._v("cc")]),t._v(" to "),s("code",[t._v(">= v1.0.64")])])]),t._v(" "),s("h3",{attrs:{id:"compact-filters-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compact-filters-example"}},[t._v("#")]),t._v(" Compact Filters example")]),t._v(" "),s("p",[t._v("Thanks to the upgrade to "),s("code",[t._v("bitcoin v0.26")]),t._v(" all the issues related to new networking messages in the P2P Bitcoin network have been fixed, which means that we can finally use our (experimental) compact filters "),s("code",[t._v("Blockchain")]),t._v(" with\nstandard Bitcoin Core 0.21 full nodes.")]),t._v(" "),s("p",[t._v("The following example has also been added to the repository and can be run with "),s("code",[t._v("cargo run --features=compact_filters --example compact_filters_balance")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/// This will return wallet balance using compact filters")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/// Requires a synced local bitcoin node 0.21 running on testnet with blockfilterindex=1 and peerblockfilters=1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersError")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("env_logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("init")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("info!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"start"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" num_threads "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mempool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("num_threads"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token closure-params"}},[s("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"localhost:18333"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("mempool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("peers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./wallet-filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("info!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"done {:?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" descriptor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh(tpubD6NzVbkrYhZ4X2yy78HWrr1M9NT8dKeWfzNiQqDdMqqa9UmmGztGGz6TaLFGsLfdft5iu32gxq1T4eMNxExNNWzVCpf9Y6JZi5TnqoC9wJq/*)"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" database "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("noop_progress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("info!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"balance: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"contributors"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),s("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),s("p",[t._v("Since the "),s("code",[t._v("v0.3.0")]),t._v(" release around a month ago, we've had "),s("code",[t._v("59")]),t._v(" new commits made by "),s("code",[t._v("8")]),t._v(" different contributors for a total of "),s("code",[t._v("2463")]),t._v(" additions and "),s("code",[t._v("1991")]),t._v(" deletions. Here's the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.3.0...v0.4.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/luckysori",target:"_blank",rel:"noopener noreferrer"}},[t._v("@luckysori"),s("OutboundLink")],1),t._v(" - Lucas Soriano")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[71],{429:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("p",[t._v("A new release of BDK is out: the "),s("a",{attrs:{href:"https://crates.io/crates/bdk/0.4.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.4.0")]),s("OutboundLink")],1),t._v(" release brings updated dependencies, more sanity checks and an overhauled API to build transactions.")]),t._v(" "),s("p",[t._v("You can find the full "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/5e352489a0ac9dd92002a73aa64789a9ae2f0794/CHANGELOG.md#v040---v030",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.4.0 changelog"),s("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),s("h2",{attrs:{id:"whats-new-in-v040"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v040"}},[t._v("#")]),t._v(" What's new in v0.4.0")]),t._v(" "),s("p",[t._v("Below are some highlights of the new improved APIs coming with this release:")]),t._v(" "),s("h3",{attrs:{id:"a-new-api-to-build-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#a-new-api-to-build-transaction"}},[t._v("#")]),t._v(" A new API to build transaction")]),t._v(" "),s("p",[t._v("The star of this release is the new API designed and implemented by "),s("a",{attrs:{href:"https://github.com/llfourn",target:"_blank",rel:"noopener noreferrer"}},[t._v("@llfourn"),s("OutboundLink")],1),t._v(" that brings much more flexibility to the way we create transactions: originally the process of making a transaction involved the creation of a "),s("code",[t._v("TxBuilder")]),t._v(" which was used\nto configure "),s("em",[t._v("how")]),t._v(" the wallet should build the transaction. Things like which outputs to create, what "),s("code",[t._v("nLockTime")]),t._v(" to use, which UTXOs to spend, and much more.")]),t._v(" "),s("p",[t._v("Once fully configured, this builder was then given to the "),s("code",[t._v("Wallet")]),t._v(" itself in a "),s("code",[t._v("Wallet::create_tx()")]),t._v(" or "),s("code",[t._v("Wallet::bump_fee()")]),t._v(" call: the "),s("code",[t._v("Wallet")]),t._v(" would try to follow the "),s("em",[t._v("instructions")]),t._v(" given by the builder, but in\ncase of conflicting or straight-up wrong options it would have to fail and force the user to start over.")]),t._v(" "),s("p",[t._v("The new API maintains the concept of a "),s("em",[t._v("builder")]),t._v(", but it changes the way it's created so that it always contains a reference to the main "),s("code",[t._v("Wallet")]),t._v(" instance. What this means is that most checks can now be performed right\nwhen something is added to the builder, not at the end, allowing the user to recover from errors instead of having to start over.")]),t._v(" "),s("p",[t._v("This also opens the door to even more improvements and additions, such as a way to "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/279",target:"_blank",rel:"noopener noreferrer"}},[t._v("spend foreign utxos"),s("OutboundLink")],1),t._v(" in a transaction, or even a way to "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/280",target:"_blank",rel:"noopener noreferrer"}},[t._v("bump the fees of multiple transactions at once"),s("OutboundLink")],1),t._v(" by batching them together, which\nsaves a bit of space and money.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" send_to "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_new_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" details"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("send_to"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enable_rbf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("do_not_spend_change")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fee_rate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeRate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat_per_vb")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"upgraded-dependencies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#upgraded-dependencies"}},[t._v("#")]),t._v(" Upgraded dependencies")]),t._v(" "),s("p",[t._v("This release also brings many updates to our dependencies, including:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("bitcoin")]),t._v(" to "),s("code",[t._v("v0.26")])]),t._v(" "),s("li",[s("code",[t._v("miniscript")]),t._v(" to "),s("code",[t._v("v5.1")])]),t._v(" "),s("li",[s("code",[t._v("electrum-client")]),t._v(" to "),s("code",[t._v("v0.6")])]),t._v(" "),s("li",[s("code",[t._v("tokio")]),t._v(" to "),s("code",[t._v("v1")])]),t._v(" "),s("li",[s("code",[t._v("reqwest")]),t._v(" to "),s("code",[t._v("v0.11")])]),t._v(" "),s("li",[s("code",[t._v("cc")]),t._v(" to "),s("code",[t._v(">= v1.0.64")])])]),t._v(" "),s("h3",{attrs:{id:"compact-filters-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compact-filters-example"}},[t._v("#")]),t._v(" Compact Filters example")]),t._v(" "),s("p",[t._v("Thanks to the upgrade to "),s("code",[t._v("bitcoin v0.26")]),t._v(" all the issues related to new networking messages in the P2P Bitcoin network have been fixed, which means that we can finally use our (experimental) compact filters "),s("code",[t._v("Blockchain")]),t._v(" with\nstandard Bitcoin Core 0.21 full nodes.")]),t._v(" "),s("p",[t._v("The following example has also been added to the repository and can be run with "),s("code",[t._v("cargo run --features=compact_filters --example compact_filters_balance")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/// This will return wallet balance using compact filters")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/// Requires a synced local bitcoin node 0.21 running on testnet with blockfilterindex=1 and peerblockfilters=1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersError")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("env_logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("init")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("info!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"start"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" num_threads "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mempool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("num_threads"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token closure-params"}},[s("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"localhost:18333"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("mempool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("collect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("peers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./wallet-filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("info!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"done {:?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" descriptor "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh(tpubD6NzVbkrYhZ4X2yy78HWrr1M9NT8dKeWfzNiQqDdMqqa9UmmGztGGz6TaLFGsLfdft5iu32gxq1T4eMNxExNNWzVCpf9Y6JZi5TnqoC9wJq/*)"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" database "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("descriptor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("noop_progress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("info!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"balance: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"contributors"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),s("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),s("p",[t._v("Since the "),s("code",[t._v("v0.3.0")]),t._v(" release around a month ago, we've had "),s("code",[t._v("59")]),t._v(" new commits made by "),s("code",[t._v("8")]),t._v(" different contributors for a total of "),s("code",[t._v("2463")]),t._v(" additions and "),s("code",[t._v("1991")]),t._v(" deletions. Here's the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.3.0...v0.4.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/luckysori",target:"_blank",rel:"noopener noreferrer"}},[t._v("@luckysori"),s("OutboundLink")],1),t._v(" - Lucas Soriano")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/72.d0343ad9.js b/assets/js/72.1d7ffcda.js similarity index 98% rename from assets/js/72.d0343ad9.js rename to assets/js/72.1d7ffcda.js index 6afccb51f0..f93761aa55 100644 --- a/assets/js/72.d0343ad9.js +++ b/assets/js/72.1d7ffcda.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[72],{430:function(t,e,n){"use strict";n.r(e);var a=n(7),s=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("A new release of BDK is out: "),e("a",{attrs:{href:"https://crates.io/crates/bdk/0.5.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.5.0")]),e("OutboundLink")],1),t._v(" is our first release licensed under Apache 2.0 and MIT, brings new features, bugfixes and some internal refactoring.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/f786f0e6241a3df47b96bbb07f1aba374bc73b2f/CHANGELOG.md#v050---v040",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.5.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v050"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v050"}},[t._v("#")]),t._v(" What's new in v0.5.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h3",{attrs:{id:"dual-licensing"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dual-licensing"}},[t._v("#")]),t._v(" Dual Licensing")]),t._v(" "),e("p",[t._v("From now on BDK will be released under both Apache 2.0 and MIT, at your discretion. This change aligns our project with many other Rust crates and reiterates our commitment to a permissive licensing model.")]),t._v(" "),e("h3",{attrs:{id:"spending-foreign-utxos"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#spending-foreign-utxos"}},[t._v("#")]),t._v(" Spending "),e("em",[t._v("foreign")]),t._v(" UTXOs")]),t._v(" "),e("p",[t._v("This release adds a new "),e("code",[t._v("TxBuilder")]),t._v(" method called "),e("a",{attrs:{href:"https://docs.rs/bdk/0.5.0/bdk/wallet/tx_builder/struct.TxBuilder.html#method.add_foreign_utxo",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("add_foreign_utxo()")]),e("OutboundLink")],1),t._v(", which can be used to spend UTXOs that don't belong to the "),e("code",[t._v("Wallet")]),t._v(". We think this is going to be very useful to developers working on multiparty\nprotocols like CoinJoins, Pay Join, etc.")]),t._v(" "),e("p",[t._v("It's as easy as giving the library a PSBT input and the satisfaction cost for that input:")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nbuilder\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("60_000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_foreign_utxo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foreign_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" foreign_utxo_psbt_input"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" foreign_utxo_satisfaction_weight"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n")])])]),e("h2",{attrs:{id:"contributors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),e("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),e("p",[t._v("Since the "),e("code",[t._v("v0.4.0")]),t._v(" release around a month ago, we've had "),e("code",[t._v("54")]),t._v(" new commits made by "),e("code",[t._v("7")]),t._v(" different contributors for a total of "),e("code",[t._v("1430")]),t._v(" additions and "),e("code",[t._v("1212")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.4.0...v0.5.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/davemo88",target:"_blank",rel:"noopener noreferrer"}},[t._v("@davemo88"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[72],{428:function(t,e,n){"use strict";n.r(e);var a=n(7),s=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("A new release of BDK is out: "),e("a",{attrs:{href:"https://crates.io/crates/bdk/0.5.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.5.0")]),e("OutboundLink")],1),t._v(" is our first release licensed under Apache 2.0 and MIT, brings new features, bugfixes and some internal refactoring.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/f786f0e6241a3df47b96bbb07f1aba374bc73b2f/CHANGELOG.md#v050---v040",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.5.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v050"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v050"}},[t._v("#")]),t._v(" What's new in v0.5.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h3",{attrs:{id:"dual-licensing"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dual-licensing"}},[t._v("#")]),t._v(" Dual Licensing")]),t._v(" "),e("p",[t._v("From now on BDK will be released under both Apache 2.0 and MIT, at your discretion. This change aligns our project with many other Rust crates and reiterates our commitment to a permissive licensing model.")]),t._v(" "),e("h3",{attrs:{id:"spending-foreign-utxos"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#spending-foreign-utxos"}},[t._v("#")]),t._v(" Spending "),e("em",[t._v("foreign")]),t._v(" UTXOs")]),t._v(" "),e("p",[t._v("This release adds a new "),e("code",[t._v("TxBuilder")]),t._v(" method called "),e("a",{attrs:{href:"https://docs.rs/bdk/0.5.0/bdk/wallet/tx_builder/struct.TxBuilder.html#method.add_foreign_utxo",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("add_foreign_utxo()")]),e("OutboundLink")],1),t._v(", which can be used to spend UTXOs that don't belong to the "),e("code",[t._v("Wallet")]),t._v(". We think this is going to be very useful to developers working on multiparty\nprotocols like CoinJoins, Pay Join, etc.")]),t._v(" "),e("p",[t._v("It's as easy as giving the library a PSBT input and the satisfaction cost for that input:")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nbuilder\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("60_000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_foreign_utxo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("foreign_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" foreign_utxo_psbt_input"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" foreign_utxo_satisfaction_weight"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n")])])]),e("h2",{attrs:{id:"contributors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),e("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),e("p",[t._v("Since the "),e("code",[t._v("v0.4.0")]),t._v(" release around a month ago, we've had "),e("code",[t._v("54")]),t._v(" new commits made by "),e("code",[t._v("7")]),t._v(" different contributors for a total of "),e("code",[t._v("1430")]),t._v(" additions and "),e("code",[t._v("1212")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.4.0...v0.5.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/davemo88",target:"_blank",rel:"noopener noreferrer"}},[t._v("@davemo88"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/73.a5e67ee7.js b/assets/js/73.5decc786.js similarity index 99% rename from assets/js/73.a5e67ee7.js rename to assets/js/73.5decc786.js index 6d82fd02ed..f9e5387eec 100644 --- a/assets/js/73.a5e67ee7.js +++ b/assets/js/73.5decc786.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[73],{429:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("A new release of BDK is out: "),e("a",{attrs:{href:"https://crates.io/crates/bdk/0.6.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.6.0")]),e("OutboundLink")],1),t._v(" brings some new API calls, renamed types and some bugfixes.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/2bddd9baedc3744cd7647176c2f31405ee7bb54a/CHANGELOG.md#v060---v051",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.6.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v060"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v060"}},[t._v("#")]),t._v(" What's new in v0.6.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h3",{attrs:{id:"a-new-way-to-generate-addresses"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-new-way-to-generate-addresses"}},[t._v("#")]),t._v(" A new way to generate addresses")]),t._v(" "),e("p",[t._v("The old "),e("code",[t._v("get_new_address()")]),t._v(" method has been upgraded into a more generic "),e("code",[t._v("get_address()")]),t._v(", which takes a "),e("a",{attrs:{href:"https://docs.rs/bdk/0.6.0/bdk/wallet/enum.AddressIndex.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("AddressIndex")]),e("OutboundLink")],1),t._v(" argument. "),e("code",[t._v("AddressIndex")]),t._v(" is defined as an enum with the following variants:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("AddressIndex::New")]),t._v(" increments the derivation index stored in the database and returns a new address. It's equivalent to the old "),e("code",[t._v("get_new_address()")]),t._v(".")]),t._v(" "),e("li",[e("code",[t._v("AddressIndex::LastUnused")]),t._v(" returns the address for the current derivation index if no usage has been detected. "),e("code",[t._v("sync()")]),t._v(" should be called to ensure the internal database is up to date.")]),t._v(" "),e("li",[e("code",[t._v("AddressIndex::Peek(index)")]),t._v(" returns the address at a given derivation index, without updating the database.")]),t._v(" "),e("li",[e("code",[t._v("AddressIndex::Reset(index)")]),t._v(" returns the address at a given derivation index, and stores that value in the database.")])]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Prints the first ten addresses without updating the derivation index")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" index "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Address #{}: {}"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peek")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h3",{attrs:{id:"easier-multiparty-transaction-creation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#easier-multiparty-transaction-creation"}},[t._v("#")]),t._v(" Easier multiparty transaction creation")]),t._v(" "),e("p",[t._v("A new method called "),e("a",{attrs:{href:"https://docs.rs/bdk/0.6.0/bdk/wallet/struct.Wallet.html#method.get_psbt_input",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("get_psbt_input()")]),e("OutboundLink")],1),t._v(" has been added to the "),e("code",[t._v("Wallet")]),t._v(" structure, and it makes it very easy to get a complete PSBT input with all the required metadata for a given UTXO. This can be very convenient\nwhen working with "),e("code",[t._v("add_foreign_utxo()")]),t._v(", which was added in the previous release:")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// On Alice's wallet")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" alice_utxo "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LocalUtxo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" alice_psbt_input "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet_alice"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_psbt_input")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("alice_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_input_to_bob")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("alice_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" alice_psbt_input"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// On Bob's wallet")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet_bob"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nbuilder\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("60_000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_foreign_utxo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("alice_outpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" alice_psbt_input"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" satisfaction_weight"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n")])])]),e("h3",{attrs:{id:"renamed-types"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#renamed-types"}},[t._v("#")]),t._v(" Renamed types")]),t._v(" "),e("p",[t._v("To keep our coding style in line with the best practices defined by the Rust language, we've renamed some of our types and enum variants to avoid using "),e("a",{attrs:{href:"https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms",target:"_blank",rel:"noopener noreferrer"}},[t._v("upper case acronyms"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("Some examples are:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("UTXO")]),t._v(" -> "),e("code",[t._v("Utxo")])]),t._v(" "),e("li",[e("code",[t._v("RBFValue")]),t._v(" -> "),e("code",[t._v("RbfValue")])]),t._v(" "),e("li",[e("code",[t._v("BIP69Lexicographic")]),t._v(" -> "),e("code",[t._v("Bip69Lexicographic")])]),t._v(" "),e("li",[e("code",[t._v("P2PKH")]),t._v(" -> "),e("code",[t._v("P2Pkh")])]),t._v(" "),e("li",[e("code",[t._v("BIP44Public")]),t._v(" -> "),e("code",[t._v("Bip44Public")])])]),t._v(" "),e("h3",{attrs:{id:"new-msrv"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#new-msrv"}},[t._v("#")]),t._v(" New MSRV")]),t._v(" "),e("p",[t._v("Due to some changes in one of our dependency, our MSRV has been bumped up from "),e("code",[t._v("1.45")]),t._v(" to "),e("code",[t._v("1.46")]),t._v(", which was released in August 2020. The last release fully supporting "),e("code",[t._v("1.45")]),t._v(" is "),e("code",[t._v("v0.5.1")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"contributors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),e("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),e("p",[t._v("Since the "),e("code",[t._v("v0.5.1")]),t._v(" release around a month ago, we've had "),e("code",[t._v("37")]),t._v(" new commits made by "),e("code",[t._v("7")]),t._v(" different contributors for a total of "),e("code",[t._v("1092")]),t._v(" additions and "),e("code",[t._v("548")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.5.1...v0.6.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/da-kami",target:"_blank",rel:"noopener noreferrer"}},[t._v("@da-kami"),e("OutboundLink")],1),t._v(" - Daniel Karzel")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[73],{430:function(t,e,a){"use strict";a.r(e);var s=a(7),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("A new release of BDK is out: "),e("a",{attrs:{href:"https://crates.io/crates/bdk/0.6.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.6.0")]),e("OutboundLink")],1),t._v(" brings some new API calls, renamed types and some bugfixes.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/2bddd9baedc3744cd7647176c2f31405ee7bb54a/CHANGELOG.md#v060---v051",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.6.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v060"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v060"}},[t._v("#")]),t._v(" What's new in v0.6.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h3",{attrs:{id:"a-new-way-to-generate-addresses"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-new-way-to-generate-addresses"}},[t._v("#")]),t._v(" A new way to generate addresses")]),t._v(" "),e("p",[t._v("The old "),e("code",[t._v("get_new_address()")]),t._v(" method has been upgraded into a more generic "),e("code",[t._v("get_address()")]),t._v(", which takes a "),e("a",{attrs:{href:"https://docs.rs/bdk/0.6.0/bdk/wallet/enum.AddressIndex.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("AddressIndex")]),e("OutboundLink")],1),t._v(" argument. "),e("code",[t._v("AddressIndex")]),t._v(" is defined as an enum with the following variants:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("AddressIndex::New")]),t._v(" increments the derivation index stored in the database and returns a new address. It's equivalent to the old "),e("code",[t._v("get_new_address()")]),t._v(".")]),t._v(" "),e("li",[e("code",[t._v("AddressIndex::LastUnused")]),t._v(" returns the address for the current derivation index if no usage has been detected. "),e("code",[t._v("sync()")]),t._v(" should be called to ensure the internal database is up to date.")]),t._v(" "),e("li",[e("code",[t._v("AddressIndex::Peek(index)")]),t._v(" returns the address at a given derivation index, without updating the database.")]),t._v(" "),e("li",[e("code",[t._v("AddressIndex::Reset(index)")]),t._v(" returns the address at a given derivation index, and stores that value in the database.")])]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Prints the first ten addresses without updating the derivation index")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" index "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Address #{}: {}"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peek")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h3",{attrs:{id:"easier-multiparty-transaction-creation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#easier-multiparty-transaction-creation"}},[t._v("#")]),t._v(" Easier multiparty transaction creation")]),t._v(" "),e("p",[t._v("A new method called "),e("a",{attrs:{href:"https://docs.rs/bdk/0.6.0/bdk/wallet/struct.Wallet.html#method.get_psbt_input",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("get_psbt_input()")]),e("OutboundLink")],1),t._v(" has been added to the "),e("code",[t._v("Wallet")]),t._v(" structure, and it makes it very easy to get a complete PSBT input with all the required metadata for a given UTXO. This can be very convenient\nwhen working with "),e("code",[t._v("add_foreign_utxo()")]),t._v(", which was added in the previous release:")]),t._v(" "),e("div",{staticClass:"language-rust extra-class"},[e("pre",{pre:!0,attrs:{class:"language-rust"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// On Alice's wallet")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" alice_utxo "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LocalUtxo")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" alice_psbt_input "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet_alice"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_psbt_input")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("alice_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clone")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("send_input_to_bob")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("alice_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" alice_psbt_input"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// On Bob's wallet")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet_bob"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nbuilder\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_recipient")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("60_000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_foreign_utxo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("alice_outpoint"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" alice_psbt_input"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" satisfaction_weight"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n")])])]),e("h3",{attrs:{id:"renamed-types"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#renamed-types"}},[t._v("#")]),t._v(" Renamed types")]),t._v(" "),e("p",[t._v("To keep our coding style in line with the best practices defined by the Rust language, we've renamed some of our types and enum variants to avoid using "),e("a",{attrs:{href:"https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms",target:"_blank",rel:"noopener noreferrer"}},[t._v("upper case acronyms"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("Some examples are:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("UTXO")]),t._v(" -> "),e("code",[t._v("Utxo")])]),t._v(" "),e("li",[e("code",[t._v("RBFValue")]),t._v(" -> "),e("code",[t._v("RbfValue")])]),t._v(" "),e("li",[e("code",[t._v("BIP69Lexicographic")]),t._v(" -> "),e("code",[t._v("Bip69Lexicographic")])]),t._v(" "),e("li",[e("code",[t._v("P2PKH")]),t._v(" -> "),e("code",[t._v("P2Pkh")])]),t._v(" "),e("li",[e("code",[t._v("BIP44Public")]),t._v(" -> "),e("code",[t._v("Bip44Public")])])]),t._v(" "),e("h3",{attrs:{id:"new-msrv"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#new-msrv"}},[t._v("#")]),t._v(" New MSRV")]),t._v(" "),e("p",[t._v("Due to some changes in one of our dependency, our MSRV has been bumped up from "),e("code",[t._v("1.45")]),t._v(" to "),e("code",[t._v("1.46")]),t._v(", which was released in August 2020. The last release fully supporting "),e("code",[t._v("1.45")]),t._v(" is "),e("code",[t._v("v0.5.1")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"contributors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#contributors"}},[t._v("#")]),t._v(" Contributors")]),t._v(" "),e("p",[t._v("A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.")]),t._v(" "),e("p",[t._v("Since the "),e("code",[t._v("v0.5.1")]),t._v(" release around a month ago, we've had "),e("code",[t._v("37")]),t._v(" new commits made by "),e("code",[t._v("7")]),t._v(" different contributors for a total of "),e("code",[t._v("1092")]),t._v(" additions and "),e("code",[t._v("548")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.5.1...v0.6.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("A special thanks to the new contributor for this release:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/da-kami",target:"_blank",rel:"noopener noreferrer"}},[t._v("@da-kami"),e("OutboundLink")],1),t._v(" - Daniel Karzel")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/78.f8907212.js b/assets/js/78.4514085a.js similarity index 99% rename from assets/js/78.f8907212.js rename to assets/js/78.4514085a.js index d9c1291a02..34318481d0 100644 --- a/assets/js/78.f8907212.js +++ b/assets/js/78.4514085a.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[78],{435:function(a,s,t){"use strict";t.r(s);var e=t(7),n=Object(e.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[a._v("#")]),a._v(" Introduction")]),a._v(" "),s("p",[a._v("In this post we will use the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[a._v("bdk-cli"),s("OutboundLink")],1),a._v(" tool to demonstrate how to use the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[a._v("bdk"),s("OutboundLink")],1),a._v(" library to:")]),a._v(" "),s("ol",[s("li",[a._v("generate "),s("em",[a._v("testnet")]),a._v(" public and private keys")]),a._v(" "),s("li",[a._v("create "),s("a",{attrs:{href:"https://bitcoinops.org/en/topics/psbt/",target:"_blank",rel:"noopener noreferrer"}},[a._v("PSBT"),s("OutboundLink")],1),a._v("s that can be spent based on different "),s("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[a._v("miniscript spending policies"),s("OutboundLink")],1)]),a._v(" "),s("li",[a._v("cooperatively sign and finalize the resulting PSBTs")]),a._v(" "),s("li",[a._v("broadcast and confirm spending transactions")])]),a._v(" "),s("p",[a._v("The scenario we will simulate is a wallet with two spending policies:")]),a._v(" "),s("p",[a._v("A. "),s("strong",[a._v("three")]),a._v(" out of "),s("strong",[a._v("three")]),a._v(" signers must sign spending transaction input "),s("a",{attrs:{href:"https://developer.bitcoin.org/glossary.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("UTXO"),s("OutboundLink")],1),a._v("s, "),s("strong",[a._v("OR")])]),a._v(" "),s("p",[a._v("B. "),s("strong",[a._v("two")]),a._v(" out of "),s("strong",[a._v("three")]),a._v(" signers must sign "),s("strong",[a._v("AND")]),a._v(" the input UTXOs must be a relative number of blocks older than the spending transaction's block")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("p",[s("em",[a._v("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.")])]),a._v(" "),s("h2",{attrs:{id:"initial-setup"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initial-setup"}},[a._v("#")]),a._v(" Initial Setup")]),a._v(" "),s("h3",{attrs:{id:"step-0-install-a-recent-version-bdk-cli"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-0-install-a-recent-version-bdk-cli"}},[a._v("#")]),a._v(" Step 0: Install a recent version "),s("code",[a._v("bdk-cli")])]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cargo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" bdk-cli "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--features")]),a._v(" electrum\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# confirm bdk-cli is installed")]),a._v("\nbdk-cli "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--version")]),a._v("\nBDK CLI "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0.4")]),a._v(".0\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# bdk-cli usage can be explored with the `help` sub-command")]),a._v("\nbdk-cli "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-1-generate-private-extended-keys"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-1-generate-private-extended-keys"}},[a._v("#")]),a._v(" Step 1: Generate private extended keys")]),a._v(" "),s("p",[a._v("Generate new extended private keys for each of our wallet participants:")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli key generate "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tee")]),a._v(" alice-key.json\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5adb4683"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"mnemonic"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"witness poverty pulse crush era item game rose bargain quantum spawn sure way behave also basket journey worry stem entry toddler floor way bone"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xprv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tprv8ZgxMBicQKsPeAuGznXJZwfWHgWo86dFuufRBZN7ZT44UzoNG2cYmZLNLrnsm7eXhGSeccRU2nTtxunT11UkpqrRhJQefBnFJeHBddF68bg"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli key generate "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tee")]),a._v(" bob-key.json\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5fdec309"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"mnemonic"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"shiver atom february jealous spy gallery upset height captain snake tooth master ugly orbit amazing nice parrot elevator own olympic great relief ozone violin"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xprv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tprv8ZgxMBicQKsPei56wJPNt9u2132Ynncp2qXdfSHszobnyjaGjQwxQBGASUidc1unmEmpyMQ9XzLgvbN36MDW7LNziVFdXVGMrx6ckMHuRmd"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli key generate "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tee")]),a._v(" carol-key.json\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"de41e56d"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"mnemonic"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"upon bridge side tool style lounge need faculty middle nation armed corn valve that undo ribbon rent digital adapt capable embody zero shiver carpet"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xprv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tprv8ZgxMBicQKsPf2edJLnXsF2AKwkCshCy2Z7fQD6FxiNVGsbkvpLRfxM8FSKrLqqpLFzLzVUBwgE9F5MQASrbedKCrGk1NG8oJgqYtmTLQEU"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-2-extract-private-extended-keys"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-2-extract-private-extended-keys"}},[a._v("#")]),a._v(" Step 2: Extract private extended keys")]),a._v(" "),s("p",[a._v("Here we use the "),s("code",[a._v("jq")]),a._v(" Unix command to parse the json output of the "),s("code",[a._v("bdk-cli")]),a._v(" commands.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_XPRV")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cat")]),a._v(" alice-key.json "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BOB_XPRV")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cat")]),a._v(" bob-key.json "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CAROL_XPRV")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cat")]),a._v(" carol-key.json "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),s("h3",{attrs:{id:"step-3-derive-public-extended-keys"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-3-derive-public-extended-keys"}},[a._v("#")]),a._v(" Step 3: Derive public extended keys")]),a._v(" "),s("p",[a._v("For this example we are using the "),s("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP-84"),s("OutboundLink")],1),a._v(" key path: "),s("code",[a._v("m/84h/1h/0h/0/*")]),a._v(" to derive extended public keys to share with other wallet participants.")]),a._v(" "),s("p",[a._v("Note that the "),s("code",[a._v("key derive")]),a._v(" sub-command will generate a tpub for the last hardened node in the given derivation path. You'll also notice that "),s("code",[a._v("bdk-cli")]),a._v(" will returns our tpub with the key origin (fingerprint/path) added to it (the metadata part that looks like "),s("code",[a._v("[5adb4683/84'/1'/0']")]),a._v(" 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.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_XPUB")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $ALICE_XPRV "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"m/84'/1'/0'/0\"")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".xpub"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPUB")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"\n'),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"[5adb4683/84'/1'/0']tpubDCyRBuncqwyAjSNiw1GWLmwQsWyhgPMEBpx3ZNpnCwZwf3HXerspTpaneN81KRxkwj8vjqH9pNWEPgNhen7dfE212SHfxBBbsCywxQGxvvu/0/*\"")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BOB_XPUB")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $BOB_XPRV "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"m/84'/1'/0'/0\"")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".xpub"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPUB")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"\n'),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"[5fdec309/84'/1'/0']tpubDDQcUeBH9JFtgZEsHZBhmRu8AuZ8ceJY1umnipPVEg1had2coGMCWdFBXNnZWKoCPic3EMgDZTdmkAVNoakwNZu2ESSW36rQvts6VXGx4bU/0/*\"")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CAROL_XPUB")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $CAROL_XPRV "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"m/84'/1'/0'/0\"")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".xpub"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPUB")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"\n'),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"[de41e56d/84'/1'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/0/*\"")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-4-create-wallet-descriptors-for-each-participant"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-4-create-wallet-descriptors-for-each-participant"}},[a._v("#")]),a._v(" Step 4: Create wallet descriptors for each participant")]),a._v(" "),s("p",[a._v("We used the "),s("a",{attrs:{href:"https://bitcoindevkit.org/bdk-cli/playground/",target:"_blank",rel:"noopener noreferrer"}},[a._v("BDK Playground Policy Compiler"),s("OutboundLink")],1),a._v(" to compile the "),s("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[a._v("miniscript"),s("OutboundLink")],1),a._v(" policy:")]),a._v(" "),s("p",[s("code",[a._v("thresh(3,pk(Alice),pk(Bob),pk(Carol),older(2))")])]),a._v(" "),s("p",[a._v("To the "),s("a",{attrs:{href:"https://bitcoindevkit.org/descriptors/",target:"_blank",rel:"noopener noreferrer"}},[a._v("output descriptor"),s("OutboundLink")],1),a._v(":")]),a._v(" "),s("p",[s("code",[a._v("wsh(thresh(3,pk(Alice),s:pk(Bob),s:pk(Carol),sdv:older(2)))")])]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("p",[a._v("Each participant's descriptor only uses their own XPRV key plus the XPUB keys of the other participants.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_DESCRIPTOR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wsh(thresh(3,pk('),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPRV")]),a._v("/84'/1'/0'/0/*),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPUB")]),a._v('),snl:older(2)))"')]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BOB_DESCRIPTOR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wsh(thresh(3,pk('),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPRV")]),a._v("/84'/1'/0'/0/*),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPUB")]),a._v('),snl:older(2)))"')]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CAROL_DESCRIPTOR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wsh(thresh(3,pk('),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPRV")]),a._v("/84'/1'/0'/0/*),snl:older(2)))\"")]),a._v("\n")])])]),s("h2",{attrs:{id:"policy-a-three-signatures"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#policy-a-three-signatures"}},[a._v("#")]),a._v(" Policy A. Three signatures")]),a._v(" "),s("h3",{attrs:{id:"step-1a-create-a-testnet-segwit0-receive-address"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-1a-create-a-testnet-segwit0-receive-address"}},[a._v("#")]),a._v(" Step 1a: Create a testnet "),s("a",{attrs:{href:"https://en.bitcoin.it/wiki/Segregated_Witness",target:"_blank",rel:"noopener noreferrer"}},[a._v("segwit0"),s("OutboundLink")],1),a._v(" receive address")]),a._v(" "),s("p",[a._v("This step can be done independently by Alice, Bob, or Carol.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" get_new_address\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-2a-send-testnet-bitcoin-from-a-faucet-to-receive-address"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-2a-send-testnet-bitcoin-from-a-faucet-to-receive-address"}},[a._v("#")]),a._v(" Step 2a: Send testnet bitcoin from a faucet to receive address")]),a._v(" "),s("p",[a._v("After a faucet payment is sent, use a testnet block explorer to confirm the transaction was included in a block.")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e"),s("OutboundLink")],1)]),a._v(" "),s("h3",{attrs:{id:"step-3a-sync-participant-wallets-and-confirm-balance"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-3a-sync-participant-wallets-and-confirm-balance"}},[a._v("#")]),a._v(" Step 3a: Sync participant wallets and confirm balance")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-4a-view-wallet-spending-policies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-4a-view-wallet-spending-policies"}},[a._v("#")]),a._v(" Step 4a: View wallet spending policies")]),a._v(" "),s("p",[a._v("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..")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" policies\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"external"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"conditions"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"0"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("2")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"items"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("3")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"m"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("3")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"n"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("4")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"PARTIAL"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"ydtnup84"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"items"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"condition"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"COMPLETE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5adb4683"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"uyxvyzqt"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"SIGNATURE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5fdec309"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"dzkmxcgu"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"SIGNATURE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"de41e56d"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"ekfu5uaw"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"SIGNATURE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"condition"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("2")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"COMPLETE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"8kel7sdw"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"RELATIVETIMELOCK"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"value"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("2")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"threshold"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("3")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"THRESH"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"internal"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-5a-create-spending-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-5a-create-spending-transaction"}},[a._v("#")]),a._v(" Step 5a: Create spending transaction")]),a._v(" "),s("p",[a._v("The transaction can also be created by Alice, Bob, or Carol, or even an untrusted coordinator that only has all three tpubs.")]),a._v(" "),s("p",[a._v("Note that the argument provided to the --external_policy flag contains the id retrieved from the "),s("code",[a._v("policies")]),a._v(" subcommand in the above step, in this case "),s("code",[a._v("ydtnup84")]),a._v(".")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,2]}"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"details"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fees"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("169")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"height"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"received"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"sent"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"timestamp"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1614058791")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"transaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"psbt"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cHNidP8BAFIBAAAAAYx7T0cL7EoUYBEU0mSL6+DS4VQafUzJgAf0Ftlbkya5AQAAAAD/////AWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgCBH16JNfSPhmjJR75EdDB+gSCEF7tStNOLqw/k3BvA0BBXchA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxrHwhA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mrJN8IQIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOKyTfHZjUrJpaJNThyIGAi82No/6bA0LQO2BoHoQ0H8M8+VtQNHr41nhLDTvSPM4DO66tnIAAAAAAAAAACIGA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxGFrbRoNUAACAAQAAgAAAAIAAAAAAAAAAACIGA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mDEMxpeYAAAAAAAAAAAAA"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("UNSIGNED_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,2]}"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),s("h3",{attrs:{id:"step-6a-sign-and-finalize-psbts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-6a-sign-and-finalize-psbts"}},[a._v("#")]),a._v(" Step 6a: Sign and finalize PSBTs")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# ALICE SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_SIGNED_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $UNSIGNED_PSBT "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# BOB SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_BOB_SIGNED_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BOB_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $ALICE_SIGNED_PSBT "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# CAROL SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("FINAL_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $CAROL_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $ALICE_BOB_SIGNED_PSBT "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("## PSBT is finalized")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_BOB_SIGNED_PSBT")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"is_finalized"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" true,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"psbt"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"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"')]),a._v("\n")])])]),s("h3",{attrs:{id:"step-7a-broadcast-finalized-psbt"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-7a-broadcast-finalized-psbt"}},[a._v("#")]),a._v(" Step 7a: Broadcast finalized PSBT")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" broadcast "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$FINAL_PSBT")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-8a-confirm-transaction-included-in-a-testnet-block"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-8a-confirm-transaction-included-in-a-testnet-block"}},[a._v("#")]),a._v(" Step 8a: Confirm transaction included in a testnet block")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"),s("OutboundLink")],1)]),a._v(" "),s("p",[a._v("And new wallet balance is now zero.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h4",{attrs:{id:"done-"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#done-"}},[a._v("#")]),a._v(" DONE!")]),a._v(" "),s("h2",{attrs:{id:"policy-b-two-signatures-after-a-relative-time-lock"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#policy-b-two-signatures-after-a-relative-time-lock"}},[a._v("#")]),a._v(" Policy B. Two signatures after a relative time lock")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("h3",{attrs:{id:"step-1b-create-a-new-testnet-receive-address"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-1b-create-a-new-testnet-receive-address"}},[a._v("#")]),a._v(" Step 1b: Create a new testnet receive address")]),a._v(" "),s("p",[a._v("The receive address can still be generated by Alice, Bob, or Carol.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_new_address\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-2b-fund-new-address-from-testnet-faucet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-2b-fund-new-address-from-testnet-faucet"}},[a._v("#")]),a._v(" Step 2b: Fund new address from testnet faucet")]),a._v(" "),s("p",[a._v("After the faucet payment is sent, confirm using a testnet block explorer to verify the transaction was included in a block.")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9"),s("OutboundLink")],1)]),a._v(" "),s("h3",{attrs:{id:"step-3b-sync-wallet-and-confirm-wallet-balance"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-3b-sync-wallet-and-confirm-wallet-balance"}},[a._v("#")]),a._v(" Step 3b: Sync wallet and confirm wallet balance")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# NO CAROL SHE LOST HER KEY!")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-4b-create-spending-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-4b-create-spending-transaction"}},[a._v("#")]),a._v(" Step 4b: Create spending transaction")]),a._v(" "),s("p",[a._v("This spending transaction uses Alice and Bob's keys plus a two block relative time-lock, see above "),s("a",{attrs:{href:"#step-4a-view-wallet-spending-policies"}},[a._v("Step 4a")]),a._v(" for the policy id. The transaction can be created by Alice or Bob.")]),a._v(" "),s("p",[a._v("A time based relative time-lock can be used instead of one based on blocks but is slightly more complicated to calculate. See\n"),s("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#specification",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP-68"),s("OutboundLink")],1),a._v(" for the details.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,3]}"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"details"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fees"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("169")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"height"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"received"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"sent"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"timestamp"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1614059434")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"transaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"psbt"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cHNidP8BAFICAAAAAYmc6mhj4Cf4pcJyBvxSbCd9IB1yDGs+plzb95t7++v0AAAAAAACAAAAAWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgOfTlC2vtnGDNEC2n4j++Wxusqryh4QyqDCqEOQZ5mm4BBXchAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCpprHwhAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFrJN8IQOrU70B/wo/oUUCKFQ2cIsBxx6SysE7uVwxyu0ozM4zYqyTfHZjUrJpaJNThyIGAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCppGFrbRoNUAACAAQAAgAAAAIAAAAAAAQAAACIGAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFDEMxpeYAAAAAAQAAACIGA6tTvQH/Cj+hRQIoVDZwiwHHHpLKwTu5XDHK7SjMzjNiDO66tnIAAAAAAQAAAAAA"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("UNSIGNED_PSBT2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,3]}"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),s("h3",{attrs:{id:"step-5b-sign-and-finalize-psbts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-5b-sign-and-finalize-psbts"}},[a._v("#")]),a._v(" Step 5b: Sign and finalize PSBTs")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# ALICE SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_SIGNED_PSBT2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $UNSIGNED_PSBT2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# BOB SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("FINAL_PSBT2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BOB_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $ALICE_SIGNED_PSBT2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# CAROL DOES *NOT* SIGN")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-6b-broadcast-finalized-psbt"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-6b-broadcast-finalized-psbt"}},[a._v("#")]),a._v(" Step 6b: Broadcast finalized PSBT")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" broadcast "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$FINAL_PSBT2")]),a._v("\nthread "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'main'")]),a._v(" panicked at "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('\'called `Result::unwrap()` on an `Err` value: Electrum(Protocol(String("sendrawtransaction RPC error: {\\"code\\":-26,\\"message\\":\\"non-BIP68-final\\"}")))\'')]),a._v(", src/bdk_cli.rs:168:50\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# Oops we didn't wait long enough for the relative time lock to expire")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# Try again in ~20 mins and it is successfully broadcast")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" broadcast "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$FINAL_PSBT2")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-7b-view-confirmed-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-7b-view-confirmed-transaction"}},[a._v("#")]),a._v(" Step 7b: View confirmed transaction")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"),s("OutboundLink")],1)]),a._v(" "),s("p",[a._v("And wallet balance is again zero")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h4",{attrs:{id:"done-again-"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#done-again-"}},[a._v("#")]),a._v(" Done again!")]),a._v(" "),s("p",[a._v("In this demo we showed how to receive and spend bitcoin using two different descriptor wallet policies using the "),s("code",[a._v("bdk")]),a._v(" library and "),s("code",[a._v("bdk-cli")]),a._v(" wallet tool.")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[78],{437:function(a,s,t){"use strict";t.r(s);var e=t(7),n=Object(e.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[a._v("#")]),a._v(" Introduction")]),a._v(" "),s("p",[a._v("In this post we will use the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[a._v("bdk-cli"),s("OutboundLink")],1),a._v(" tool to demonstrate how to use the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[a._v("bdk"),s("OutboundLink")],1),a._v(" library to:")]),a._v(" "),s("ol",[s("li",[a._v("generate "),s("em",[a._v("testnet")]),a._v(" public and private keys")]),a._v(" "),s("li",[a._v("create "),s("a",{attrs:{href:"https://bitcoinops.org/en/topics/psbt/",target:"_blank",rel:"noopener noreferrer"}},[a._v("PSBT"),s("OutboundLink")],1),a._v("s that can be spent based on different "),s("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[a._v("miniscript spending policies"),s("OutboundLink")],1)]),a._v(" "),s("li",[a._v("cooperatively sign and finalize the resulting PSBTs")]),a._v(" "),s("li",[a._v("broadcast and confirm spending transactions")])]),a._v(" "),s("p",[a._v("The scenario we will simulate is a wallet with two spending policies:")]),a._v(" "),s("p",[a._v("A. "),s("strong",[a._v("three")]),a._v(" out of "),s("strong",[a._v("three")]),a._v(" signers must sign spending transaction input "),s("a",{attrs:{href:"https://developer.bitcoin.org/glossary.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("UTXO"),s("OutboundLink")],1),a._v("s, "),s("strong",[a._v("OR")])]),a._v(" "),s("p",[a._v("B. "),s("strong",[a._v("two")]),a._v(" out of "),s("strong",[a._v("three")]),a._v(" signers must sign "),s("strong",[a._v("AND")]),a._v(" the input UTXOs must be a relative number of blocks older than the spending transaction's block")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("p",[s("em",[a._v("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.")])]),a._v(" "),s("h2",{attrs:{id:"initial-setup"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initial-setup"}},[a._v("#")]),a._v(" Initial Setup")]),a._v(" "),s("h3",{attrs:{id:"step-0-install-a-recent-version-bdk-cli"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-0-install-a-recent-version-bdk-cli"}},[a._v("#")]),a._v(" Step 0: Install a recent version "),s("code",[a._v("bdk-cli")])]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cargo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" bdk-cli "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--features")]),a._v(" electrum\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# confirm bdk-cli is installed")]),a._v("\nbdk-cli "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--version")]),a._v("\nBDK CLI "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0.4")]),a._v(".0\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# bdk-cli usage can be explored with the `help` sub-command")]),a._v("\nbdk-cli "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-1-generate-private-extended-keys"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-1-generate-private-extended-keys"}},[a._v("#")]),a._v(" Step 1: Generate private extended keys")]),a._v(" "),s("p",[a._v("Generate new extended private keys for each of our wallet participants:")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli key generate "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tee")]),a._v(" alice-key.json\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5adb4683"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"mnemonic"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"witness poverty pulse crush era item game rose bargain quantum spawn sure way behave also basket journey worry stem entry toddler floor way bone"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xprv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tprv8ZgxMBicQKsPeAuGznXJZwfWHgWo86dFuufRBZN7ZT44UzoNG2cYmZLNLrnsm7eXhGSeccRU2nTtxunT11UkpqrRhJQefBnFJeHBddF68bg"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli key generate "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tee")]),a._v(" bob-key.json\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5fdec309"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"mnemonic"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"shiver atom february jealous spy gallery upset height captain snake tooth master ugly orbit amazing nice parrot elevator own olympic great relief ozone violin"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xprv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tprv8ZgxMBicQKsPei56wJPNt9u2132Ynncp2qXdfSHszobnyjaGjQwxQBGASUidc1unmEmpyMQ9XzLgvbN36MDW7LNziVFdXVGMrx6ckMHuRmd"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli key generate "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tee")]),a._v(" carol-key.json\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"de41e56d"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"mnemonic"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"upon bridge side tool style lounge need faculty middle nation armed corn valve that undo ribbon rent digital adapt capable embody zero shiver carpet"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"xprv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tprv8ZgxMBicQKsPf2edJLnXsF2AKwkCshCy2Z7fQD6FxiNVGsbkvpLRfxM8FSKrLqqpLFzLzVUBwgE9F5MQASrbedKCrGk1NG8oJgqYtmTLQEU"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-2-extract-private-extended-keys"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-2-extract-private-extended-keys"}},[a._v("#")]),a._v(" Step 2: Extract private extended keys")]),a._v(" "),s("p",[a._v("Here we use the "),s("code",[a._v("jq")]),a._v(" Unix command to parse the json output of the "),s("code",[a._v("bdk-cli")]),a._v(" commands.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_XPRV")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cat")]),a._v(" alice-key.json "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BOB_XPRV")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cat")]),a._v(" bob-key.json "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CAROL_XPRV")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cat")]),a._v(" carol-key.json "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),s("h3",{attrs:{id:"step-3-derive-public-extended-keys"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-3-derive-public-extended-keys"}},[a._v("#")]),a._v(" Step 3: Derive public extended keys")]),a._v(" "),s("p",[a._v("For this example we are using the "),s("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP-84"),s("OutboundLink")],1),a._v(" key path: "),s("code",[a._v("m/84h/1h/0h/0/*")]),a._v(" to derive extended public keys to share with other wallet participants.")]),a._v(" "),s("p",[a._v("Note that the "),s("code",[a._v("key derive")]),a._v(" sub-command will generate a tpub for the last hardened node in the given derivation path. You'll also notice that "),s("code",[a._v("bdk-cli")]),a._v(" will returns our tpub with the key origin (fingerprint/path) added to it (the metadata part that looks like "),s("code",[a._v("[5adb4683/84'/1'/0']")]),a._v(" 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.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_XPUB")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $ALICE_XPRV "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"m/84'/1'/0'/0\"")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".xpub"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPUB")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"\n'),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"[5adb4683/84'/1'/0']tpubDCyRBuncqwyAjSNiw1GWLmwQsWyhgPMEBpx3ZNpnCwZwf3HXerspTpaneN81KRxkwj8vjqH9pNWEPgNhen7dfE212SHfxBBbsCywxQGxvvu/0/*\"")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BOB_XPUB")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $BOB_XPRV "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"m/84'/1'/0'/0\"")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".xpub"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPUB")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"\n'),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"[5fdec309/84'/1'/0']tpubDDQcUeBH9JFtgZEsHZBhmRu8AuZ8ceJY1umnipPVEg1had2coGMCWdFBXNnZWKoCPic3EMgDZTdmkAVNoakwNZu2ESSW36rQvts6VXGx4bU/0/*\"")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CAROL_XPUB")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $CAROL_XPRV "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"m/84'/1'/0'/0\"")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".xpub"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPUB")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v('"\n'),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("\"[de41e56d/84'/1'/0']tpubDCdxmvzJ5QBjTN8oCjjyT2V58AyZvA1fkmCeZRC75QMoaHcVP2m45Bv3hmnR7ttAwkb2UNYyoXdHVt4gwBqRrJqLUU2JrM43HippxiWpHra/0/*\"")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-4-create-wallet-descriptors-for-each-participant"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-4-create-wallet-descriptors-for-each-participant"}},[a._v("#")]),a._v(" Step 4: Create wallet descriptors for each participant")]),a._v(" "),s("p",[a._v("We used the "),s("a",{attrs:{href:"https://bitcoindevkit.org/bdk-cli/playground/",target:"_blank",rel:"noopener noreferrer"}},[a._v("BDK Playground Policy Compiler"),s("OutboundLink")],1),a._v(" to compile the "),s("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[a._v("miniscript"),s("OutboundLink")],1),a._v(" policy:")]),a._v(" "),s("p",[s("code",[a._v("thresh(3,pk(Alice),pk(Bob),pk(Carol),older(2))")])]),a._v(" "),s("p",[a._v("To the "),s("a",{attrs:{href:"https://bitcoindevkit.org/descriptors/",target:"_blank",rel:"noopener noreferrer"}},[a._v("output descriptor"),s("OutboundLink")],1),a._v(":")]),a._v(" "),s("p",[s("code",[a._v("wsh(thresh(3,pk(Alice),s:pk(Bob),s:pk(Carol),sdv:older(2)))")])]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("p",[a._v("Each participant's descriptor only uses their own XPRV key plus the XPUB keys of the other participants.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_DESCRIPTOR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wsh(thresh(3,pk('),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPRV")]),a._v("/84'/1'/0'/0/*),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPUB")]),a._v('),snl:older(2)))"')]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BOB_DESCRIPTOR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wsh(thresh(3,pk('),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPRV")]),a._v("/84'/1'/0'/0/*),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPUB")]),a._v('),snl:older(2)))"')]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CAROL_DESCRIPTOR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wsh(thresh(3,pk('),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_XPUB")]),a._v("),s:pk("),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_XPRV")]),a._v("/84'/1'/0'/0/*),snl:older(2)))\"")]),a._v("\n")])])]),s("h2",{attrs:{id:"policy-a-three-signatures"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#policy-a-three-signatures"}},[a._v("#")]),a._v(" Policy A. Three signatures")]),a._v(" "),s("h3",{attrs:{id:"step-1a-create-a-testnet-segwit0-receive-address"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-1a-create-a-testnet-segwit0-receive-address"}},[a._v("#")]),a._v(" Step 1a: Create a testnet "),s("a",{attrs:{href:"https://en.bitcoin.it/wiki/Segregated_Witness",target:"_blank",rel:"noopener noreferrer"}},[a._v("segwit0"),s("OutboundLink")],1),a._v(" receive address")]),a._v(" "),s("p",[a._v("This step can be done independently by Alice, Bob, or Carol.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" get_new_address\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-2a-send-testnet-bitcoin-from-a-faucet-to-receive-address"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-2a-send-testnet-bitcoin-from-a-faucet-to-receive-address"}},[a._v("#")]),a._v(" Step 2a: Send testnet bitcoin from a faucet to receive address")]),a._v(" "),s("p",[a._v("After a faucet payment is sent, use a testnet block explorer to confirm the transaction was included in a block.")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/address/tb1qpqglt6yntay0se5vj3a7g36rql5pyzzp0w6jknfch2c0unwphsxs22g96e"),s("OutboundLink")],1)]),a._v(" "),s("h3",{attrs:{id:"step-3a-sync-participant-wallets-and-confirm-balance"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-3a-sync-participant-wallets-and-confirm-balance"}},[a._v("#")]),a._v(" Step 3a: Sync participant wallets and confirm balance")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-4a-view-wallet-spending-policies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-4a-view-wallet-spending-policies"}},[a._v("#")]),a._v(" Step 4a: View wallet spending policies")]),a._v(" "),s("p",[a._v("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..")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" policies\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"external"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"conditions"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"0"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("2")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"items"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("3")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"m"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("3")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"n"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("4")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"PARTIAL"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"ydtnup84"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"items"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"condition"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"COMPLETE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5adb4683"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"uyxvyzqt"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"SIGNATURE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"5fdec309"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"dzkmxcgu"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"SIGNATURE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fingerprint"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"de41e56d"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"ekfu5uaw"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"SIGNATURE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"contribution"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"condition"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("2")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"COMPLETE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"id"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"8kel7sdw"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"RELATIVETIMELOCK"')]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"value"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("2")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satisfaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NONE"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"threshold"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("3")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"type"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"THRESH"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"internal"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-5a-create-spending-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-5a-create-spending-transaction"}},[a._v("#")]),a._v(" Step 5a: Create spending transaction")]),a._v(" "),s("p",[a._v("The transaction can also be created by Alice, Bob, or Carol, or even an untrusted coordinator that only has all three tpubs.")]),a._v(" "),s("p",[a._v("Note that the argument provided to the --external_policy flag contains the id retrieved from the "),s("code",[a._v("policies")]),a._v(" subcommand in the above step, in this case "),s("code",[a._v("ydtnup84")]),a._v(".")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,2]}"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"details"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fees"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("169")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"height"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"received"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"sent"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"timestamp"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1614058791")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"transaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"psbt"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cHNidP8BAFIBAAAAAYx7T0cL7EoUYBEU0mSL6+DS4VQafUzJgAf0Ftlbkya5AQAAAAD/////AWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgCBH16JNfSPhmjJR75EdDB+gSCEF7tStNOLqw/k3BvA0BBXchA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxrHwhA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mrJN8IQIvNjaP+mwNC0DtgaB6ENB/DPPlbUDR6+NZ4Sw070jzOKyTfHZjUrJpaJNThyIGAi82No/6bA0LQO2BoHoQ0H8M8+VtQNHr41nhLDTvSPM4DO66tnIAAAAAAAAAACIGA3c1Ak2kcGOzOh6eRXFKfpnpzP1lzfcXIYhxFGZG51mxGFrbRoNUAACAAQAAgAAAAIAAAAAAAAAAACIGA75YDXRLDLt+eX5UsE03mIGUSsQP2MrJ9lm17cGXDw2mDEMxpeYAAAAAAAAAAAAA"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("UNSIGNED_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,2]}"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),s("h3",{attrs:{id:"step-6a-sign-and-finalize-psbts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-6a-sign-and-finalize-psbts"}},[a._v("#")]),a._v(" Step 6a: Sign and finalize PSBTs")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# ALICE SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_SIGNED_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $UNSIGNED_PSBT "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# BOB SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_BOB_SIGNED_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BOB_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $ALICE_SIGNED_PSBT "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# CAROL SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("FINAL_PSBT")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $CAROL_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $ALICE_BOB_SIGNED_PSBT "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("## PSBT is finalized")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_BOB_SIGNED_PSBT")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"is_finalized"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" true,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"psbt"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"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"')]),a._v("\n")])])]),s("h3",{attrs:{id:"step-7a-broadcast-finalized-psbt"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-7a-broadcast-finalized-psbt"}},[a._v("#")]),a._v(" Step 7a: Broadcast finalized PSBT")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" carol "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CAROL_DESCRIPTOR")]),a._v(" broadcast "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$FINAL_PSBT")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-8a-confirm-transaction-included-in-a-testnet-block"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-8a-confirm-transaction-included-in-a-testnet-block"}},[a._v("#")]),a._v(" Step 8a: Confirm transaction included in a testnet block")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/tx/3b9a7ac610afc91f1d1a0dd844e609376278fe7210c69b7ef663c5a8e8308f3e"),s("OutboundLink")],1)]),a._v(" "),s("p",[a._v("And new wallet balance is now zero.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h4",{attrs:{id:"done-"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#done-"}},[a._v("#")]),a._v(" DONE!")]),a._v(" "),s("h2",{attrs:{id:"policy-b-two-signatures-after-a-relative-time-lock"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#policy-b-two-signatures-after-a-relative-time-lock"}},[a._v("#")]),a._v(" Policy B. Two signatures after a relative time lock")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("h3",{attrs:{id:"step-1b-create-a-new-testnet-receive-address"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-1b-create-a-new-testnet-receive-address"}},[a._v("#")]),a._v(" Step 1b: Create a new testnet receive address")]),a._v(" "),s("p",[a._v("The receive address can still be generated by Alice, Bob, or Carol.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_new_address\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-2b-fund-new-address-from-testnet-faucet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-2b-fund-new-address-from-testnet-faucet"}},[a._v("#")]),a._v(" Step 2b: Fund new address from testnet faucet")]),a._v(" "),s("p",[a._v("After the faucet payment is sent, confirm using a testnet block explorer to verify the transaction was included in a block.")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/address/tb1q886w2zmtakwxpngs9kn7y0a7tvd6e24u58sse2sv92zrjpnenfhqtfnmw9"),s("OutboundLink")],1)]),a._v(" "),s("h3",{attrs:{id:"step-3b-sync-wallet-and-confirm-wallet-balance"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-3b-sync-wallet-and-confirm-wallet-balance"}},[a._v("#")]),a._v(" Step 3b: Sync wallet and confirm wallet balance")]),a._v(" "),s("p",[a._v("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.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# NO CAROL SHE LOST HER KEY!")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-4b-create-spending-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-4b-create-spending-transaction"}},[a._v("#")]),a._v(" Step 4b: Create spending transaction")]),a._v(" "),s("p",[a._v("This spending transaction uses Alice and Bob's keys plus a two block relative time-lock, see above "),s("a",{attrs:{href:"#step-4a-view-wallet-spending-policies"}},[a._v("Step 4a")]),a._v(" for the policy id. The transaction can be created by Alice or Bob.")]),a._v(" "),s("p",[a._v("A time based relative time-lock can be used instead of one based on blocks but is slightly more complicated to calculate. See\n"),s("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#specification",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP-68"),s("OutboundLink")],1),a._v(" for the details.")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,3]}"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"details"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"fees"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("169")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"height"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"received"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"sent"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10000")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"timestamp"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1614059434")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"transaction"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" null,\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"')]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v(",\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"psbt"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"cHNidP8BAFICAAAAAYmc6mhj4Cf4pcJyBvxSbCd9IB1yDGs+plzb95t7++v0AAAAAAACAAAAAWcmAAAAAAAAFgAU3RacollkleIxk+lz8my/mLCXiH0AAAAAAAEBKxAnAAAAAAAAIgAgOfTlC2vtnGDNEC2n4j++Wxusqryh4QyqDCqEOQZ5mm4BBXchAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCpprHwhAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFrJN8IQOrU70B/wo/oUUCKFQ2cIsBxx6SysE7uVwxyu0ozM4zYqyTfHZjUrJpaJNThyIGAlUVWMkNwGkCxDe4ZAcyz7HI+Vpmo4A5//OvkV33PCppGFrbRoNUAACAAQAAgAAAAIAAAAAAAQAAACIGAq9NOHBbPEdKr8IzYEomNTk1eokAkLQ9+ZMuS/OlX+nFDEMxpeYAAAAAAQAAACIGA6tTvQH/Cj+hRQIoVDZwiwHHHpLKwTu5XDHK7SjMzjNiDO66tnIAAAAAAQAAAAAA"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("UNSIGNED_PSBT2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR create_tx "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2:0 "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--external_policy")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"{'),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v("ydtnup84"),s("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[a._v('\\"')]),a._v(': [0,1,3]}"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),s("h3",{attrs:{id:"step-5b-sign-and-finalize-psbts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-5b-sign-and-finalize-psbts"}},[a._v("#")]),a._v(" Step 5b: Sign and finalize PSBTs")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# ALICE SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ALICE_SIGNED_PSBT2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $ALICE_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $UNSIGNED_PSBT2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# BOB SIGNS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("FINAL_PSBT2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BOB_DESCRIPTOR sign "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $ALICE_SIGNED_PSBT2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('".psbt"')]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# CAROL DOES *NOT* SIGN")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-6b-broadcast-finalized-psbt"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-6b-broadcast-finalized-psbt"}},[a._v("#")]),a._v(" Step 6b: Broadcast finalized PSBT")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" broadcast "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$FINAL_PSBT2")]),a._v("\nthread "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v("'main'")]),a._v(" panicked at "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('\'called `Result::unwrap()` on an `Err` value: Electrum(Protocol(String("sendrawtransaction RPC error: {\\"code\\":-26,\\"message\\":\\"non-BIP68-final\\"}")))\'')]),a._v(", src/bdk_cli.rs:168:50\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# Oops we didn't wait long enough for the relative time lock to expire")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# Try again in ~20 mins and it is successfully broadcast")]),a._v("\n\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" bob "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BOB_DESCRIPTOR")]),a._v(" broadcast "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$FINAL_PSBT2")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h3",{attrs:{id:"step-7b-view-confirmed-transaction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-7b-view-confirmed-transaction"}},[a._v("#")]),a._v(" Step 7b: View confirmed transaction")]),a._v(" "),s("p",[s("a",{attrs:{href:"https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://mempool.space/testnet/tx/6a04c60dff8eeb14dc0848c663d669c34ddc30125d9564364c9414e3ff4a7d28"),s("OutboundLink")],1)]),a._v(" "),s("p",[a._v("And wallet balance is again zero")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("bdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\nbdk-cli wallet "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" alice "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ALICE_DESCRIPTOR")]),a._v(" get_balance\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),s("h4",{attrs:{id:"done-again-"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#done-again-"}},[a._v("#")]),a._v(" Done again!")]),a._v(" "),s("p",[a._v("In this demo we showed how to receive and spend bitcoin using two different descriptor wallet policies using the "),s("code",[a._v("bdk")]),a._v(" library and "),s("code",[a._v("bdk-cli")]),a._v(" wallet tool.")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/79.0f18b068.js b/assets/js/79.61fe8f96.js similarity index 99% rename from assets/js/79.0f18b068.js rename to assets/js/79.61fe8f96.js index 74821af51c..d0601b3fb0 100644 --- a/assets/js/79.0f18b068.js +++ b/assets/js/79.61fe8f96.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[79],{436:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("The bitcoindevkit organization maintains "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/rust-hwi",target:"_blank",rel:"noopener noreferrer"}},[t._v("rust-hwi"),s("OutboundLink")],1),t._v(", a Rust wrapper around Bitcoin Core's "),s("a",{attrs:{href:"https://github.com/bitcoin-core/HWI",target:"_blank",rel:"noopener noreferrer"}},[t._v("HWI"),s("OutboundLink")],1),t._v(". rust-hwi makes it possible to use hardware wallets with BDK, which is exactly what we're going to do in this tutorial.")]),t._v(" "),s("h2",{attrs:{id:"prerequisites"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),s("p",[t._v("To follow along you'll need the "),s("a",{attrs:{href:"https://pypi.org/project/hwi/",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("hwi")]),s("OutboundLink")],1),t._v(" python package installed on your system, and a hardware wallet.")]),t._v(" "),s("p",[t._v("Never use a hardware wallet with real funds for testing! Either buy a separate one to be used only for tests, or use a hardware wallet emulator, such as:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/LedgerHQ/speculos",target:"_blank",rel:"noopener noreferrer"}},[t._v("Speculos"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://docs.trezor.io/trezor-firmware/core/emulator/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Trezor emulator"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://github.com/Coldcard/firmware",target:"_blank",rel:"noopener noreferrer"}},[t._v("Coldcard emulator"),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v("To check if "),s("code",[t._v("hwi")]),t._v(" is installed, open a python terminal and try to import it:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ python3\nPython "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.9")]),t._v(".13 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("main, May "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("17")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2022")]),t._v(", "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),t._v(":19:07"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("GCC "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("11.3")]),t._v(".0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" on linux\nType "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"help"')]),t._v(", "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"copyright"')]),t._v(", "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"credits"')]),t._v(" or "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"license"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("more")]),t._v(" information.\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("import")]),t._v(" hwilib\n")])])]),s("p",[t._v("If nothing happens, you're set! Instead, if you get a "),s("code",[t._v("ModuleNotFoundError")]),t._v(", follow the instructions in "),s("a",{attrs:{href:"https://github.com/bitcoin-core/HWI#bitcoin-hardware-wallet-interface",target:"_blank",rel:"noopener noreferrer"}},[t._v("HWI's README.md"),s("OutboundLink")],1),t._v(" for installing.")]),t._v(" "),s("p",[t._v("Warning: if you're using macOS and "),s("code",[t._v("virtualenv")]),t._v(", you "),s("em",[t._v("may")]),t._v(" encounter some problems with "),s("code",[t._v("rust-hwi")]),t._v(", as we internally use "),s("code",[t._v("PyO3")]),t._v(": https://github.com/PyO3/pyo3/issues/1741")]),t._v(" "),s("h2",{attrs:{id:"initial-setup"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initial-setup"}},[t._v("#")]),t._v(" Initial setup")]),t._v(" "),s("p",[t._v("Start by creating a new Rust project:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" init bdk-hwi\n Created binary "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("application"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" package\n$ "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-hwi\n")])])]),s("p",[t._v("Add "),s("code",[t._v("bdk")]),t._v(" with the "),s("code",[t._v("hardware-signer")]),t._v(" feature as a dependency in the "),s("code",[t._v("Cargo.toml")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("package")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("name")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-hwi"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.1.0"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("edition")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2021"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.24.0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hardware-signer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("("),s("code",[t._v("bdk")]),t._v(" re-exports "),s("code",[t._v("rust-hwi")]),t._v(" since version "),s("code",[t._v("0.24.0")]),t._v(" - if you're using "),s("code",[t._v("bdk")]),t._v(" <= "),s("code",[t._v("0.23.0")]),t._v(", you have to separately declare "),s("code",[t._v("rust-hwi")]),t._v(" as a dependency)")]),t._v(" "),s("p",[t._v("Now, open "),s("code",[t._v("src/main.rs")]),t._v(" and slightly modify the "),s("code",[t._v("fn main()")]),t._v(" method to return a "),s("code",[t._v("Result")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, world!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("and add these imports at the start of the file:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("electrum_client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("hwi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("types"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIChain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignerOrdering")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("hardwaresigner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWISigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeRate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("These little changes will come in handy later, as we won't have to care about imports or error handling.")]),t._v(" "),s("p",[t._v("Build and run the project - if everything goes smoothly it will print some warnings about the unused imports (no worries, we'll use them "),s("em",[t._v("eventually")]),t._v('), and a "Hello, world!".')]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\nwarning: unused import: "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nwarning: unused import: "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nwarning: unused import: "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nHello, world"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n\n")])])]),s("h2",{attrs:{id:"finding-the-hardware-wallet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#finding-the-hardware-wallet"}},[t._v("#")]),t._v(" Finding the hardware wallet")]),t._v(" "),s("p",[t._v("In this step we'll make sure that "),s("code",[t._v("hwi")]),t._v(" can see your hardware wallet. If you're using a physical HW, connect it to your laptop; if it's an emulator, start it.")]),t._v(" "),s("p",[t._v("We start by printing all the available hardware wallets:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Listing all the available hardware wallet devices...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" devices "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enumerate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{:?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("devices"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("When run, it should print an array of "),s("code",[t._v("HWIDevice")]),t._v(" with one element:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("HWIDevice "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("p",[t._v("If the array is empty instead, "),s("code",[t._v("hwi")]),t._v(' is having troubles recognizing your device. Common issues are: the device is locked (unlock with the pin and open the "Bitcoin" app, if needed) or the udev rules aren\'t set.')]),t._v(" "),s("h2",{attrs:{id:"receiving-funds"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#receiving-funds"}},[t._v("#")]),t._v(" Receiving funds")]),t._v(" "),s("p",[t._v("In order to be able to receive funds we need to create the BDK "),s("code",[t._v("Wallet")]),t._v(" using the HW descriptors.")]),t._v(" "),s("p",[t._v("We start by creating a "),s("code",[t._v("HWIClient")]),t._v(" from the "),s("code",[t._v("HWIDevice")]),t._v(" we found in the last step:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Listing all the available hardware wallet devices...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" devices "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enumerate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" first_device "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" devices\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("first")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"No devices found. Either plug in a hardware wallet, or start a simulator."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...and creating a client out of the first one")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("first_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIChain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Look what I found, a {}!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("model"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("We then use the "),s("code",[t._v("HWIClient")]),t._v(" to get the descriptors:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Getting the HW's public descriptors")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" descriptors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The hardware wallet\'s descriptor is: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n descriptors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("receive"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Now that we have the descriptors, we use BDK as we always do: we create a "),s("code",[t._v("Wallet")]),t._v(", we sync it, we check the balance, and if there aren't funds on it, we ask the user to send some:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("descriptors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("receive"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("descriptors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("internal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create client for Blockstream's testnet electrum server")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Syncing the wallet..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nwallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get deposit address")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" deposit_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet balances in SATs: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_total")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"Send some sats from the u01.net testnet faucet to address '{addr}'.\\nFaucet URL: https://bitcoinfaucet.uo1.net/?to={addr}\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" deposit_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Use a testnet faucet to send funds to the specified address, and then re-run the program to check that they arrived. You don't have to wait for them to be confirmed before going to the next step.")]),t._v(" "),s("h2",{attrs:{id:"spending-funds"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#spending-funds"}},[t._v("#")]),t._v(" Spending funds")]),t._v(" "),s("p",[t._v("We're going to send back the sats we just received to the testnet faucet. As always, we need to start by creating the transaction:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" return_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _details"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("drain_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("drain_to")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("return_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enable_rbf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fee_rate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeRate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat_per_vb")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("We can't just call "),s("code",[t._v("sign")]),t._v(" on the "),s("code",[t._v("psbt")]),t._v(" as we'd normally do though, as the "),s("code",[t._v("Wallet")]),t._v(" doesn't have any private keys, and doesn't even know that it's supposed to sign with the hardware wallet. (Go on and try to call "),s("code",[t._v("sign()")]),t._v(", if you're curious!)")]),t._v(" "),s("p",[t._v("We need to create a "),s("code",[t._v("HWISigner")]),t._v(" object, and then manually add it to the "),s("code",[t._v("Wallet")]),t._v(", using "),s("code",[t._v("add_signer")]),t._v(". "),s("code",[t._v("add_signer")]),t._v(" requires a "),s("code",[t._v("SignerOrdering")]),t._v(", which BDK uses to know which signer call first - in this case we just use the default, as we only have one signer.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Creating a custom signer from the device")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" custom_signer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWISigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_device")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("first_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIChain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Adding the hardware signer to the BDK wallet")]),t._v("\nwallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_signer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignerOrdering")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("custom_signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("We can now sign and broadcast "),s("code",[t._v("psbt")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// `sign` will call the hardware wallet asking for a signature")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The hardware wallet couldn\'t finalize the transaction :("')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Let\'s broadcast your tx..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" raw_transaction "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" raw_transaction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("txid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nblockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("raw_transaction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction broadcasted! TXID: {txid}.\\nExplorer URL: https://mempool.space/testnet/tx/{txid}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"conclusion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),s("p",[t._v("We just received coins on a hardware wallet and spent from it - how cool is that?!")]),t._v(" "),s("p",[t._v("See the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/master/examples/hardware_signer.rs",target:"_blank",rel:"noopener noreferrer"}},[t._v("hardware signer example"),s("OutboundLink")],1),t._v(" for the full code, and, if you have any questions or suggestions, head to our "),s("a",{attrs:{href:"https://discord.gg/dstn4dQ",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord"),s("OutboundLink")],1),t._v(". See you there!")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[79],{435:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("The bitcoindevkit organization maintains "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/rust-hwi",target:"_blank",rel:"noopener noreferrer"}},[t._v("rust-hwi"),s("OutboundLink")],1),t._v(", a Rust wrapper around Bitcoin Core's "),s("a",{attrs:{href:"https://github.com/bitcoin-core/HWI",target:"_blank",rel:"noopener noreferrer"}},[t._v("HWI"),s("OutboundLink")],1),t._v(". rust-hwi makes it possible to use hardware wallets with BDK, which is exactly what we're going to do in this tutorial.")]),t._v(" "),s("h2",{attrs:{id:"prerequisites"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),s("p",[t._v("To follow along you'll need the "),s("a",{attrs:{href:"https://pypi.org/project/hwi/",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("hwi")]),s("OutboundLink")],1),t._v(" python package installed on your system, and a hardware wallet.")]),t._v(" "),s("p",[t._v("Never use a hardware wallet with real funds for testing! Either buy a separate one to be used only for tests, or use a hardware wallet emulator, such as:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://github.com/LedgerHQ/speculos",target:"_blank",rel:"noopener noreferrer"}},[t._v("Speculos"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://docs.trezor.io/trezor-firmware/core/emulator/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Trezor emulator"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://github.com/Coldcard/firmware",target:"_blank",rel:"noopener noreferrer"}},[t._v("Coldcard emulator"),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v("To check if "),s("code",[t._v("hwi")]),t._v(" is installed, open a python terminal and try to import it:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ python3\nPython "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.9")]),t._v(".13 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("main, May "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("17")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2022")]),t._v(", "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),t._v(":19:07"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("GCC "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("11.3")]),t._v(".0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" on linux\nType "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"help"')]),t._v(", "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"copyright"')]),t._v(", "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"credits"')]),t._v(" or "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"license"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("more")]),t._v(" information.\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("import")]),t._v(" hwilib\n")])])]),s("p",[t._v("If nothing happens, you're set! Instead, if you get a "),s("code",[t._v("ModuleNotFoundError")]),t._v(", follow the instructions in "),s("a",{attrs:{href:"https://github.com/bitcoin-core/HWI#bitcoin-hardware-wallet-interface",target:"_blank",rel:"noopener noreferrer"}},[t._v("HWI's README.md"),s("OutboundLink")],1),t._v(" for installing.")]),t._v(" "),s("p",[t._v("Warning: if you're using macOS and "),s("code",[t._v("virtualenv")]),t._v(", you "),s("em",[t._v("may")]),t._v(" encounter some problems with "),s("code",[t._v("rust-hwi")]),t._v(", as we internally use "),s("code",[t._v("PyO3")]),t._v(": https://github.com/PyO3/pyo3/issues/1741")]),t._v(" "),s("h2",{attrs:{id:"initial-setup"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initial-setup"}},[t._v("#")]),t._v(" Initial setup")]),t._v(" "),s("p",[t._v("Start by creating a new Rust project:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" init bdk-hwi\n Created binary "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("application"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" package\n$ "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-hwi\n")])])]),s("p",[t._v("Add "),s("code",[t._v("bdk")]),t._v(" with the "),s("code",[t._v("hardware-signer")]),t._v(" feature as a dependency in the "),s("code",[t._v("Cargo.toml")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("package")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("name")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-hwi"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.1.0"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("edition")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2021"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.24.0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hardware-signer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("("),s("code",[t._v("bdk")]),t._v(" re-exports "),s("code",[t._v("rust-hwi")]),t._v(" since version "),s("code",[t._v("0.24.0")]),t._v(" - if you're using "),s("code",[t._v("bdk")]),t._v(" <= "),s("code",[t._v("0.23.0")]),t._v(", you have to separately declare "),s("code",[t._v("rust-hwi")]),t._v(" as a dependency)")]),t._v(" "),s("p",[t._v("Now, open "),s("code",[t._v("src/main.rs")]),t._v(" and slightly modify the "),s("code",[t._v("fn main()")]),t._v(" method to return a "),s("code",[t._v("Result")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, world!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("and add these imports at the start of the file:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("electrum_client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("hwi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("types"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIChain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignerOrdering")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("hardwaresigner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWISigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeRate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("These little changes will come in handy later, as we won't have to care about imports or error handling.")]),t._v(" "),s("p",[t._v("Build and run the project - if everything goes smoothly it will print some warnings about the unused imports (no worries, we'll use them "),s("em",[t._v("eventually")]),t._v('), and a "Hello, world!".')]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\nwarning: unused import: "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nwarning: unused import: "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nwarning: unused import: "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(".\nHello, world"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n\n")])])]),s("h2",{attrs:{id:"finding-the-hardware-wallet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#finding-the-hardware-wallet"}},[t._v("#")]),t._v(" Finding the hardware wallet")]),t._v(" "),s("p",[t._v("In this step we'll make sure that "),s("code",[t._v("hwi")]),t._v(" can see your hardware wallet. If you're using a physical HW, connect it to your laptop; if it's an emulator, start it.")]),t._v(" "),s("p",[t._v("We start by printing all the available hardware wallets:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Box")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("dyn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Listing all the available hardware wallet devices...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" devices "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enumerate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{:?}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("devices"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("When run, it should print an array of "),s("code",[t._v("HWIDevice")]),t._v(" with one element:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" run\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("HWIDevice "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("p",[t._v("If the array is empty instead, "),s("code",[t._v("hwi")]),t._v(' is having troubles recognizing your device. Common issues are: the device is locked (unlock with the pin and open the "Bitcoin" app, if needed) or the udev rules aren\'t set.')]),t._v(" "),s("h2",{attrs:{id:"receiving-funds"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#receiving-funds"}},[t._v("#")]),t._v(" Receiving funds")]),t._v(" "),s("p",[t._v("In order to be able to receive funds we need to create the BDK "),s("code",[t._v("Wallet")]),t._v(" using the HW descriptors.")]),t._v(" "),s("p",[t._v("We start by creating a "),s("code",[t._v("HWIClient")]),t._v(" from the "),s("code",[t._v("HWIDevice")]),t._v(" we found in the last step:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Listing all the available hardware wallet devices...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" devices "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enumerate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" first_device "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" devices\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("first")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"No devices found. Either plug in a hardware wallet, or start a simulator."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...and creating a client out of the first one")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("first_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIChain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Look what I found, a {}!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("model"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("We then use the "),s("code",[t._v("HWIClient")]),t._v(" to get the descriptors:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Getting the HW's public descriptors")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" descriptors "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The hardware wallet\'s descriptor is: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n descriptors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("receive"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Now that we have the descriptors, we use BDK as we always do: we create a "),s("code",[t._v("Wallet")]),t._v(", we sync it, we check the balance, and if there aren't funds on it, we ask the user to send some:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("descriptors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("receive"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("descriptors"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("internal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create client for Blockstream's testnet electrum server")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Syncing the wallet..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nwallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get deposit address")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" deposit_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("New")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" balance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_balance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet balances in SATs: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" balance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_total")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"Send some sats from the u01.net testnet faucet to address '{addr}'.\\nFaucet URL: https://bitcoinfaucet.uo1.net/?to={addr}\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" deposit_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Use a testnet faucet to send funds to the specified address, and then re-run the program to check that they arrived. You don't have to wait for them to be confirmed before going to the next step.")]),t._v(" "),s("h2",{attrs:{id:"spending-funds"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#spending-funds"}},[t._v("#")]),t._v(" Spending funds")]),t._v(" "),s("p",[t._v("We're going to send back the sats we just received to the testnet faucet. As always, we need to start by creating the transaction:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" return_address "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _details"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" builder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("drain_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("drain_to")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("return_address"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("script_pubkey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("enable_rbf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fee_rate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FeeRate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_sat_per_vb")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n builder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("We can't just call "),s("code",[t._v("sign")]),t._v(" on the "),s("code",[t._v("psbt")]),t._v(" as we'd normally do though, as the "),s("code",[t._v("Wallet")]),t._v(" doesn't have any private keys, and doesn't even know that it's supposed to sign with the hardware wallet. (Go on and try to call "),s("code",[t._v("sign()")]),t._v(", if you're curious!)")]),t._v(" "),s("p",[t._v("We need to create a "),s("code",[t._v("HWISigner")]),t._v(" object, and then manually add it to the "),s("code",[t._v("Wallet")]),t._v(", using "),s("code",[t._v("add_signer")]),t._v(". "),s("code",[t._v("add_signer")]),t._v(" requires a "),s("code",[t._v("SignerOrdering")]),t._v(", which BDK uses to know which signer call first - in this case we just use the default, as we only have one signer.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Creating a custom signer from the device")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" custom_signer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWISigner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_device")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("first_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HWIChain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Adding the hardware signer to the BDK wallet")]),t._v("\nwallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add_signer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignerOrdering")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("custom_signer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("We can now sign and broadcast "),s("code",[t._v("psbt")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// `sign` will call the hardware wallet asking for a signature")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("assert!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The hardware wallet couldn\'t finalize the transaction :("')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Let\'s broadcast your tx..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" raw_transaction "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" psbt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("extract_tx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" raw_transaction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("txid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nblockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("raw_transaction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Transaction broadcasted! TXID: {txid}.\\nExplorer URL: https://mempool.space/testnet/tx/{txid}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" txid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" txid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"conclusion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),s("p",[t._v("We just received coins on a hardware wallet and spent from it - how cool is that?!")]),t._v(" "),s("p",[t._v("See the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/master/examples/hardware_signer.rs",target:"_blank",rel:"noopener noreferrer"}},[t._v("hardware signer example"),s("OutboundLink")],1),t._v(" for the full code, and, if you have any questions or suggestions, head to our "),s("a",{attrs:{href:"https://discord.gg/dstn4dQ",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord"),s("OutboundLink")],1),t._v(". See you there!")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/80.1e8a3836.js b/assets/js/80.00db3e80.js similarity index 98% rename from assets/js/80.1e8a3836.js rename to assets/js/80.00db3e80.js index 2da74a46c8..ef3a2be453 100644 --- a/assets/js/80.1e8a3836.js +++ b/assets/js/80.00db3e80.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[80],{437:function(e,t,i){"use strict";i.r(t);var a=i(7),s=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This article explores the reasons why the Bitcoin Dev Kit Foundation supports a number of language bindings libraries as part of its core offering, and the challenges and decision tradeoffs we face along the way.")]),e._v(" "),t("p",[e._v('We build language bindings for a number of use cases. One of the most common of those rests on a belief that as time goes on, applications of all kinds will need to interact with the bitcoin protocol. Many of those will be applications that are not "bitcoin-first" like wallets, but rather other kinds of applications that simply wish to integrate payments for their users (games, chat applications, content creation, etc.). These applications already have well-developed codebases and teams, seldom built entirely in Rust (BDK\'s first and core language). Our goal is to offer these teams and applications an all-inclusive dependency they can add to whatever technology stack they are using in production, and allow the integration of bitcoin-related capabilities without the need to completely change their tech stack or require the hire of full-time bitcoin experts.')]),e._v(" "),t("p",[e._v("Why not simply use libraries that are available in the specific languages? We think the bitcoin development kit is special (of course we do!) for a few reasons:")]),e._v(" "),t("ol",[t("li",[e._v("The level of review and number of in-production applications in bitcoin that use the Rust bitcoin ecosystem of libraries is unparalleled (rust-bitcoin, rust-miniscript, and bdk).")]),e._v(" "),t("li",[e._v("For the reason above, it is most often the case that new features and BIPs are available in Rust first (taproot, miniscript, etc.) and take years to appear on other tech stacks.")])]),e._v(" "),t("h2",{attrs:{id:"awesome-producing-bindings-must-be-easy-right"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#awesome-producing-bindings-must-be-easy-right"}},[e._v("#")]),e._v(" Awesome! Producing Bindings Must Be Easy Right?")]),e._v(" "),t("p",[e._v("Along the way, "),t("em",[e._v("actually")]),e._v(" producing language bindings for a variety of languages is no easy feat. Here are some of the challenges we face:")]),e._v(" "),t("ol",[t("li",[e._v("We create bindings for many languages in one fell swoop with a Rust tool called "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("uniffi"),t("OutboundLink")],1),e._v(". The result is that for the work of 1 language, we actually get a few: Swift, Kotlin (works for JVM server-side and on Android), Java, Python. The Kotlin and Swift languages can in turn be combined to create React Native and Flutter libraries.")]),e._v(" "),t("li",[e._v("The goal of the bindings is not to provide all the complexity available in the Rust libraries (this would simply be out-of-scope for us). We basically need to strike a balance and generate a unified API that contains and combines 8 Rust libraries: rust-bitcoin, rust-miniscript, bdk_wallet, bdk_chain, bdk_file_store, and the electrum-client, esplora-client, and rpc-client libraries). This is required because it is impractical to produce bindings libraries for all of the above individually. The final bindings libraries are centered around the bdk_wallet API, and supporting its most common use cases for mobile clients.")]),e._v(" "),t("li",[e._v("Point 2 above has interesting implications: while developers using Rust can simply import any number of those libraries in their projects, we must expose as much (and as little) as is required.")]),e._v(" "),t("li",[e._v("A few caveats give us interesting puzzles we need to juggle with as we design and develop the language bindings libraries:\n"),t("ul",[t("li",[e._v('We cannot expose Rust generics using uniffi. This means that in practice, we need to remove all generics from the Rust API (either by not exposing the underlying construct or by exposing all—or the most important—of its variants as concrete structs). In this process, some of the complexity and beauty of the Rust language and Rust-based codebases is "erased".')]),e._v(" "),t("li",[e._v("Because the Rust code must be exposed in a variety of languages, some of the most Rust-specific constructs cannot be expressed in the bindings libraries. Things like functions that return tuples and tuple structs do not have Kotlin/Swift/Python equivalents, and must therefore be wrapped in some way, changing the shape of the Rust API slightly.")])])])]),e._v(" "),t("p",[t("em",[e._v("Note:")]),e._v(" The "),t("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-rn"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-flutter"),t("OutboundLink")],1),e._v(" are closely related projects. The React Native library uses the bdk-swift and bdk-android libraries and simply wraps them in a way that allows React Native users to leverage them, while the bdk-flutter library is build using a separate tool called "),t("a",{attrs:{href:""}},[e._v("rust-flutter-bridge")]),e._v(", and is not a direct descendant of the uniffi-based libraries, although it follows a similar API.")])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[80],{436:function(e,t,i){"use strict";i.r(t);var a=i(7),s=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This article explores the reasons why the Bitcoin Dev Kit Foundation supports a number of language bindings libraries as part of its core offering, and the challenges and decision tradeoffs we face along the way.")]),e._v(" "),t("p",[e._v('We build language bindings for a number of use cases. One of the most common of those rests on a belief that as time goes on, applications of all kinds will need to interact with the bitcoin protocol. Many of those will be applications that are not "bitcoin-first" like wallets, but rather other kinds of applications that simply wish to integrate payments for their users (games, chat applications, content creation, etc.). These applications already have well-developed codebases and teams, seldom built entirely in Rust (BDK\'s first and core language). Our goal is to offer these teams and applications an all-inclusive dependency they can add to whatever technology stack they are using in production, and allow the integration of bitcoin-related capabilities without the need to completely change their tech stack or require the hire of full-time bitcoin experts.')]),e._v(" "),t("p",[e._v("Why not simply use libraries that are available in the specific languages? We think the bitcoin development kit is special (of course we do!) for a few reasons:")]),e._v(" "),t("ol",[t("li",[e._v("The level of review and number of in-production applications in bitcoin that use the Rust bitcoin ecosystem of libraries is unparalleled (rust-bitcoin, rust-miniscript, and bdk).")]),e._v(" "),t("li",[e._v("For the reason above, it is most often the case that new features and BIPs are available in Rust first (taproot, miniscript, etc.) and take years to appear on other tech stacks.")])]),e._v(" "),t("h2",{attrs:{id:"awesome-producing-bindings-must-be-easy-right"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#awesome-producing-bindings-must-be-easy-right"}},[e._v("#")]),e._v(" Awesome! Producing Bindings Must Be Easy Right?")]),e._v(" "),t("p",[e._v("Along the way, "),t("em",[e._v("actually")]),e._v(" producing language bindings for a variety of languages is no easy feat. Here are some of the challenges we face:")]),e._v(" "),t("ol",[t("li",[e._v("We create bindings for many languages in one fell swoop with a Rust tool called "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("uniffi"),t("OutboundLink")],1),e._v(". The result is that for the work of 1 language, we actually get a few: Swift, Kotlin (works for JVM server-side and on Android), Java, Python. The Kotlin and Swift languages can in turn be combined to create React Native and Flutter libraries.")]),e._v(" "),t("li",[e._v("The goal of the bindings is not to provide all the complexity available in the Rust libraries (this would simply be out-of-scope for us). We basically need to strike a balance and generate a unified API that contains and combines 8 Rust libraries: rust-bitcoin, rust-miniscript, bdk_wallet, bdk_chain, bdk_file_store, and the electrum-client, esplora-client, and rpc-client libraries). This is required because it is impractical to produce bindings libraries for all of the above individually. The final bindings libraries are centered around the bdk_wallet API, and supporting its most common use cases for mobile clients.")]),e._v(" "),t("li",[e._v("Point 2 above has interesting implications: while developers using Rust can simply import any number of those libraries in their projects, we must expose as much (and as little) as is required.")]),e._v(" "),t("li",[e._v("A few caveats give us interesting puzzles we need to juggle with as we design and develop the language bindings libraries:\n"),t("ul",[t("li",[e._v('We cannot expose Rust generics using uniffi. This means that in practice, we need to remove all generics from the Rust API (either by not exposing the underlying construct or by exposing all—or the most important—of its variants as concrete structs). In this process, some of the complexity and beauty of the Rust language and Rust-based codebases is "erased".')]),e._v(" "),t("li",[e._v("Because the Rust code must be exposed in a variety of languages, some of the most Rust-specific constructs cannot be expressed in the bindings libraries. Things like functions that return tuples and tuple structs do not have Kotlin/Swift/Python equivalents, and must therefore be wrapped in some way, changing the shape of the Rust API slightly.")])])])]),e._v(" "),t("p",[t("em",[e._v("Note:")]),e._v(" The "),t("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-rn"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-flutter"),t("OutboundLink")],1),e._v(" are closely related projects. The React Native library uses the bdk-swift and bdk-android libraries and simply wraps them in a way that allows React Native users to leverage them, while the bdk-flutter library is build using a separate tool called "),t("a",{attrs:{href:""}},[e._v("rust-flutter-bridge")]),e._v(", and is not a direct descendant of the uniffi-based libraries, although it follows a similar API.")])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/85.944e7baf.js b/assets/js/85.bee02999.js similarity index 96% rename from assets/js/85.944e7baf.js rename to assets/js/85.bee02999.js index 27f93a2502..7d9d6347fa 100644 --- a/assets/js/85.944e7baf.js +++ b/assets/js/85.bee02999.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[85],{449:function(t,e,o){"use strict";o.r(e);var n=o(7),r=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"introduction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),e("p",[e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("bdk-cli")]),e("OutboundLink")],1),t._v(" is a lightweight "),e("a",{attrs:{href:"https://codewith.mu/en/tutorials/1.0/repl",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("repl")]),e("OutboundLink")],1),t._v(" wrapper over "),e("code",[t._v("bdk")]),t._v(" that comes as a command line application. It is useful for quick testing and prototyping of bdk functionalities.")]),t._v(" "),e("p",[t._v("This can also be used as an example application to create your own command line bitcoin wallet tool using bdk.")]),t._v(" "),e("p",[e("code",[t._v("bdk-cli")]),t._v(" can interface with all the blockchain backends currently supported by "),e("code",[t._v("bdk")]),t._v(", like "),e("code",[t._v("rpc")]),t._v(", "),e("code",[t._v("electrum")]),t._v(", "),e("code",[t._v("esplora")]),t._v(" and "),e("code",[t._v("compact_filters")]),t._v(".")]),t._v(" "),e("p",[t._v("Check out "),e("a",{attrs:{href:"https://docs.rs/bdk-cli/0.5.0/bdk_cli/",target:"_blank",rel:"noopener noreferrer"}},[t._v("project documentation"),e("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),e("p",[t._v("The following sections goes into more details on the installation and usage of "),e("code",[t._v("bdk-cli")]),t._v(".")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[85],{450:function(t,e,o){"use strict";o.r(e);var n=o(7),r=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"introduction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),e("p",[e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("bdk-cli")]),e("OutboundLink")],1),t._v(" is a lightweight "),e("a",{attrs:{href:"https://codewith.mu/en/tutorials/1.0/repl",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("repl")]),e("OutboundLink")],1),t._v(" wrapper over "),e("code",[t._v("bdk")]),t._v(" that comes as a command line application. It is useful for quick testing and prototyping of bdk functionalities.")]),t._v(" "),e("p",[t._v("This can also be used as an example application to create your own command line bitcoin wallet tool using bdk.")]),t._v(" "),e("p",[e("code",[t._v("bdk-cli")]),t._v(" can interface with all the blockchain backends currently supported by "),e("code",[t._v("bdk")]),t._v(", like "),e("code",[t._v("rpc")]),t._v(", "),e("code",[t._v("electrum")]),t._v(", "),e("code",[t._v("esplora")]),t._v(" and "),e("code",[t._v("compact_filters")]),t._v(".")]),t._v(" "),e("p",[t._v("Check out "),e("a",{attrs:{href:"https://docs.rs/bdk-cli/0.5.0/bdk_cli/",target:"_blank",rel:"noopener noreferrer"}},[t._v("project documentation"),e("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),e("p",[t._v("The following sections goes into more details on the installation and usage of "),e("code",[t._v("bdk-cli")]),t._v(".")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/86.5eefdee5.js b/assets/js/86.ac423664.js similarity index 88% rename from assets/js/86.5eefdee5.js rename to assets/js/86.ac423664.js index 8bcf03716f..5916a23dc1 100644 --- a/assets/js/86.5eefdee5.js +++ b/assets/js/86.ac423664.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[86],{450:function(t,s,a){"use strict";a.r(s);var r=a(7),l=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"playground"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#playground"}},[this._v("#")]),this._v(" Playground")]),this._v(" "),t("iframe",{staticClass:"playground",staticStyle:{height:"1100px"},attrs:{src:"/bdk-cli/playground/playground.html"}})])}),[],!1,null,null,null);s.default=l.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[86],{449:function(t,s,a){"use strict";a.r(s);var r=a(7),l=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"playground"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#playground"}},[this._v("#")]),this._v(" Playground")]),this._v(" "),t("iframe",{staticClass:"playground",staticStyle:{height:"1100px"},attrs:{src:"/bdk-cli/playground/playground.html"}})])}),[],!1,null,null,null);s.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/94.bff8e7bd.js b/assets/js/94.78a1ba7f.js similarity index 98% rename from assets/js/94.bff8e7bd.js rename to assets/js/94.78a1ba7f.js index 39f8017d83..59fa8ee303 100644 --- a/assets/js/94.bff8e7bd.js +++ b/assets/js/94.78a1ba7f.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[94],{459:function(e,t,r){"use strict";r.r(t);var o=r(7),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"grants-program"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#grants-program"}},[e._v("#")]),e._v(" Grants Program")]),e._v(" "),t("p",[e._v("One of the primary purposes of the BDK Foundation is to support the ongoing development and maintenance of the BDK suite of open source software. To this end the BDK Foundation funds open source developers working on BDK and related projects via full-time and project based grants.")]),e._v(" "),t("h2",{attrs:{id:"grant-requirements"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#grant-requirements"}},[e._v("#")]),e._v(" Grant Requirements")]),e._v(" "),t("p",[e._v("Below is a list of general requirements the BDK Foundation looks for in grant applicants. These requirements may be demonstrated via any open source project you have contributed to. In particular through your public work on PR reviews, PRs, issues, team discussions, and current or prior side projects. We also consider work you've done as part of bitcoin development training programs (eg. Chaincode Labs, Base58, etc.) and related professional work experience.")]),e._v(" "),t("ul",[t("li",[e._v("Mature team player who communicates well and supports fellow team members.")]),e._v(" "),t("li",[e._v("Supports the overall bitcoin mission, in particular to improve individuals financial privacy and autonomy.")]),e._v(" "),t("li",[e._v("Understands bitcoin on-chain protocols and technology.")]),e._v(" "),t("li",[e._v("Helps train/mentor/onboard others to BDK, bitcoin, or related software development.")]),e._v(" "),t("li",[e._v("Helps supports a project outside of coding; for example user support, maintaining docs, CI, and managing releases.")])]),e._v(" "),t("p",[e._v("Bonus/optional:")]),e._v(" "),t("ul",[t("li",[e._v("Likely in the future to start or work for a project or company using BDK.")]),e._v(" "),t("li",[e._v("Understands/has experience with related protocols, eg. Lightning, e-cash.")]),e._v(" "),t("li",[e._v("Active in your local bitcoin community (eg. bitdevs, meetups, workshops).")]),e._v(" "),t("li",[e._v("From a geographical region not currently represented on the team.")])]),e._v(" "),t("h2",{attrs:{id:"full-time-grants"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#full-time-grants"}},[e._v("#")]),e._v(" Full-time grants")]),e._v(" "),t("p",[e._v("Full-time grants are for developers who are dedicating most of their work time to improving and maintaining bitcoin open source software, and in particular BDK and supporting projects.")]),e._v(" "),t("p",[e._v("The core "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("bdk")]),t("OutboundLink")],1),e._v(" repo projects are written in Rust with mobile and language bindings (Swift, Kotlin, Python) provided by the "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("bdk-ffi")]),t("OutboundLink")],1),e._v(" repo projects. Grantees should have strong Rust and/or mobile and language bindings skills.")]),e._v(" "),t("h3",{attrs:{id:"rust"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust"}},[e._v("#")]),e._v(" Rust")]),e._v(" "),t("p",[e._v("Additional traits that are a plus for full-time Rust developer grants:")]),e._v(" "),t("ul",[t("li",[e._v("Solid Rust development and API use and design experience.")]),e._v(" "),t("li",[e._v("A vision for how to maintain and improve the overall BDK Rust codebase.")]),e._v(" "),t("li",[e._v("A proposal for new or existing BDK Rust features or modules you want to improve and maintain.")]),e._v(" "),t("li",[e._v("Engaged with upstream projects, eg. rust-bitcoin, rust-miniscript, uniffi-rs, etc.")]),e._v(" "),t("li",[e._v("Engaged with downstream projects.")])]),e._v(" "),t("h3",{attrs:{id:"mobile-language-bindings"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mobile-language-bindings"}},[e._v("#")]),e._v(" Mobile / language bindings")]),e._v(" "),t("p",[e._v("Additional traits that are a plus for full-time mobile/language bindings grants:")]),e._v(" "),t("ul",[t("li",[e._v("Solid mobile development and app design experience (Android, iOS).")]),e._v(" "),t("li",[e._v("Kotlin, Swift, and/or Python development and API use and design experience.")]),e._v(" "),t("li",[e._v("Rust development experience and/or willingness to learn.")]),e._v(" "),t("li",[e._v("Vision for how to best support all BDK based app developers.")]),e._v(" "),t("li",[e._v("Engaged with the bitcoin app design community.")])]),e._v(" "),t("h2",{attrs:{id:"project-grants"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#project-grants"}},[e._v("#")]),e._v(" Project grants")]),e._v(" "),t("p",[e._v("Project grants are for contributors who are able to focus part-time for at least three months on a project to improve BDK or a supporting project.")]),e._v(" "),t("p",[e._v("Additional traits that are a plus for project grants:")]),e._v(" "),t("ul",[t("li",[e._v("A project proposal that clearly supports the BDK mission.")]),e._v(" "),t("li",[e._v("The project doesn't have to be coding, it could be research, testing, docs, etc.")]),e._v(" "),t("li",[e._v("The project can be completed in 3 months (one quarter).")])]),e._v(" "),t("h2",{attrs:{id:"applying"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#applying"}},[e._v("#")]),e._v(" Applying")]),e._v(" "),t("p",[e._v("To apply for a full-time or project grant please send your proposal to: "),t("a",{attrs:{href:"mailto:grants@bitcoindevkit.org"}},[e._v("grants@bitcoindevkit.org")])])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[94],{458:function(e,t,r){"use strict";r.r(t);var o=r(7),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"grants-program"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#grants-program"}},[e._v("#")]),e._v(" Grants Program")]),e._v(" "),t("p",[e._v("One of the primary purposes of the BDK Foundation is to support the ongoing development and maintenance of the BDK suite of open source software. To this end the BDK Foundation funds open source developers working on BDK and related projects via full-time and project based grants.")]),e._v(" "),t("h2",{attrs:{id:"grant-requirements"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#grant-requirements"}},[e._v("#")]),e._v(" Grant Requirements")]),e._v(" "),t("p",[e._v("Below is a list of general requirements the BDK Foundation looks for in grant applicants. These requirements may be demonstrated via any open source project you have contributed to. In particular through your public work on PR reviews, PRs, issues, team discussions, and current or prior side projects. We also consider work you've done as part of bitcoin development training programs (eg. Chaincode Labs, Base58, etc.) and related professional work experience.")]),e._v(" "),t("ul",[t("li",[e._v("Mature team player who communicates well and supports fellow team members.")]),e._v(" "),t("li",[e._v("Supports the overall bitcoin mission, in particular to improve individuals financial privacy and autonomy.")]),e._v(" "),t("li",[e._v("Understands bitcoin on-chain protocols and technology.")]),e._v(" "),t("li",[e._v("Helps train/mentor/onboard others to BDK, bitcoin, or related software development.")]),e._v(" "),t("li",[e._v("Helps supports a project outside of coding; for example user support, maintaining docs, CI, and managing releases.")])]),e._v(" "),t("p",[e._v("Bonus/optional:")]),e._v(" "),t("ul",[t("li",[e._v("Likely in the future to start or work for a project or company using BDK.")]),e._v(" "),t("li",[e._v("Understands/has experience with related protocols, eg. Lightning, e-cash.")]),e._v(" "),t("li",[e._v("Active in your local bitcoin community (eg. bitdevs, meetups, workshops).")]),e._v(" "),t("li",[e._v("From a geographical region not currently represented on the team.")])]),e._v(" "),t("h2",{attrs:{id:"full-time-grants"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#full-time-grants"}},[e._v("#")]),e._v(" Full-time grants")]),e._v(" "),t("p",[e._v("Full-time grants are for developers who are dedicating most of their work time to improving and maintaining bitcoin open source software, and in particular BDK and supporting projects.")]),e._v(" "),t("p",[e._v("The core "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("bdk")]),t("OutboundLink")],1),e._v(" repo projects are written in Rust with mobile and language bindings (Swift, Kotlin, Python) provided by the "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("bdk-ffi")]),t("OutboundLink")],1),e._v(" repo projects. Grantees should have strong Rust and/or mobile and language bindings skills.")]),e._v(" "),t("h3",{attrs:{id:"rust"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust"}},[e._v("#")]),e._v(" Rust")]),e._v(" "),t("p",[e._v("Additional traits that are a plus for full-time Rust developer grants:")]),e._v(" "),t("ul",[t("li",[e._v("Solid Rust development and API use and design experience.")]),e._v(" "),t("li",[e._v("A vision for how to maintain and improve the overall BDK Rust codebase.")]),e._v(" "),t("li",[e._v("A proposal for new or existing BDK Rust features or modules you want to improve and maintain.")]),e._v(" "),t("li",[e._v("Engaged with upstream projects, eg. rust-bitcoin, rust-miniscript, uniffi-rs, etc.")]),e._v(" "),t("li",[e._v("Engaged with downstream projects.")])]),e._v(" "),t("h3",{attrs:{id:"mobile-language-bindings"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mobile-language-bindings"}},[e._v("#")]),e._v(" Mobile / language bindings")]),e._v(" "),t("p",[e._v("Additional traits that are a plus for full-time mobile/language bindings grants:")]),e._v(" "),t("ul",[t("li",[e._v("Solid mobile development and app design experience (Android, iOS).")]),e._v(" "),t("li",[e._v("Kotlin, Swift, and/or Python development and API use and design experience.")]),e._v(" "),t("li",[e._v("Rust development experience and/or willingness to learn.")]),e._v(" "),t("li",[e._v("Vision for how to best support all BDK based app developers.")]),e._v(" "),t("li",[e._v("Engaged with the bitcoin app design community.")])]),e._v(" "),t("h2",{attrs:{id:"project-grants"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#project-grants"}},[e._v("#")]),e._v(" Project grants")]),e._v(" "),t("p",[e._v("Project grants are for contributors who are able to focus part-time for at least three months on a project to improve BDK or a supporting project.")]),e._v(" "),t("p",[e._v("Additional traits that are a plus for project grants:")]),e._v(" "),t("ul",[t("li",[e._v("A project proposal that clearly supports the BDK mission.")]),e._v(" "),t("li",[e._v("The project doesn't have to be coding, it could be research, testing, docs, etc.")]),e._v(" "),t("li",[e._v("The project can be completed in 3 months (one quarter).")])]),e._v(" "),t("h2",{attrs:{id:"applying"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#applying"}},[e._v("#")]),e._v(" Applying")]),e._v(" "),t("p",[e._v("To apply for a full-time or project grant please send your proposal to: "),t("a",{attrs:{href:"mailto:grants@bitcoindevkit.org"}},[e._v("grants@bitcoindevkit.org")])])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/95.8216e261.js b/assets/js/95.ef892223.js similarity index 90% rename from assets/js/95.8216e261.js rename to assets/js/95.ef892223.js index 89abb17fa2..d2fed73351 100644 --- a/assets/js/95.8216e261.js +++ b/assets/js/95.ef892223.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[95],{458:function(t,o,i){"use strict";i.r(o);var n=i(7),e=Object(n.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"bitcoin-dev-kit-foundation"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-foundation"}},[this._v("#")]),this._v(" Bitcoin Dev Kit Foundation")]),this._v(" "),t("p",[this._v("The Bitcoin Dev Kit Foundation is established as a US non-profit corporation to promote the development of, public access to and adoption of the free and open source Bitcoin Dev Kit (BDK) library software.")])])}),[],!1,null,null,null);o.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[95],{460:function(t,o,i){"use strict";i.r(o);var n=i(7),e=Object(n.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"bitcoin-dev-kit-foundation"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-foundation"}},[this._v("#")]),this._v(" Bitcoin Dev Kit Foundation")]),this._v(" "),t("p",[this._v("The Bitcoin Dev Kit Foundation is established as a US non-profit corporation to promote the development of, public access to and adoption of the free and open source Bitcoin Dev Kit (BDK) library software.")])])}),[],!1,null,null,null);o.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/96.1fc7dd90.js b/assets/js/96.68e5ddd3.js similarity index 96% rename from assets/js/96.1fc7dd90.js rename to assets/js/96.68e5ddd3.js index d048930d66..5f952db101 100644 --- a/assets/js/96.1fc7dd90.js +++ b/assets/js/96.68e5ddd3.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[96],{460:function(t,a,r){"use strict";r.r(a);var s=r(7),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"members"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#members"}},[t._v("#")]),t._v(" Members")]),t._v(" "),a("p",[t._v("The Bitcoin Dev Kit project is proudly supported by the Bitcoin Dev Kit Foundation and its members.")]),t._v(" "),a("div",{staticStyle:{"text-align":"left","margin-bottom":"2rem"}},[a("a",{staticStyle:{display:"inline-block","background-color":"var(--docs-primary-dark)",color:"var(--docs-dark)",padding:"10px 20px","text-decoration":"none","border-radius":"5px","font-weight":"bold"},attrs:{href:"/foundation/become-a-member"}},[t._v("Become A Member")])]),t._v(" "),a("h2",{attrs:{id:"platinum"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#platinum"}},[t._v("#")]),t._v(" Platinum")]),t._v(" "),a("div",{staticClass:"members"},[a("div",{staticClass:"row"},[a("a",{attrs:{href:"https://spiral.xyz/",target:"_blank",rel:"nofollow noopener"}},[a("img",{attrs:{src:"/img/spiral.svg",alt:"Spiral"}}),t._v("\n Spiral\n ")])])]),t._v(" "),a("br"),t._v(" "),a("h2",{attrs:{id:"gold"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#gold"}},[t._v("#")]),t._v(" Gold")]),t._v(" "),a("div",{staticClass:"members"},[a("div",{staticClass:"row"},[a("a",{attrs:{href:"https://opensats.org/",target:"_blank",rel:"nofollow noopener"}},[a("img",{attrs:{src:"/img/opensats.png",alt:"OpenSats"}}),t._v("\n OpenSats\n ")])])]),t._v(" "),a("br"),t._v(" "),a("h2",{attrs:{id:"silver"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#silver"}},[t._v("#")]),t._v(" Silver")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[96],{459:function(t,a,r){"use strict";r.r(a);var s=r(7),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"members"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#members"}},[t._v("#")]),t._v(" Members")]),t._v(" "),a("p",[t._v("The Bitcoin Dev Kit project is proudly supported by the Bitcoin Dev Kit Foundation and its members.")]),t._v(" "),a("div",{staticStyle:{"text-align":"left","margin-bottom":"2rem"}},[a("a",{staticStyle:{display:"inline-block","background-color":"var(--docs-primary-dark)",color:"var(--docs-dark)",padding:"10px 20px","text-decoration":"none","border-radius":"5px","font-weight":"bold"},attrs:{href:"/foundation/become-a-member"}},[t._v("Become A Member")])]),t._v(" "),a("h2",{attrs:{id:"platinum"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#platinum"}},[t._v("#")]),t._v(" Platinum")]),t._v(" "),a("div",{staticClass:"members"},[a("div",{staticClass:"row"},[a("a",{attrs:{href:"https://spiral.xyz/",target:"_blank",rel:"nofollow noopener"}},[a("img",{attrs:{src:"/img/spiral.svg",alt:"Spiral"}}),t._v("\n Spiral\n ")])])]),t._v(" "),a("br"),t._v(" "),a("h2",{attrs:{id:"gold"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#gold"}},[t._v("#")]),t._v(" Gold")]),t._v(" "),a("div",{staticClass:"members"},[a("div",{staticClass:"row"},[a("a",{attrs:{href:"https://opensats.org/",target:"_blank",rel:"nofollow noopener"}},[a("img",{attrs:{src:"/img/opensats.png",alt:"OpenSats"}}),t._v("\n OpenSats\n ")])])]),t._v(" "),a("br"),t._v(" "),a("h2",{attrs:{id:"silver"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#silver"}},[t._v("#")]),t._v(" Silver")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/app.b7fe13ec.js b/assets/js/app.f3740f7e.js similarity index 73% rename from assets/js/app.b7fe13ec.js rename to assets/js/app.f3740f7e.js index ab3aff5346..c1025fcd75 100644 --- a/assets/js/app.b7fe13ec.js +++ b/assets/js/app.f3740f7e.js @@ -1,4 +1,4 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(t){function e(e){for(var i,a,c=e[0],l=e[1],s=e[2],d=0,u=[];d
'};function o(t,e,n){return tn?n:t}function r(t){return 100*(-1+t)}n.configure=function(t){var e,n;for(e in t)void 0!==(n=t[e])&&t.hasOwnProperty(e)&&(i[e]=n);return this},n.status=null,n.set=function(t){var e=n.isStarted();t=o(t,i.minimum,1),n.status=1===t?null:t;var l=n.render(!e),s=l.querySelector(i.barSelector),p=i.speed,d=i.easing;return l.offsetWidth,a((function(e){""===i.positionUsing&&(i.positionUsing=n.getPositioningCSS()),c(s,function(t,e,n){var o;return(o="translate3d"===i.positionUsing?{transform:"translate3d("+r(t)+"%,0,0)"}:"translate"===i.positionUsing?{transform:"translate("+r(t)+"%,0)"}:{"margin-left":r(t)+"%"}).transition="all "+e+"ms "+n,o}(t,p,d)),1===t?(c(l,{transition:"none",opacity:1}),l.offsetWidth,setTimeout((function(){c(l,{transition:"all "+p+"ms linear",opacity:0}),setTimeout((function(){n.remove(),e()}),p)}),p)):setTimeout(e,p)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var t=function(){setTimeout((function(){n.status&&(n.trickle(),t())}),i.trickleSpeed)};return i.trickle&&t(),this},n.done=function(t){return t||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(t){var e=n.status;return e?("number"!=typeof t&&(t=(1-e)*o(Math.random()*e,.1,.95)),e=o(e+t,0,.994),n.set(e)):n.start()},n.trickle=function(){return n.inc(Math.random()*i.trickleRate)},t=0,e=0,n.promise=function(i){return i&&"resolved"!==i.state()?(0===e&&n.start(),t++,e++,i.always((function(){0==--e?(t=0,n.done()):n.set((t-e)/t)})),this):this},n.render=function(t){if(n.isRendered())return document.getElementById("nprogress");s(document.documentElement,"nprogress-busy");var e=document.createElement("div");e.id="nprogress",e.innerHTML=i.template;var o,a=e.querySelector(i.barSelector),l=t?"-100":r(n.status||0),p=document.querySelector(i.parent);return c(a,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),i.showSpinner||(o=e.querySelector(i.spinnerSelector))&&u(o),p!=document.body&&s(p,"nprogress-custom-parent"),p.appendChild(e),e},n.remove=function(){p(document.documentElement,"nprogress-busy"),p(document.querySelector(i.parent),"nprogress-custom-parent");var t=document.getElementById("nprogress");t&&u(t)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var t=document.body.style,e="WebkitTransform"in t?"Webkit":"MozTransform"in t?"Moz":"msTransform"in t?"ms":"OTransform"in t?"O":"";return e+"Perspective"in t?"translate3d":e+"Transform"in t?"translate":"margin"};var a=function(){var t=[];function e(){var n=t.shift();n&&n(e)}return function(n){t.push(n),1==t.length&&e()}}(),c=function(){var t=["Webkit","O","Moz","ms"],e={};function n(n){return n=n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(t,e){return e.toUpperCase()})),e[n]||(e[n]=function(e){var n=document.body.style;if(e in n)return e;for(var i,o=t.length,r=e.charAt(0).toUpperCase()+e.slice(1);o--;)if((i=t[o]+r)in n)return i;return e}(n))}function i(t,e,i){e=n(e),t.style[e]=i}return function(t,e){var n,o,r=arguments;if(2==r.length)for(n in e)void 0!==(o=e[n])&&e.hasOwnProperty(n)&&i(t,n,o);else i(t,r[1],r[2])}}();function l(t,e){return("string"==typeof t?t:d(t)).indexOf(" "+e+" ")>=0}function s(t,e){var n=d(t),i=n+e;l(n,e)||(t.className=i.substring(1))}function p(t,e){var n,i=d(t);l(t,e)&&(n=i.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))}function d(t){return(" "+(t.className||"")+" ").replace(/\s+/gi," ")}function u(t){t&&t.parentNode&&t.parentNode.removeChild(t)}return n})?i.call(e,n,e,t):i)||(t.exports=o)},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e){t.exports=function(t){return t}},function(t,e,n){"use strict";var i=n(0),o=n(54).f,r=n(13),a=n(96),c=n(34),l=n(69),s=n(135);t.exports=function(t,e){var n,p,d,u,g,h=t.target,m=t.global,f=t.stat;if(n=m?i:f?i[h]||c(h,{}):i[h]&&i[h].prototype)for(p in e){if(u=e[p],d=t.dontCallGetSet?(g=o(n,p))&&g.value:n[p],!s(m?p:h+(f?".":"#")+p,t.forced)&&void 0!==d){if(typeof u==typeof d)continue;l(u,d)}(t.sham||d&&d.sham)&&r(u,"sham",!0),a(n,p,u,t)}}},function(t,e,n){"use strict";var i=n(27),o=Function.prototype.call;t.exports=i?o.bind(o):function(){return o.apply(o,arguments)}},function(t,e,n){"use strict";var i=n(3);t.exports=!i((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},function(t,e,n){"use strict";t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){"use strict";var i=n(55),o=n(56);t.exports=function(t){return i(o(t))}},function(t,e,n){"use strict";var i=n(0),o=n(1),r=function(t){return o(t)?t:void 0};t.exports=function(t,e){return arguments.length<2?r(i[t]):i[t]&&i[t][e]}},function(t,e,n){"use strict";var i=n(1),o=n(117),r=TypeError;t.exports=function(t){if(i(t))return t;throw new r(o(t)+" is not a function")}},function(t,e,n){"use strict";var i=n(0),o=n(64),r=n(9),a=n(66),c=n(62),l=n(61),s=i.Symbol,p=o("wks"),d=l?s.for||s:s&&s.withoutSetter||a;t.exports=function(t){return r(p,t)||(p[t]=c&&r(s,t)?s[t]:d("Symbol."+t)),p[t]}},function(t,e,n){"use strict";var i=n(65),o=n(0),r=n(34),a=t.exports=o["__core-js_shared__"]||r("__core-js_shared__",{});(a.versions||(a.versions=[])).push({version:"3.36.0",mode:i?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.36.0/LICENSE",source:"https://github.com/zloirock/core-js"})},function(t,e,n){"use strict";var i=n(0),o=Object.defineProperty;t.exports=function(t,e){try{o(i,t,{value:e,configurable:!0,writable:!0})}catch(n){i[t]=e}return e}},function(t,e,n){"use strict";var i=n(56),o=Object;t.exports=function(t){return o(i(t))}},function(t,e,n){"use strict";var i=n(8),o=String,r=TypeError;t.exports=function(t){if(i(t))return t;throw new r(o(t)+" is not an object")}},function(t,e,n){"use strict";var i=n(132);t.exports=function(t){return i(t.length)}},function(t,e,n){var i=n(158),o=n(11),r=Object.prototype,a=r.hasOwnProperty,c=r.propertyIsEnumerable,l=i(function(){return arguments}())?i:function(t){return o(t)&&a.call(t,"callee")&&!c.call(t,"callee")};t.exports=l},function(t,e,n){var i=n(10)(n(6),"Map");t.exports=i},function(t,e,n){var i=n(177),o=n(184),r=n(186),a=n(187),c=n(188);function l(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}},function(t,e,n){var i=n(4),o=n(44),r=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,a=/^\w*$/;t.exports=function(t,e){if(i(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!o(t))||(a.test(t)||!r.test(t)||null!=e&&t in Object(e))}},function(t,e,n){var i=n(12),o=n(11);t.exports=function(t){return"symbol"==typeof t||o(t)&&"[object Symbol]"==i(t)}},function(t,e,n){t.exports=function(){"use strict";var t=6e4,e=36e5,n="millisecond",i="second",o="minute",r="hour",a="day",c="week",l="month",s="quarter",p="year",d="date",u="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,h=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},f=function(t,e,n){var i=String(t);return!i||i.length>=e?t:""+Array(e+1-i.length).join(n)+t},v={s:f,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),i=Math.floor(n/60),o=n%60;return(e<=0?"+":"-")+f(i,2,"0")+":"+f(o,2,"0")},m:function t(e,n){if(e.date()1)return t(a[0])}else{var c=e.name;y[c]=e,o=c}return!i&&o&&(b=o),o||!i&&b},B=function(t,e){if(k(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new x(n)},D=v;D.l=_,D.i=k,D.w=function(t,e){return B(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var x=function(){function m(t){this.$L=_(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[w]=!0}var f=m.prototype;return f.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(D.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var i=e.match(g);if(i){var o=i[2]-1||0,r=(i[7]||"0").substring(0,3);return n?new Date(Date.UTC(i[1],o,i[3]||1,i[4]||0,i[5]||0,i[6]||0,r)):new Date(i[1],o,i[3]||1,i[4]||0,i[5]||0,i[6]||0,r)}}return new Date(e)}(t),this.init()},f.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},f.$utils=function(){return D},f.isValid=function(){return!(this.$d.toString()===u)},f.isSame=function(t,e){var n=B(t);return this.startOf(e)<=n&&n<=this.endOf(e)},f.isAfter=function(t,e){return B(t)-1&&t%1==0&&t79&&a<83||!r("reduce")},{reduce:function(t){var e=arguments.length;return o(this,t,e,e>1?arguments[1]:void 0)}})},function(t,e,n){"use strict";var i=n(5),o=n(26),r=n(113),a=n(28),c=n(29),l=n(58),s=n(9),p=n(67),d=Object.getOwnPropertyDescriptor;e.f=i?d:function(t,e){if(t=c(t),e=l(e),p)try{return d(t,e)}catch(t){}if(s(t,e))return a(!o(r.f,t,e),t[e])}},function(t,e,n){"use strict";var i=n(2),o=n(3),r=n(17),a=Object,c=i("".split);t.exports=o((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"===r(t)?c(t,""):a(t)}:a},function(t,e,n){"use strict";var i=n(57),o=TypeError;t.exports=function(t){if(i(t))throw new o("Can't call method on "+t);return t}},function(t,e,n){"use strict";t.exports=function(t){return null==t}},function(t,e,n){"use strict";var i=n(114),o=n(59);t.exports=function(t){var e=i(t,"string");return o(e)?e:e+""}},function(t,e,n){"use strict";var i=n(30),o=n(1),r=n(60),a=n(61),c=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=i("Symbol");return o(e)&&r(e.prototype,c(t))}},function(t,e,n){"use strict";var i=n(2);t.exports=i({}.isPrototypeOf)},function(t,e,n){"use strict";var i=n(62);t.exports=i&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(t,e,n){"use strict";var i=n(63),o=n(3),r=n(0).String;t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol("symbol detection");return!r(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&i&&i<41}))},function(t,e,n){"use strict";var i,o,r=n(0),a=n(115),c=r.process,l=r.Deno,s=c&&c.versions||l&&l.version,p=s&&s.v8;p&&(o=(i=p.split("."))[0]>0&&i[0]<4?1:+(i[0]+i[1])),!o&&a&&(!(i=a.match(/Edge\/(\d+)/))||i[1]>=74)&&(i=a.match(/Chrome\/(\d+)/))&&(o=+i[1]),t.exports=o},function(t,e,n){"use strict";var i=n(33);t.exports=function(t,e){return i[t]||(i[t]=e||{})}},function(t,e,n){"use strict";t.exports=!1},function(t,e,n){"use strict";var i=n(2),o=0,r=Math.random(),a=i(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++o+r,36)}},function(t,e,n){"use strict";var i=n(5),o=n(3),r=n(119);t.exports=!i&&!o((function(){return 7!==Object.defineProperty(r("div"),"a",{get:function(){return 7}}).a}))},function(t,e,n){"use strict";t.exports={}},function(t,e,n){"use strict";var i=n(9),o=n(126),r=n(54),a=n(15);t.exports=function(t,e,n){for(var c=o(e),l=a.f,s=r.f,p=0;pp))return!1;var u=l.get(t),g=l.get(e);if(u&&g)return u==e&&g==t;var h=-1,m=!0,f=2&n?new i:void 0;for(l.set(t,e),l.set(e,t);++h=0&&Math.floor(e)===e&&isFinite(t)}function m(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function f(t){return null==t?"":Array.isArray(t)||u(t)&&t.toString===d?JSON.stringify(t,v,2):String(t)}function v(t,e){return e&&e.__v_isRef?e.value:e}function b(t){var e=parseFloat(t);return isNaN(e)?t:e}function y(t,e){for(var n=Object.create(null),i=t.split(","),o=0;o-1)return t.splice(i,1)}}var _=Object.prototype.hasOwnProperty;function B(t,e){return _.call(t,e)}function D(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var x=/-(\w)/g,P=D((function(t){return t.replace(x,(function(t,e){return e?e.toUpperCase():""}))})),K=D((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),S=/\B([A-Z])/g,T=D((function(t){return t.replace(S,"-$1").toLowerCase()}));var O=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var i=arguments.length;return i?i>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function C(t,e){e=e||0;for(var n=t.length-e,i=new Array(n);n--;)i[n]=t[n+e];return i}function F(t,e){for(var n in e)t[n]=e[n];return t}function A(t){for(var e={},n=0;n0,Y=Q&&Q.indexOf("edge/")>0;Q&&Q.indexOf("android");var tt=Q&&/iphone|ipad|ipod|ios/.test(Q);Q&&/chrome\/\d+/.test(Q),Q&&/phantomjs/.test(Q);var et,nt=Q&&Q.match(/firefox\/(\d+)/),it={}.watch,ot=!1;if(Z)try{var rt={};Object.defineProperty(rt,"passive",{get:function(){ot=!0}}),window.addEventListener("test-passive",null,rt)}catch(t){}var at=function(){return void 0===et&&(et=!Z&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),et},ct=Z&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function lt(t){return"function"==typeof t&&/native code/.test(t.toString())}var st,pt="undefined"!=typeof Symbol&<(Symbol)&&"undefined"!=typeof Reflect&<(Reflect.ownKeys);st="undefined"!=typeof Set&<(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var dt=null;function ut(t){void 0===t&&(t=null),t||dt&&dt._scope.off(),dt=t,t&&t._scope.on()}var gt=function(){function t(t,e,n,i,o,r,a,c){this.tag=t,this.data=e,this.children=n,this.text=i,this.elm=o,this.ns=void 0,this.context=r,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=c,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),ht=function(t){void 0===t&&(t="");var e=new gt;return e.text=t,e.isComment=!0,e};function mt(t){return new gt(void 0,void 0,void 0,String(t))}function ft(t){var e=new gt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}"function"==typeof SuppressedError&&SuppressedError;var vt=0,bt=[],yt=function(){function t(){this._pending=!1,this.id=vt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,bt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,i=e.length;n0&&(Qt((s=t(s,"".concat(n||"","_").concat(i)))[0])&&Qt(d)&&(u[p]=mt(d.text+s[0].text),s.shift()),u.push.apply(u,s)):l(s)?Qt(d)?u[p]=mt(d.text+s):""!==s&&u.push(mt(s)):Qt(s)&&Qt(d)?u[p]=mt(d.text+s.text):(c(e._isVList)&&a(s.tag)&&r(s.key)&&a(n)&&(s.key="__vlist".concat(n,"_").concat(i,"__")),u.push(s)));return u}(t):void 0}function Qt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Xt(t,e){var n,i,r,c,l=null;if(o(t)||"string"==typeof t)for(l=new Array(t.length),n=0,i=t.length;n0,c=e?!!e.$stable:!a,l=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(c&&o&&o!==i&&l===o.$key&&!a&&!o.$hasNormal)return o;for(var s in r={},e)e[s]&&"$"!==s[0]&&(r[s]=fe(t,n,s,e[s]))}else r={};for(var p in n)p in r||(r[p]=ve(n,p));return e&&Object.isExtensible(e)&&(e._normalized=r),H(r,"$stable",c),H(r,"$key",l),H(r,"$hasNormal",a),r}function fe(t,e,n,i){var r=function(){var e=dt;ut(t);var n=arguments.length?i.apply(null,arguments):i({}),r=(n=n&&"object"==typeof n&&!o(n)?[n]:Zt(n))&&n[0];return ut(e),n&&(!r||1===n.length&&r.isComment&&!he(r))?void 0:n};return i.proxy&&Object.defineProperty(e,n,{get:r,enumerable:!0,configurable:!0}),r}function ve(t,e){return function(){return t[e]}}function be(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),ye(e,t.$attrs,i,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ye(t._listenersProxy={},t.$listeners,i,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||ke(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:O(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return Ut(t,e,n)}))}}}function ye(t,e,n,i,o){var r=!1;for(var a in e)a in t?e[a]!==n[a]&&(r=!0):(r=!0,we(t,a,i,o));for(var a in t)a in e||(r=!0,delete t[a]);return r}function we(t,e,n,i){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[i][e]}})}function ke(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var _e=null;function Be(t,e){return(t.__esModule||pt&&"Module"===t[Symbol.toStringTag])&&(t=t.default),p(t)?e.extend(t):t}function De(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(sn=function(){return pn.now()})}var dn=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function un(){var t,e;for(ln=sn(),an=!0,en.sort(dn),cn=0;cncn&&en[n].id>t.id;)n--;en.splice(n+1,0,t)}else en.push(t);rn||(rn=!0,Ie(un))}}function hn(t,e){if(t){for(var n=Object.create(null),i=pt?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(r&&!B(o,"default"))a=!1;else if(""===a||a===T(t)){var l=jn(String,o.type);(l<0||c-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!g(t)&&t.test(e)}function Xn(t,e){var n=t.cache,i=t.keys,o=t._vnode,r=t.$vnode;for(var a in n){var c=n[a];if(c){var l=c.name;l&&!e(l)&&Jn(n,a,i,o)}}r.componentOptions.children=void 0}function Jn(t,e,n,i){var o=t[e];!o||i&&o.tag===i.tag||o.componentInstance.$destroy(),t[e]=null,k(n,e)}Vn.prototype._init=function(t){var e=this;e._uid=qn++,e._isVue=!0,e.__v_skip=!0,e._scope=new Lt(!0),e._scope.parent=void 0,e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),i=e._parentVnode;n.parent=e.parent,n._parentVnode=i;var o=i.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=On(Hn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ze(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=ue(e._renderChildren,o),t.$scopedSlots=n?me(t.$parent,n.data.scopedSlots,t.$slots):i,t._c=function(e,n,i,o){return xe(t,e,n,i,o,!1)},t.$createElement=function(e,n,i,o){return xe(t,e,n,i,o,!0)};var r=n&&n.data;Ft(t,"$attrs",r&&r.attrs||i,null,!0),Ft(t,"$listeners",e._parentListeners||i,null,!0)}(e),tn(e,"beforeCreate",void 0,!1),function(t){var e=hn(t.$options.inject,t);e&&(St(!1),Object.keys(e).forEach((function(n){Ft(t,n,e[n])})),St(!0))}(e),In(e),function(t){var e=t.$options.provide;if(e){var n=s(e)?e.call(t):e;if(!p(n))return;for(var i=Wt(t),o=pt?Reflect.ownKeys(n):Object.keys(n),r=0;r1?C(n):n;for(var i=C(arguments,1),o='event handler for "'.concat(t,'"'),r=0,a=n.length;rparseInt(this.max)&&Jn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Jn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Xn(t,(function(t){return Qn(e,t)}))})),this.$watch("exclude",(function(e){Xn(t,(function(t){return!Qn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=De(t),n=e&&e.componentOptions;if(n){var i=Zn(n),o=this.include,r=this.exclude;if(o&&(!i||!Qn(o,i))||r&&i&&Qn(r,i))return e;var a=this.cache,c=this.keys,l=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[l]?(e.componentInstance=a[l].componentInstance,k(c,l),c.push(l)):(this.vnodeToCache=e,this.keyToCache=l),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return W}};Object.defineProperty(t,"config",e),t.util={warn:Bn,extend:F,mergeOptions:On,defineReactive:Ft},t.set=At,t.delete=Et,t.nextTick=Ie,t.observable=function(t){return Ct(t),t},t.options=Object.create(null),N.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,F(t.options.components,ti),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=C(arguments,1);return n.unshift(this),s(t.install)?t.install.apply(t,n):s(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=On(this.options,t),this}}(t),Gn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&u(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&s(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Vn),Object.defineProperty(Vn.prototype,"$isServer",{get:at}),Object.defineProperty(Vn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Vn,"FunctionalRenderContext",{value:mn}),Vn.version="2.7.16";var ei=y("style,class"),ni=y("input,textarea,option,select,progress"),ii=y("contenteditable,draggable,spellcheck"),oi=y("events,caret,typing,plaintext-only"),ri=y("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ai="http://www.w3.org/1999/xlink",ci=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},li=function(t){return ci(t)?t.slice(6,t.length):""},si=function(t){return null==t||!1===t};function pi(t){for(var e=t.data,n=t,i=t;a(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(e=di(i.data,e));for(;a(n=n.parent);)n&&n.data&&(e=di(e,n.data));return function(t,e){if(a(t)||a(e))return ui(t,gi(e));return""}(e.staticClass,e.class)}function di(t,e){return{staticClass:ui(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function ui(t,e){return t?e?t+" "+e:t:e||""}function gi(t){return Array.isArray(t)?function(t){for(var e,n="",i=0,o=t.length;i-1?Mi(t,e,n):ri(e)?si(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):ii(e)?t.setAttribute(e,function(t,e){return si(e)||"false"===e?"false":"contenteditable"===t&&oi(e)?e:"true"}(e,n)):ci(e)?si(n)?t.removeAttributeNS(ai,li(e)):t.setAttributeNS(ai,e,n):Mi(t,e,n)}function Mi(t,e,n){if(si(n))t.removeAttribute(e);else{if(X&&!J&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var i=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",i)};t.addEventListener("input",i),t.__ieph=!0}t.setAttribute(e,n)}}var Ri={create:$i,update:$i};function Ii(t,e){var n=e.elm,i=e.data,o=t.data;if(!(r(i.staticClass)&&r(i.class)&&(r(o)||r(o.staticClass)&&r(o.class)))){var c=pi(e),l=n._transitionClasses;a(l)&&(c=ui(c,gi(l))),c!==n._prevClass&&(n.setAttribute("class",c),n._prevClass=c)}}var Ui,Ni={create:Ii,update:Ii};function Li(t,e,n){var i=Ui;return function o(){var r=e.apply(null,arguments);null!==r&&qi(t,o,n,i)}}var Wi=Ce&&!(nt&&Number(nt[1])<=53);function zi(t,e,n,i){if(Wi){var o=ln,r=e;e=r._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return r.apply(this,arguments)}}Ui.addEventListener(t,e,ot?{capture:n,passive:i}:n)}function qi(t,e,n,i){(i||Ui).removeEventListener(t,e._wrapper||e,n)}function Hi(t,e){if(!r(t.data.on)||!r(e.data.on)){var n=e.data.on||{},i=t.data.on||{};Ui=e.elm||t.elm,function(t){if(a(t.__r)){var e=X?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Ht(n,i,zi,qi,Li,e.context),Ui=void 0}}var Vi,Gi={create:Hi,update:Hi,destroy:function(t){return Hi(t,Di)}};function Zi(t,e){if(!r(t.data.domProps)||!r(e.data.domProps)){var n,i,o=e.elm,l=t.data.domProps||{},s=e.data.domProps||{};for(n in(a(s.__ob__)||c(s._v_attr_proxy))&&(s=e.data.domProps=F({},s)),l)n in s||(o[n]="");for(n in s){if(i=s[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),i===l[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=i;var p=r(i)?"":String(i);Qi(o,p)&&(o.value=p)}else if("innerHTML"===n&&fi(o.tagName)&&r(o.innerHTML)){(Vi=Vi||document.createElement("div")).innerHTML="".concat(i,"");for(var d=Vi.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;d.firstChild;)o.appendChild(d.firstChild)}else if(i!==l[n])try{o[n]=i}catch(t){}}}}function Qi(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,i=t._vModifiers;if(a(i)){if(i.number)return b(n)!==b(e);if(i.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Xi={create:Zi,update:Zi},Ji=D((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var i=t.split(n);i.length>1&&(e[i[0].trim()]=i[1].trim())}})),e}));function Yi(t){var e=to(t.style);return t.staticStyle?F(t.staticStyle,e):e}function to(t){return Array.isArray(t)?A(t):"string"==typeof t?Ji(t):t}var eo,no=/^--/,io=/\s*!important$/,oo=function(t,e,n){if(no.test(e))t.style.setProperty(e,n);else if(io.test(n))t.style.setProperty(T(e),n.replace(io,""),"important");else{var i=ao(e);if(Array.isArray(n))for(var o=0,r=n.length;o-1?e.split(so).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function uo(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(so).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),i=" "+e+" ";n.indexOf(i)>=0;)n=n.replace(i," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function go(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&F(e,ho(t.name||"v")),F(e,t),e}return"string"==typeof t?ho(t):void 0}}var ho=D((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),mo=Z&&!J,fo="transition",vo="transitionend",bo="animation",yo="animationend";mo&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(fo="WebkitTransition",vo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(bo="WebkitAnimation",yo="webkitAnimationEnd"));var wo=Z?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function ko(t){wo((function(){wo(t)}))}function _o(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),po(t,e))}function Bo(t,e){t._transitionClasses&&k(t._transitionClasses,e),uo(t,e)}function Do(t,e,n){var i=Po(t,e),o=i.type,r=i.timeout,a=i.propCount;if(!o)return n();var c="transition"===o?vo:yo,l=0,s=function(){t.removeEventListener(c,p),n()},p=function(e){e.target===t&&++l>=a&&s()};setTimeout((function(){l0&&(n="transition",p=a,d=r.length):"animation"===e?s>0&&(n="animation",p=s,d=l.length):d=(n=(p=Math.max(a,s))>0?a>s?"transition":"animation":null)?"transition"===n?r.length:l.length:0,{type:n,timeout:p,propCount:d,hasTransform:"transition"===n&&xo.test(i[fo+"Property"])}}function Ko(t,e){for(;t.length1}function Ao(t,e){!0!==e.data.show&&To(e)}var Eo=function(t){var e,n,i={},s=t.modules,p=t.nodeOps;for(e=0;eh?w(t,r(n[v+1])?null:n[v+1].elm,n,g,v,i):g>v&&_(e,d,h)}(d,m,v,n,s):a(v)?(a(t.text)&&p.setTextContent(d,""),w(d,null,v,0,v.length-1,n)):a(m)?_(m,0,m.length-1):a(t.text)&&p.setTextContent(d,""):t.text!==e.text&&p.setTextContent(d,e.text),a(h)&&a(g=h.hook)&&a(g=g.postpatch)&&g(t,e)}}}function P(t,e,n){if(c(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var i=0;i-1,a.selected!==r&&(a.selected=r);else if(M(Io(a),i))return void(t.selectedIndex!==c&&(t.selectedIndex=c));o||(t.selectedIndex=-1)}}function Ro(t,e){return e.every((function(e){return!M(e,t)}))}function Io(t){return"_value"in t?t._value:t.value}function Uo(t){t.target.composing=!0}function No(t){t.target.composing&&(t.target.composing=!1,Lo(t.target,"input"))}function Lo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Wo(t){return!t.componentInstance||t.data&&t.data.transition?t:Wo(t.componentInstance._vnode)}var zo={model:$o,show:{bind:function(t,e,n){var i=e.value,o=(n=Wo(n)).data&&n.data.transition,r=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;i&&o?(n.data.show=!0,To(n,(function(){t.style.display=r}))):t.style.display=i?r:"none"},update:function(t,e,n){var i=e.value;!i!=!e.oldValue&&((n=Wo(n)).data&&n.data.transition?(n.data.show=!0,i?To(n,(function(){t.style.display=t.__vOriginalDisplay})):Oo(n,(function(){t.style.display="none"}))):t.style.display=i?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,i,o){o||(t.style.display=t.__vOriginalDisplay)}}},qo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Ho(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ho(De(e.children)):t}function Vo(t){var e={},n=t.$options;for(var i in n.propsData)e[i]=t[i];var o=n._parentListeners;for(var i in o)e[P(i)]=o[i];return e}function Go(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Zo=function(t){return t.tag||he(t)},Qo=function(t){return"show"===t.name},Xo={name:"transition",props:qo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Zo)).length){0;var i=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var r=Ho(o);if(!r)return o;if(this._leaving)return Go(t,o);var a="__transition-".concat(this._uid,"-");r.key=null==r.key?r.isComment?a+"comment":a+r.tag:l(r.key)?0===String(r.key).indexOf(a)?r.key:a+r.key:r.key;var c=(r.data||(r.data={})).transition=Vo(this),s=this._vnode,p=Ho(s);if(r.data.directives&&r.data.directives.some(Qo)&&(r.data.show=!0),p&&p.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(r,p)&&!he(p)&&(!p.componentInstance||!p.componentInstance._vnode.isComment)){var d=p.data.transition=F({},c);if("out-in"===i)return this._leaving=!0,Vt(d,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Go(t,o);if("in-out"===i){if(he(r))return s;var u,g=function(){u()};Vt(c,"afterEnter",g),Vt(c,"enterCancelled",g),Vt(d,"delayLeave",(function(t){u=t}))}}return o}}},Jo=F({tag:String,moveClass:String},qo);function Yo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function tr(t){t.data.newPos=t.elm.getBoundingClientRect()}function er(t){var e=t.data.pos,n=t.data.newPos,i=e.left-n.left,o=e.top-n.top;if(i||o){t.data.moved=!0;var r=t.elm.style;r.transform=r.WebkitTransform="translate(".concat(i,"px,").concat(o,"px)"),r.transitionDuration="0s"}}delete Jo.mode;var nr={Transition:Xo,TransitionGroup:{props:Jo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,i){var o=Xe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,i)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),i=this.prevChildren=this.children,o=this.$slots.default||[],r=this.children=[],a=Vo(this),c=0;c-1?bi[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:bi[t]=/HTMLUnknownElement/.test(e.toString())},F(Vn.options.directives,zo),F(Vn.options.components,nr),Vn.prototype.__patch__=Z?Eo:E,Vn.prototype.$mount=function(t,e){return function(t,e,n){var i;t.$el=e,t.$options.render||(t.$options.render=ht),tn(t,"beforeMount"),i=function(){t._update(t._render(),n)},new qe(t,i,E,{before:function(){t._isMounted&&!t._isDestroyed&&tn(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var r=0;r=0&&(e=t.slice(i),t=t.slice(0,i));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),s=e&&e.path||"/",p=l.path?Br(l.path,s,n||o.append):s,d=function(t,e,n){void 0===e&&(e={});var i,o=n||pr;try{i=o(t||"")}catch(t){i={}}for(var r in e){var a=e[r];i[r]=Array.isArray(a)?a.map(sr):sr(a)}return i}(l.query,o.query,i&&i.options.parseQuery),u=o.hash||l.hash;return u&&"#"!==u.charAt(0)&&(u="#"+u),{_normalized:!0,path:p,query:d,hash:u}}var zr,qr=function(){},Hr={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,i=this.$route,o=n.resolve(this.to,i,this.append),r=o.location,a=o.route,c=o.href,l={},s=n.options.linkActiveClass,p=n.options.linkExactActiveClass,d=null==s?"router-link-active":s,u=null==p?"router-link-exact-active":p,g=null==this.activeClass?d:this.activeClass,h=null==this.exactActiveClass?u:this.exactActiveClass,m=a.redirectedFrom?gr(null,Wr(a.redirectedFrom),null,n):a;l[h]=br(i,m,this.exactPath),l[g]=this.exact||this.exactPath?l[h]:function(t,e){return 0===t.path.replace(ur,"/").indexOf(e.path.replace(ur,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(i,m);var f=l[h]?this.ariaCurrentValue:null,v=function(t){Vr(t)&&(e.replace?n.replace(r,qr):n.push(r,qr))},b={click:Vr};Array.isArray(this.event)?this.event.forEach((function(t){b[t]=v})):b[this.event]=v;var y={class:l},w=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:c,route:a,navigate:v,isActive:l[g],isExactActive:l[h]});if(w){if(1===w.length)return w[0];if(w.length>1||!w.length)return 0===w.length?t():t("span",{},w)}if("a"===this.tag)y.on=b,y.attrs={href:c,"aria-current":f};else{var k=function t(e){var n;if(e)for(var i=0;i-1&&(c.params[u]=n.params[u]);return c.path=Lr(p.path,c.params),l(p,c,a)}if(c.path){c.params={};for(var g=0;g-1}function Da(t,e){return Ba(t)&&t._isRouter&&(null==e||t.type===e)}function xa(t,e,n){var i=function(o){o>=t.length?n():t[o]?e(t[o],(function(){i(o+1)})):i(o+1)};i(0)}function Pa(t){return function(e,n,i){var o=!1,r=0,a=null;Ka(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){o=!0,r++;var l,s=Oa((function(e){var o;((o=e).__esModule||Ta&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:zr.extend(e),n.components[c]=e,--r<=0&&i()})),p=Oa((function(t){var e="Failed to resolve async component "+c+": "+t;a||(a=Ba(t)?t:new Error(e),i(a))}));try{l=t(s,p)}catch(t){p(t)}if(l)if("function"==typeof l.then)l.then(s,p);else{var d=l.component;d&&"function"==typeof d.then&&d.then(s,p)}}})),o||i()}}function Ka(t,e){return Sa(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Sa(t){return Array.prototype.concat.apply([],t)}var Ta="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Oa(t){var e=!1;return function(){for(var n=[],i=arguments.length;i--;)n[i]=arguments[i];if(!e)return e=!0,t.apply(this,n)}}var Ca=function(t,e){this.router=t,this.base=function(t){if(!t)if(Gr){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=mr,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Fa(t,e,n,i){var o=Ka(t,(function(t,i,o,r){var a=function(t,e){"function"!=typeof t&&(t=zr.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,i,o,r)})):n(a,i,o,r)}));return Sa(i?o.reverse():o)}function Aa(t,e){if(e)return function(){return t.apply(e,arguments)}}Ca.prototype.listen=function(t){this.cb=t},Ca.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Ca.prototype.onError=function(t){this.errorCbs.push(t)},Ca.prototype.transitionTo=function(t,e,n){var i,o=this;try{i=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var r=this.current;this.confirmTransition(i,(function(){o.updateRoute(i),e&&e(i),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(i,r)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(i)})))}),(function(t){n&&n(t),t&&!o.ready&&(Da(t,ba.redirected)&&r===mr||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},Ca.prototype.confirmTransition=function(t,e,n){var i=this,o=this.current;this.pending=t;var r,a,c=function(t){!Da(t)&&Ba(t)&&(i.errorCbs.length?i.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},l=t.matched.length-1,s=o.matched.length-1;if(br(t,o)&&l===s&&t.matched[l]===o.matched[s])return this.ensureURL(),t.hash&&aa(this.router,o,t,!1),c(((a=ka(r=o,t,ba.duplicated,'Avoided redundant navigation to current location: "'+r.fullPath+'".')).name="NavigationDuplicated",a));var p=function(t,e){var n,i=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,i=ma&&n;i&&this.listeners.push(ra());var o=function(){var n=t.current,o=$a(t.base);t.current===mr&&o===t._startLocation||t.transitionTo(o,(function(t){i&&aa(e,t,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){fa(Dr(i.base+t.fullPath)),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){va(Dr(i.base+t.fullPath)),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if($a(this.base)!==this.current.fullPath){var e=Dr(this.base+this.current.fullPath);t?fa(e):va(e)}},e.prototype.getCurrentLocation=function(){return $a(this.base)},e}(Ca);function $a(t){var e=window.location.pathname,n=e.toLowerCase(),i=t.toLowerCase();return!t||n!==i&&0!==n.indexOf(Dr(i+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var ja=function(t){function e(e,n,i){t.call(this,e,n),i&&function(t){var e=$a(t);if(!/^\/#/.test(e))return window.location.replace(Dr(t+"/#"+e)),!0}(this.base)||Ma()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=ma&&e;n&&this.listeners.push(ra());var i=function(){var e=t.current;Ma()&&t.transitionTo(Ra(),(function(i){n&&aa(t.router,i,e,!0),ma||Na(i.fullPath)}))},o=ma?"popstate":"hashchange";window.addEventListener(o,i),this.listeners.push((function(){window.removeEventListener(o,i)}))}},e.prototype.push=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){Ua(t.fullPath),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ra()!==e&&(t?Ua(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ra()},e}(Ca);function Ma(){var t=Ra();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ra(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Ia(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ua(t){ma?fa(Ia(t)):window.location.hash=t}function Na(t){ma?va(Ia(t)):window.location.replace(Ia(t))}var La=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index+1).concat(t),i.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var i=this.stack[n];this.confirmTransition(i,(function(){var t=e.current;e.index=n,e.updateRoute(i),e.router.afterHooks.forEach((function(e){e&&e(i,t)}))}),(function(t){Da(t,ba.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Ca),Wa=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Xr(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ma&&!1!==t.fallback,this.fallback&&(e="hash"),Gr||(e="abstract"),this.mode=e,e){case"history":this.history=new Ea(this,t.base);break;case"hash":this.history=new ja(this,t.base,this.fallback);break;case"abstract":this.history=new La(this,t.base);break;default:0}},za={currentRoute:{configurable:!0}};Wa.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},za.currentRoute.get=function(){return this.history&&this.history.current},Wa.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof Ea||n instanceof ja){var i=function(t){n.setupListeners(),function(t){var i=n.current,o=e.options.scrollBehavior;ma&&o&&"fullPath"in t&&aa(e,t,i,!1)}(t)};n.transitionTo(n.getCurrentLocation(),i,i)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Wa.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},Wa.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},Wa.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},Wa.prototype.onReady=function(t,e){this.history.onReady(t,e)},Wa.prototype.onError=function(t){this.history.onError(t)},Wa.prototype.push=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.push(t,e,n)}));this.history.push(t,e,n)},Wa.prototype.replace=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.replace(t,e,n)}));this.history.replace(t,e,n)},Wa.prototype.go=function(t){this.history.go(t)},Wa.prototype.back=function(){this.go(-1)},Wa.prototype.forward=function(){this.go(1)},Wa.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Wa.prototype.resolve=function(t,e,n){var i=Wr(t,e=e||this.history.current,n,this),o=this.match(i,e),r=o.redirectedFrom||o.fullPath;return{location:i,route:o,href:function(t,e,n){var i="hash"===n?"#"+e:e;return t?Dr(t+"/"+i):i}(this.history.base,r,this.mode),normalizedTo:i,resolved:o}},Wa.prototype.getRoutes=function(){return this.matcher.getRoutes()},Wa.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==mr&&this.history.transitionTo(this.history.getCurrentLocation())},Wa.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==mr&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Wa.prototype,za);var qa=Wa;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Wa.install=function t(e){if(!t.installed||zr!==e){t.installed=!0,zr=e;var n=function(t){return void 0!==t},i=function(t,e){var i=t.$options._parentVnode;n(i)&&n(i=i.data)&&n(i=i.registerRouteInstance)&&i(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,i(this,this)},destroyed:function(){i(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",kr),e.component("RouterLink",Hr);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Wa.version="3.6.5",Wa.isNavigationFailure=Da,Wa.NavigationFailureType=ba,Wa.START_LOCATION=mr,Gr&&window.Vue&&window.Vue.use(Wa);n(53);n(100),n(46);var Va={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(23)]).then(n.bind(null,325)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(22)]).then(n.bind(null,286)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(32)]).then(n.bind(null,261)),"components/Home":()=>Promise.all([n.e(0),n.e(27)]).then(n.bind(null,326)),"components/NavLink":()=>n.e(43).then(n.bind(null,253)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(20)]).then(n.bind(null,275)),"components/Navbar":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,285)),"components/Page":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,297)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(28)]).then(n.bind(null,287)),"components/PageNav":()=>Promise.all([n.e(0),n.e(24)]).then(n.bind(null,288)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,268)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(33)]).then(n.bind(null,328)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,264)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(30)]).then(n.bind(null,262)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,255)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,397)),"global-components/CodeBlock":()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,387)),"global-components/CodeGroup":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,388)),"layouts/404":()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,389)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,390)),NotFound:()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,389)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,390)),"components/Cases":()=>Promise.all([n.e(0),n.e(25)]).then(n.bind(null,327)),"components/Footer":()=>Promise.all([n.e(0),n.e(26)]).then(n.bind(null,269)),"components/LayoutWrap":()=>Promise.all([n.e(0),n.e(1),n.e(17)]).then(n.bind(null,276)),"components/PostMeta":()=>Promise.all([n.e(0),n.e(29)]).then(n.bind(null,298)),"layouts/DirectoryPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,391)),"layouts/FrontmatterKey":()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,392)),"layouts/FrontmatterPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,393)),"layouts/IndexPost":()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,324)),"layouts/Post":()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,394)),DirectoryPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,391)),FrontmatterKey:()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,392)),FrontmatterPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,393)),IndexPost:()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,324)),Post:()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,394))},Ga={"v-330a32a2":()=>n.e(45).then(n.bind(null,398)),"v-5e744cf7":()=>n.e(47).then(n.bind(null,399)),"v-2c450c3f":()=>n.e(46).then(n.bind(null,400)),"v-609f26f9":()=>n.e(48).then(n.bind(null,401)),"v-bac76d8e":()=>n.e(49).then(n.bind(null,402)),"v-62ca00fb":()=>n.e(50).then(n.bind(null,403)),"v-8bd632d6":()=>n.e(52).then(n.bind(null,404)),"v-7c0c45f9":()=>n.e(51).then(n.bind(null,405)),"v-2cebe183":()=>n.e(34).then(n.bind(null,406)),"v-3eaa044d":()=>n.e(31).then(n.bind(null,407)),"v-0f4d5d15":()=>n.e(53).then(n.bind(null,408)),"v-3875825f":()=>n.e(55).then(n.bind(null,409)),"v-353b78e1":()=>n.e(54).then(n.bind(null,410)),"v-07ff1843":()=>n.e(56).then(n.bind(null,411)),"v-9504490e":()=>n.e(57).then(n.bind(null,412)),"v-56536559":()=>n.e(19).then(n.bind(null,413)),"v-f58ec8f2":()=>n.e(21).then(n.bind(null,414)),"v-015729b9":()=>n.e(59).then(n.bind(null,415)),"v-c6756cce":()=>n.e(58).then(n.bind(null,416)),"v-2c605799":()=>n.e(60).then(n.bind(null,417)),"v-57698579":()=>n.e(61).then(n.bind(null,418)),"v-9145467a":()=>n.e(62).then(n.bind(null,419)),"v-2cf72b39":()=>n.e(63).then(n.bind(null,420)),"v-11d64359":()=>n.e(64).then(n.bind(null,421)),"v-ab5ba3ce":()=>n.e(66).then(n.bind(null,422)),"v-5d749fce":()=>n.e(65).then(n.bind(null,423)),"v-d0375c8e":()=>n.e(67).then(n.bind(null,424)),"v-10852eea":()=>n.e(68).then(n.bind(null,425)),"v-edd5570e":()=>n.e(69).then(n.bind(null,426)),"v-05df4999":()=>n.e(70).then(n.bind(null,427)),"v-faad828e":()=>n.e(71).then(n.bind(null,428)),"v-7c3d28f9":()=>n.e(73).then(n.bind(null,429)),"v-0119984e":()=>n.e(72).then(n.bind(null,430)),"v-0df1c3ce":()=>n.e(74).then(n.bind(null,431)),"v-75d11339":()=>n.e(75).then(n.bind(null,432)),"v-1ac9ef4e":()=>n.e(76).then(n.bind(null,433)),"v-55969f39":()=>n.e(77).then(n.bind(null,434)),"v-8534b9c2":()=>n.e(78).then(n.bind(null,435)),"v-aeb70fce":()=>n.e(79).then(n.bind(null,436)),"v-4dc135e3":()=>n.e(80).then(n.bind(null,437)),"v-4d760891":()=>Promise.all([n.e(0),n.e(35)]).then(n.bind(null,438)),"v-30c0037b":()=>Promise.all([n.e(0),n.e(36)]).then(n.bind(null,439)),"v-4bb7844a":()=>Promise.all([n.e(0),n.e(37)]).then(n.bind(null,440)),"v-b936290e":()=>Promise.all([n.e(0),n.e(38)]).then(n.bind(null,441)),"v-7afdbb4e":()=>Promise.all([n.e(0),n.e(39)]).then(n.bind(null,442)),"v-4e0b610e":()=>Promise.all([n.e(0),n.e(40)]).then(n.bind(null,443)),"v-a7c24c4e":()=>Promise.all([n.e(0),n.e(41)]).then(n.bind(null,444)),"v-17019aeb":()=>Promise.all([n.e(0),n.e(42)]).then(n.bind(null,445)),"v-7a315e41":()=>n.e(81).then(n.bind(null,446)),"v-f611a14e":()=>n.e(82).then(n.bind(null,447)),"v-3acb6e6a":()=>n.e(83).then(n.bind(null,448)),"v-496cb7f9":()=>n.e(84).then(n.bind(null,395)),"v-0b3b65ea":()=>n.e(85).then(n.bind(null,449)),"v-a76bccee":()=>n.e(86).then(n.bind(null,450)),"v-05d01c19":()=>n.e(87).then(n.bind(null,451)),"v-11bf335e":()=>n.e(88).then(n.bind(null,452)),"v-a9236c10":()=>n.e(89).then(n.bind(null,453)),"v-29f9f21c":()=>n.e(90).then(n.bind(null,454)),"v-3750297a":()=>n.e(91).then(n.bind(null,455)),"v-71ef7c85":()=>n.e(92).then(n.bind(null,456)),"v-105750ce":()=>n.e(93).then(n.bind(null,457)),"v-c152529c":()=>n.e(95).then(n.bind(null,458)),"v-08589c4e":()=>n.e(94).then(n.bind(null,459)),"v-4a4b61eb":()=>n.e(96).then(n.bind(null,460)),"v-50aa6d4e":()=>n.e(97).then(n.bind(null,461)),"v-4bcdac39":()=>n.e(98).then(n.bind(null,462))};function Za(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Qa=/-(\w)/g,Xa=Za(t=>t.replace(Qa,(t,e)=>e?e.toUpperCase():"")),Ja=/\B([A-Z])/g,Ya=Za(t=>t.replace(Ja,"-$1").toLowerCase()),tc=Za(t=>t.charAt(0).toUpperCase()+t.slice(1));function ec(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(tc(Xa(e))):t(tc(e))||t(Ya(e))}const nc=Object.assign({},Va,Ga),ic=t=>nc[t],oc=t=>Ga[t],rc=t=>Va[t],ac=t=>Vn.component(t);function cc(t){return ec(oc,t)}function lc(t){return ec(rc,t)}function sc(t){return ec(ic,t)}function pc(t){return ec(ac,t)}function dc(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!pc(t)&&sc(t)){const e=await sc(t)();Vn.component(t,e.default)}}))}function uc(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var gc=n(91),hc=n.n(gc),mc=n(92),fc=n.n(mc),vc={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${fc()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=yc(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=wc(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return hc()([{name:"description",content:this.$description}],t,this.siteMeta,kc)},updateCanonicalLink(){bc(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",yc(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){wc(null,this.currentMetaTags),bc()}};function bc(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function yc(t=""){return t?``:""}function wc(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function kc(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var _c=n(93),Bc={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(_c)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),i=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=r.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Dc=n(22),xc=n.n(Dc),Pc={mounted(){xc.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Vn.component(t.name)||xc.a.start(),n()}),this.$router.afterEach(()=>{xc.a.done(),this.isSidebarOpen=!1})}},Kc={props:{parent:Object,code:String,options:{align:String,color:String,backgroundTransition:Boolean,backgroundColor:String,successText:String,staticIcon:Boolean}},data:()=>({success:!1,originalBackground:null,originalTransition:null}),computed:{alignStyle(){let t={};return t[this.options.align]="7.5px",t},iconClass(){return this.options.staticIcon?"":"hover"}},mounted(){this.originalTransition=this.parent.style.transition,this.originalBackground=this.parent.style.background},beforeDestroy(){this.parent.style.transition=this.originalTransition,this.parent.style.background=this.originalBackground},methods:{hexToRgb(t){let e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null},copyToClipboard(t){if(navigator.clipboard)navigator.clipboard.writeText(this.code).then(()=>{this.setSuccessTransitions()},()=>{});else{let t=document.createElement("textarea");document.body.appendChild(t),t.value=this.code,t.select(),document.execCommand("Copy"),t.remove(),this.setSuccessTransitions()}},setSuccessTransitions(){if(clearTimeout(this.successTimeout),this.options.backgroundTransition){this.parent.style.transition="background 350ms";let t=this.hexToRgb(this.options.backgroundColor);this.parent.style.background=`rgba(${t.r}, ${t.g}, ${t.b}, 0.1)`}this.success=!0,this.successTimeout=setTimeout(()=>{this.options.backgroundTransition&&(this.parent.style.background=this.originalBackground,this.parent.style.transition=this.originalTransition),this.success=!1},500)}}},Sc=(n(240),n(7)),Tc=Object(Sc.a)(Kc,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"code-copy"},[e("svg",{class:t.iconClass,style:t.alignStyle,attrs:{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},on:{click:t.copyToClipboard}},[e("path",{attrs:{fill:"none",d:"M0 0h24v24H0z"}}),t._v(" "),e("path",{attrs:{fill:t.options.color,d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}})]),t._v(" "),e("span",{class:t.success?"success":"",style:t.alignStyle},[t._v("\n "+t._s(t.options.successText)+"\n ")])])}),[],!1,null,"49140617",null).exports,Oc=(n(241),[vc,Bc,Pc,{updated(){this.update()},methods:{update(){setTimeout(()=>{document.querySelectorAll('div[class*="language-"] pre').forEach(t=>{if(t.classList.contains("code-copy-added"))return;let e=new(Vn.extend(Tc));e.options={align:"bottom",color:"#8F979E",backgroundTransition:!1,backgroundColor:"#0075b8",successText:"Copied!",staticIcon:!0},e.code=t.innerText,e.parent=t,e.$mount(),t.classList.add("code-copy-added"),t.appendChild(e.$el)})},100)}}}]),Cc={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return uc("layout",t),Vn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},Fc=Object(Sc.a)(Cc,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(Fc,"mixins",Oc);const Ac=[{name:"v-330a32a2",path:"/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-330a32a2").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-5e744cf7",path:"/blog/_2024-q1-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-5e744cf7").then(n)}},{path:"/blog/_2024-q1-update/index.html",redirect:"/blog/_2024-q1-update/"},{path:"/_blog/2024_q1_update.html",redirect:"/blog/_2024-q1-update/"},{name:"v-2c450c3f",path:"/blog/_2023-q4-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2c450c3f").then(n)}},{path:"/blog/_2023-q4-update/index.html",redirect:"/blog/_2023-q4-update/"},{path:"/_blog/2023_q4_update.html",redirect:"/blog/_2023-q4-update/"},{name:"v-609f26f9",path:"/blog/_2024-q2-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-609f26f9").then(n)}},{path:"/blog/_2024-q2-update/index.html",redirect:"/blog/_2024-q2-update/"},{path:"/_blog/2024_q2_update.html",redirect:"/blog/_2024-q2-update/"},{name:"v-bac76d8e",path:"/blog/_2024-q3-rfp-rust-maintainer/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-bac76d8e").then(n)}},{path:"/blog/_2024-q3-rfp-rust-maintainer/index.html",redirect:"/blog/_2024-q3-rfp-rust-maintainer/"},{path:"/_blog/2024_q3_rfp_rust_maintainer.html",redirect:"/blog/_2024-q3-rfp-rust-maintainer/"},{name:"v-62ca00fb",path:"/blog/_2024-q3-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-62ca00fb").then(n)}},{path:"/blog/_2024-q3-update/index.html",redirect:"/blog/_2024-q3-update/"},{path:"/_blog/2024_q3_update.html",redirect:"/blog/_2024-q3-update/"},{name:"v-8bd632d6",path:"/blog/bdk-cli-basics-multisig-2of3/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-8bd632d6").then(n)}},{path:"/blog/bdk-cli-basics-multisig-2of3/index.html",redirect:"/blog/bdk-cli-basics-multisig-2of3/"},{path:"/_blog/bdk-cli_basics_multisig_2of3.html",redirect:"/blog/bdk-cli-basics-multisig-2of3/"},{name:"v-7c0c45f9",path:"/blog/bitcoin-core-rpc-demo/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-7c0c45f9").then(n)}},{path:"/blog/bitcoin-core-rpc-demo/index.html",redirect:"/blog/bitcoin-core-rpc-demo/"},{path:"/_blog/Bitcoin_Core_RPC_Demo.html",redirect:"/blog/bitcoin-core-rpc-demo/"},{name:"v-2cebe183",path:"/blog/bdk-core-pt1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2cebe183").then(n)}},{path:"/blog/bdk-core-pt1/index.html",redirect:"/blog/bdk-core-pt1/"},{path:"/_blog/bdk_core_pt1.html",redirect:"/blog/bdk-core-pt1/"},{name:"v-3eaa044d",path:"/blog/bdk-rn-making-of/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-3eaa044d").then(n)}},{path:"/blog/bdk-rn-making-of/index.html",redirect:"/blog/bdk-rn-making-of/"},{path:"/_blog/bdk_rn_making_of.html",redirect:"/blog/bdk-rn-making-of/"},{name:"v-0f4d5d15",path:"/blog/bdk-cli-basics/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-0f4d5d15").then(n)}},{path:"/blog/bdk-cli-basics/index.html",redirect:"/blog/bdk-cli-basics/"},{path:"/_blog/bdk_cli_basics.html",redirect:"/blog/bdk-cli-basics/"},{name:"v-3875825f",path:"/blog/bindings-scope/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-3875825f").then(n)}},{path:"/blog/bindings-scope/index.html",redirect:"/blog/bindings-scope/"},{path:"/_blog/bindings-scope.html",redirect:"/blog/bindings-scope/"},{name:"v-353b78e1",path:"/blog/bdk-with-tor/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-353b78e1").then(n)}},{path:"/blog/bdk-with-tor/index.html",redirect:"/blog/bdk-with-tor/"},{path:"/_blog/bdk_with_tor.html",redirect:"/blog/bdk-with-tor/"},{name:"v-07ff1843",path:"/blog/compact-filters-demo/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-07ff1843").then(n)}},{path:"/blog/compact-filters-demo/index.html",redirect:"/blog/compact-filters-demo/"},{path:"/_blog/compact_filters_demo.html",redirect:"/blog/compact-filters-demo/"},{name:"v-9504490e",path:"/blog/descriptor-based-paper-wallet/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-9504490e").then(n)}},{path:"/blog/descriptor-based-paper-wallet/index.html",redirect:"/blog/descriptor-based-paper-wallet/"},{path:"/_blog/descriptor_based_paper_wallet.html",redirect:"/blog/descriptor-based-paper-wallet/"},{name:"v-56536559",path:"/blog/exploring-bdk-flutter/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-56536559").then(n)}},{path:"/blog/exploring-bdk-flutter/index.html",redirect:"/blog/exploring-bdk-flutter/"},{path:"/_blog/exploring_bdk_flutter.html",redirect:"/blog/exploring-bdk-flutter/"},{name:"v-f58ec8f2",path:"/blog/exploring-bdk-rn/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-f58ec8f2").then(n)}},{path:"/blog/exploring-bdk-rn/index.html",redirect:"/blog/exploring-bdk-rn/"},{path:"/_blog/exploring_bdk_rn.html",redirect:"/blog/exploring-bdk-rn/"},{name:"v-015729b9",path:"/blog/2021/01/fee-estimation-for-light-clients-part-1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-015729b9").then(n)}},{path:"/blog/2021/01/fee-estimation-for-light-clients-part-1/index.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{path:"/_blog/fee_estimation_for_light_clients_part_1.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{name:"v-c6756cce",path:"/blog/descriptors-in-the-wild/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-c6756cce").then(n)}},{path:"/blog/descriptors-in-the-wild/index.html",redirect:"/blog/descriptors-in-the-wild/"},{path:"/_blog/descriptors_in_the_wild.html",redirect:"/blog/descriptors-in-the-wild/"},{name:"v-2c605799",path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2c605799").then(n)}},{path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/index.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{path:"/_blog/fee_estimation_for_light_clients_part_2.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{name:"v-57698579",path:"/blog/2021/01/fee-estimation-for-light-clients-part-3/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-57698579").then(n)}},{path:"/blog/2021/01/fee-estimation-for-light-clients-part-3/index.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{path:"/_blog/fee_estimation_for_light_clients_part_3.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{name:"v-9145467a",path:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-9145467a").then(n)}},{path:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/index.html",redirect:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{path:"/_blog/first_bdk_taproot_tx.html",redirect:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{name:"v-2cf72b39",path:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2cf72b39").then(n)}},{path:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/index.html",redirect:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{path:"/_blog/first_bdk_taproot_tx_part_2.html",redirect:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{name:"v-11d64359",path:"/blog/getting-started-with-rust-hwi/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-11d64359").then(n)}},{path:"/blog/getting-started-with-rust-hwi/index.html",redirect:"/blog/getting-started-with-rust-hwi/"},{path:"/_blog/getting_started_with_rust_hwi.html",redirect:"/blog/getting-started-with-rust-hwi/"},{name:"v-ab5ba3ce",path:"/blog/hidden-power-of-bitcoin/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-ab5ba3ce").then(n)}},{path:"/blog/hidden-power-of-bitcoin/index.html",redirect:"/blog/hidden-power-of-bitcoin/"},{path:"/_blog/hidden-power-of-bitcoin.html",redirect:"/blog/hidden-power-of-bitcoin/"},{name:"v-5d749fce",path:"/blog/2020/12/hello-world/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-5d749fce").then(n)}},{path:"/blog/2020/12/hello-world/index.html",redirect:"/blog/2020/12/hello-world/"},{path:"/_blog/hello-world.html",redirect:"/blog/2020/12/hello-world/"},{name:"v-d0375c8e",path:"/blog/improving-coin-selection-in-bdk/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-d0375c8e").then(n)}},{path:"/blog/improving-coin-selection-in-bdk/index.html",redirect:"/blog/improving-coin-selection-in-bdk/"},{path:"/_blog/improving_coin_selection_in_BDK.html",redirect:"/blog/improving-coin-selection-in-bdk/"},{name:"v-10852eea",path:"/blog/miniscript-vulnerability/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-10852eea").then(n)}},{path:"/blog/miniscript-vulnerability/index.html",redirect:"/blog/miniscript-vulnerability/"},{path:"/_blog/miniscript_vulnerability.html",redirect:"/blog/miniscript-vulnerability/"},{name:"v-edd5570e",path:"/blog/2020/12/release-v0.2.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-edd5570e").then(n)}},{path:"/blog/2020/12/release-v0.2.0/index.html",redirect:"/blog/2020/12/release-v0.2.0/"},{path:"/_blog/release-0.2.0.html",redirect:"/blog/2020/12/release-v0.2.0/"},{name:"v-05df4999",path:"/blog/2021/01/release-v0.3.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-05df4999").then(n)}},{path:"/blog/2021/01/release-v0.3.0/index.html",redirect:"/blog/2021/01/release-v0.3.0/"},{path:"/_blog/release-0.3.0.html",redirect:"/blog/2021/01/release-v0.3.0/"},{name:"v-faad828e",path:"/blog/2021/02/release-v0.4.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-faad828e").then(n)}},{path:"/blog/2021/02/release-v0.4.0/index.html",redirect:"/blog/2021/02/release-v0.4.0/"},{path:"/_blog/release-0.4.0.html",redirect:"/blog/2021/02/release-v0.4.0/"},{name:"v-7c3d28f9",path:"/blog/2021/04/release-v0.6.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-7c3d28f9").then(n)}},{path:"/blog/2021/04/release-v0.6.0/index.html",redirect:"/blog/2021/04/release-v0.6.0/"},{path:"/_blog/release-0.6.0.html",redirect:"/blog/2021/04/release-v0.6.0/"},{name:"v-0119984e",path:"/blog/2021/03/release-v0.5.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-0119984e").then(n)}},{path:"/blog/2021/03/release-v0.5.0/index.html",redirect:"/blog/2021/03/release-v0.5.0/"},{path:"/_blog/release-0.5.0.html",redirect:"/blog/2021/03/release-v0.5.0/"},{name:"v-0df1c3ce",path:"/blog/2021/05/release-v0.7.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-0df1c3ce").then(n)}},{path:"/blog/2021/05/release-v0.7.0/index.html",redirect:"/blog/2021/05/release-v0.7.0/"},{path:"/_blog/release-0.7.0.html",redirect:"/blog/2021/05/release-v0.7.0/"},{name:"v-75d11339",path:"/blog/2021/06/release-v0.8.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-75d11339").then(n)}},{path:"/blog/2021/06/release-v0.8.0/index.html",redirect:"/blog/2021/06/release-v0.8.0/"},{path:"/_blog/release-0.8.0.html",redirect:"/blog/2021/06/release-v0.8.0/"},{name:"v-1ac9ef4e",path:"/blog/2021/07/release-v0.9.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-1ac9ef4e").then(n)}},{path:"/blog/2021/07/release-v0.9.0/index.html",redirect:"/blog/2021/07/release-v0.9.0/"},{path:"/_blog/release-0.9.0.html",redirect:"/blog/2021/07/release-v0.9.0/"},{name:"v-55969f39",path:"/blog/road-to-bdk-1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-55969f39").then(n)}},{path:"/blog/road-to-bdk-1/index.html",redirect:"/blog/road-to-bdk-1/"},{path:"/_blog/road_to_bdk_1.html",redirect:"/blog/road-to-bdk-1/"},{name:"v-8534b9c2",path:"/blog/spending-policy-demo/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-8534b9c2").then(n)}},{path:"/blog/spending-policy-demo/index.html",redirect:"/blog/spending-policy-demo/"},{path:"/_blog/spending_policy_demo.html",redirect:"/blog/spending-policy-demo/"},{name:"v-aeb70fce",path:"/blog/using-bdk-with-hardware-wallets/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-aeb70fce").then(n)}},{path:"/blog/using-bdk-with-hardware-wallets/index.html",redirect:"/blog/using-bdk-with-hardware-wallets/"},{path:"/_blog/using_bdk_with_hardware_wallets.html",redirect:"/blog/using-bdk-with-hardware-wallets/"},{name:"v-4dc135e3",path:"/blog/why-bindings/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-4dc135e3").then(n)}},{path:"/blog/why-bindings/index.html",redirect:"/blog/why-bindings/"},{path:"/_blog/why-bindings.html",redirect:"/blog/why-bindings/"},{name:"v-4d760891",path:"/adoption/all/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4d760891").then(n)}},{path:"/adoption/all/index.html",redirect:"/adoption/all/"},{path:"/adoption/all.html",redirect:"/adoption/all/"},{name:"v-30c0037b",path:"/adoption/custodial/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-30c0037b").then(n)}},{path:"/adoption/custodial/index.html",redirect:"/adoption/custodial/"},{path:"/adoption/custodial.html",redirect:"/adoption/custodial/"},{name:"v-4bb7844a",path:"/adoption/desktop/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4bb7844a").then(n)}},{path:"/adoption/desktop/index.html",redirect:"/adoption/desktop/"},{path:"/adoption/desktop.html",redirect:"/adoption/desktop/"},{name:"v-b936290e",path:"/adoption/exchange/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-b936290e").then(n)}},{path:"/adoption/exchange/index.html",redirect:"/adoption/exchange/"},{path:"/adoption/exchange.html",redirect:"/adoption/exchange/"},{name:"v-7afdbb4e",path:"/adoption/hardware/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-7afdbb4e").then(n)}},{path:"/adoption/hardware/index.html",redirect:"/adoption/hardware/"},{path:"/adoption/hardware.html",redirect:"/adoption/hardware/"},{name:"v-4e0b610e",path:"/adoption/infrastructure/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4e0b610e").then(n)}},{path:"/adoption/infrastructure/index.html",redirect:"/adoption/infrastructure/"},{path:"/adoption/infrastructure.html",redirect:"/adoption/infrastructure/"},{name:"v-a7c24c4e",path:"/adoption/mobile/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-a7c24c4e").then(n)}},{path:"/adoption/mobile/index.html",redirect:"/adoption/mobile/"},{path:"/adoption/mobile.html",redirect:"/adoption/mobile/"},{name:"v-17019aeb",path:"/adoption/web/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-17019aeb").then(n)}},{path:"/adoption/web/index.html",redirect:"/adoption/web/"},{path:"/adoption/web.html",redirect:"/adoption/web/"},{name:"v-7a315e41",path:"/bdk-cli/compiler/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-7a315e41").then(n)}},{path:"/bdk-cli/compiler/index.html",redirect:"/bdk-cli/compiler/"},{path:"/bdk-cli/compiler.html",redirect:"/bdk-cli/compiler/"},{name:"v-f611a14e",path:"/bdk-cli/concept/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-f611a14e").then(n)}},{path:"/bdk-cli/concept/index.html",redirect:"/bdk-cli/concept/"},{path:"/bdk-cli/concept.html",redirect:"/bdk-cli/concept/"},{name:"v-3acb6e6a",path:"/bdk-cli/installation/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-3acb6e6a").then(n)}},{path:"/bdk-cli/installation/index.html",redirect:"/bdk-cli/installation/"},{path:"/bdk-cli/installation.html",redirect:"/bdk-cli/installation/"},{name:"v-496cb7f9",path:"/bdk-cli/interface/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-496cb7f9").then(n)}},{path:"/bdk-cli/interface/index.html",redirect:"/bdk-cli/interface/"},{path:"/bdk-cli/interface.html",redirect:"/bdk-cli/interface/"},{name:"v-0b3b65ea",path:"/bdk-cli/introduction/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-0b3b65ea").then(n)}},{path:"/bdk-cli/introduction/index.html",redirect:"/bdk-cli/introduction/"},{path:"/bdk-cli/introduction.html",redirect:"/bdk-cli/introduction/"},{name:"v-a76bccee",path:"/bdk-cli/playground/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-a76bccee").then(n)}},{path:"/bdk-cli/playground/index.html",redirect:"/bdk-cli/playground/"},{path:"/bdk-cli/playground.html",redirect:"/bdk-cli/playground/"},{name:"v-05d01c19",path:"/bdk-cli/regtest/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-05d01c19").then(n)}},{path:"/bdk-cli/regtest/index.html",redirect:"/bdk-cli/regtest/"},{path:"/bdk-cli/regtest.html",redirect:"/bdk-cli/regtest/"},{name:"v-11bf335e",path:"/case-studies/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-11bf335e").then(n)}},{path:"/case-studies/index.html",redirect:"/case-studies/"},{path:"/case-studies.html",redirect:"/case-studies/"},{name:"v-a9236c10",path:"/descriptors/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-a9236c10").then(n)}},{path:"/descriptors/index.html",redirect:"/descriptors/"},{name:"v-29f9f21c",path:"/examples/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-29f9f21c").then(n)}},{path:"/examples/index.html",redirect:"/examples/"},{name:"v-3750297a",path:"/foundation/about/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-3750297a").then(n)}},{path:"/foundation/about/index.html",redirect:"/foundation/about/"},{path:"/foundation/about.html",redirect:"/foundation/about/"},{name:"v-71ef7c85",path:"/foundation/become-a-member/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-71ef7c85").then(n)}},{path:"/foundation/become-a-member/index.html",redirect:"/foundation/become-a-member/"},{path:"/foundation/become-a-member.html",redirect:"/foundation/become-a-member/"},{name:"v-105750ce",path:"/foundation/grantees/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-105750ce").then(n)}},{path:"/foundation/grantees/index.html",redirect:"/foundation/grantees/"},{path:"/foundation/grantees.html",redirect:"/foundation/grantees/"},{name:"v-c152529c",path:"/foundation/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-c152529c").then(n)}},{path:"/foundation/index.html",redirect:"/foundation/"},{name:"v-08589c4e",path:"/foundation/grants/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-08589c4e").then(n)}},{path:"/foundation/grants/index.html",redirect:"/foundation/grants/"},{path:"/foundation/grants.html",redirect:"/foundation/grants/"},{name:"v-4a4b61eb",path:"/foundation/members/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4a4b61eb").then(n)}},{path:"/foundation/members/index.html",redirect:"/foundation/members/"},{path:"/foundation/members.html",redirect:"/foundation/members/"},{name:"v-50aa6d4e",path:"/foundation/supporters/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-50aa6d4e").then(n)}},{path:"/foundation/supporters/index.html",redirect:"/foundation/supporters/"},{path:"/foundation/supporters.html",redirect:"/foundation/supporters/"},{name:"v-4bcdac39",path:"/getting-started/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4bcdac39").then(n)}},{path:"/getting-started/index.html",redirect:"/getting-started/"},{path:"/getting-started.html",redirect:"/getting-started/"},{name:"v-424df898",path:"/blog/",component:Fc,beforeEnter:(t,e,n)=>{dc("IndexPost","v-424df898").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/index.html",redirect:"/blog/"},{name:"v-619df59e",path:"/blog/tags/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterKey","v-619df59e").then(n)},meta:{pid:"tags",id:"tags"}},{path:"/blog/tags/index.html",redirect:"/blog/tags/"},{name:"v-b0968728",path:"/blog/author/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterKey","v-b0968728").then(n)},meta:{pid:"author",id:"author"}},{path:"/blog/author/index.html",redirect:"/blog/author/"},{name:"v-5f2600b8",path:"/blog/tags/BDK/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f2600b8").then(n)},meta:{pid:"tags",id:"BDK"}},{path:"/blog/tags/BDK/index.html",redirect:"/blog/tags/BDK/"},{name:"v-398e8fd4",path:"/blog/tags/project/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-398e8fd4").then(n)},meta:{pid:"tags",id:"project"}},{path:"/blog/tags/project/index.html",redirect:"/blog/tags/project/"},{name:"v-9d39d64c",path:"/blog/tags/grants/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-9d39d64c").then(n)},meta:{pid:"tags",id:"grants"}},{path:"/blog/tags/grants/index.html",redirect:"/blog/tags/grants/"},{name:"v-da8c869a",path:"/blog/tags/tutorial/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-da8c869a").then(n)},meta:{pid:"tags",id:"tutorial"}},{path:"/blog/tags/tutorial/index.html",redirect:"/blog/tags/tutorial/"},{name:"v-c711ccde",path:"/blog/tags/bdk-cli/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-c711ccde").then(n)},meta:{pid:"tags",id:"bdk-cli"}},{path:"/blog/tags/bdk-cli/index.html",redirect:"/blog/tags/bdk-cli/"},{name:"v-655ee4a0",path:"/blog/tags/multi-sig/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-655ee4a0").then(n)},meta:{pid:"tags",id:"multi-sig"}},{path:"/blog/tags/multi-sig/index.html",redirect:"/blog/tags/multi-sig/"},{name:"v-62bbf2ad",path:"/blog/tags/Bitcoin Core/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-62bbf2ad").then(n)},meta:{pid:"tags",id:"Bitcoin Core"}},{path:"/blog/tags/Bitcoin Core/index.html",redirect:"/blog/tags/Bitcoin Core/"},{name:"v-5f171cb0",path:"/blog/tags/RPC/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f171cb0").then(n)},meta:{pid:"tags",id:"RPC"}},{path:"/blog/tags/RPC/index.html",redirect:"/blog/tags/RPC/"},{name:"v-4696dfd8",path:"/blog/tags/Wallet/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4696dfd8").then(n)},meta:{pid:"tags",id:"Wallet"}},{path:"/blog/tags/Wallet/index.html",redirect:"/blog/tags/Wallet/"},{name:"v-c4494744",path:"/blog/tags/architecture/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-c4494744").then(n)},meta:{pid:"tags",id:"architecture"}},{path:"/blog/tags/architecture/index.html",redirect:"/blog/tags/architecture/"},{name:"v-876cfade",path:"/blog/tags/BDK-RN/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-876cfade").then(n)},meta:{pid:"tags",id:"BDK-RN"}},{path:"/blog/tags/BDK-RN/index.html",redirect:"/blog/tags/BDK-RN/"},{name:"v-3acc51dc",path:"/blog/tags/Development/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-3acc51dc").then(n)},meta:{pid:"tags",id:"Development"}},{path:"/blog/tags/Development/index.html",redirect:"/blog/tags/Development/"},{name:"v-650ae784",path:"/blog/tags/Architecture/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-650ae784").then(n)},meta:{pid:"tags",id:"Architecture"}},{path:"/blog/tags/Architecture/index.html",redirect:"/blog/tags/Architecture/"},{name:"v-e646a928",path:"/blog/tags/basics/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-e646a928").then(n)},meta:{pid:"tags",id:"basics"}},{path:"/blog/tags/basics/index.html",redirect:"/blog/tags/basics/"},{name:"v-1fb58ffb",path:"/blog/tags/novice/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-1fb58ffb").then(n)},meta:{pid:"tags",id:"novice"}},{path:"/blog/tags/novice/index.html",redirect:"/blog/tags/novice/"},{name:"v-1296a8fa",path:"/blog/tags/bindings/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-1296a8fa").then(n)},meta:{pid:"tags",id:"bindings"}},{path:"/blog/tags/bindings/index.html",redirect:"/blog/tags/bindings/"},{name:"v-5ef73f54",path:"/blog/tags/tor/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5ef73f54").then(n)},meta:{pid:"tags",id:"tor"}},{path:"/blog/tags/tor/index.html",redirect:"/blog/tags/tor/"},{name:"v-39437010",path:"/blog/tags/wallet/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-39437010").then(n)},meta:{pid:"tags",id:"wallet"}},{path:"/blog/tags/wallet/index.html",redirect:"/blog/tags/wallet/"},{name:"v-7c8563fd",path:"/blog/tags/blockchain/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-7c8563fd").then(n)},meta:{pid:"tags",id:"blockchain"}},{path:"/blog/tags/blockchain/index.html",redirect:"/blog/tags/blockchain/"},{name:"v-baacba64",path:"/blog/tags/compact_filters/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-baacba64").then(n)},meta:{pid:"tags",id:"compact_filters"}},{path:"/blog/tags/compact_filters/index.html",redirect:"/blog/tags/compact_filters/"},{name:"v-75ccd5f2",path:"/blog/tags/BIP157/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-75ccd5f2").then(n)},meta:{pid:"tags",id:"BIP157"}},{path:"/blog/tags/BIP157/index.html",redirect:"/blog/tags/BIP157/"},{name:"v-4fed1c23",path:"/blog/tags/Neutrino/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4fed1c23").then(n)},meta:{pid:"tags",id:"Neutrino"}},{path:"/blog/tags/Neutrino/index.html",redirect:"/blog/tags/Neutrino/"},{name:"v-a9e0285e",path:"/blog/tags/guide/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-a9e0285e").then(n)},meta:{pid:"tags",id:"guide"}},{path:"/blog/tags/guide/index.html",redirect:"/blog/tags/guide/"},{name:"v-733ed37c",path:"/blog/tags/descriptor/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-733ed37c").then(n)},meta:{pid:"tags",id:"descriptor"}},{path:"/blog/tags/descriptor/index.html",redirect:"/blog/tags/descriptor/"},{name:"v-1144be8a",path:"/blog/tags/paper wallets/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-1144be8a").then(n)},meta:{pid:"tags",id:"paper wallets"}},{path:"/blog/tags/paper wallets/index.html",redirect:"/blog/tags/paper wallets/"},{name:"v-915f8322",path:"/blog/tags/bitcoin/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-915f8322").then(n)},meta:{pid:"tags",id:"bitcoin"}},{path:"/blog/tags/bitcoin/index.html",redirect:"/blog/tags/bitcoin/"},{name:"v-bf53d4d4",path:"/blog/tags/React Native/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-bf53d4d4").then(n)},meta:{pid:"tags",id:"React Native"}},{path:"/blog/tags/React Native/index.html",redirect:"/blog/tags/React Native/"},{name:"v-07eeb15e",path:"/blog/tags/Flutter/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-07eeb15e").then(n)},meta:{pid:"tags",id:"Flutter"}},{path:"/blog/tags/Flutter/index.html",redirect:"/blog/tags/Flutter/"},{name:"v-5f023740",path:"/blog/tags/iOS/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f023740").then(n)},meta:{pid:"tags",id:"iOS"}},{path:"/blog/tags/iOS/index.html",redirect:"/blog/tags/iOS/"},{name:"v-414e735e",path:"/blog/tags/Android/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-414e735e").then(n)},meta:{pid:"tags",id:"Android"}},{path:"/blog/tags/Android/index.html",redirect:"/blog/tags/Android/"},{name:"v-2c94bf22",path:"/blog/tags/mobile/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-2c94bf22").then(n)},meta:{pid:"tags",id:"mobile"}},{path:"/blog/tags/mobile/index.html",redirect:"/blog/tags/mobile/"},{name:"v-dd212a9e",path:"/blog/tags/bdk-rn/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-dd212a9e").then(n)},meta:{pid:"tags",id:"bdk-rn"}},{path:"/blog/tags/bdk-rn/index.html",redirect:"/blog/tags/bdk-rn/"},{name:"v-5f07f0f8",path:"/blog/tags/bdk/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f07f0f8").then(n)},meta:{pid:"tags",id:"bdk"}},{path:"/blog/tags/bdk/index.html",redirect:"/blog/tags/bdk/"},{name:"v-5f0447f2",path:"/blog/tags/fee/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f0447f2").then(n)},meta:{pid:"tags",id:"fee"}},{path:"/blog/tags/fee/index.html",redirect:"/blog/tags/fee/"},{name:"v-e2317b12",path:"/blog/tags/machine learning/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-e2317b12").then(n)},meta:{pid:"tags",id:"machine learning"}},{path:"/blog/tags/machine learning/index.html",redirect:"/blog/tags/machine learning/"},{name:"v-57f3a168",path:"/blog/tags/taproot/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-57f3a168").then(n)},meta:{pid:"tags",id:"taproot"}},{path:"/blog/tags/taproot/index.html",redirect:"/blog/tags/taproot/"},{name:"v-ef7c3fa2",path:"/blog/tags/miniscript/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-ef7c3fa2").then(n)},meta:{pid:"tags",id:"miniscript"}},{path:"/blog/tags/miniscript/index.html",redirect:"/blog/tags/miniscript/"},{name:"v-640144b2",path:"/blog/tags/Hardware Wallets/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-640144b2").then(n)},meta:{pid:"tags",id:"Hardware Wallets"}},{path:"/blog/tags/Hardware Wallets/index.html",redirect:"/blog/tags/Hardware Wallets/"},{name:"v-01a03a08",path:"/blog/tags/bitcoin-cli/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-01a03a08").then(n)},meta:{pid:"tags",id:"bitcoin-cli"}},{path:"/blog/tags/bitcoin-cli/index.html",redirect:"/blog/tags/bitcoin-cli/"},{name:"v-79c3de4b",path:"/blog/tags/getting started/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-79c3de4b").then(n)},meta:{pid:"tags",id:"getting started"}},{path:"/blog/tags/getting started/index.html",redirect:"/blog/tags/getting started/"},{name:"v-3fee41ed",path:"/blog/tags/rust/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-3fee41ed").then(n)},meta:{pid:"tags",id:"rust"}},{path:"/blog/tags/rust/index.html",redirect:"/blog/tags/rust/"},{name:"v-74edfe92",path:"/blog/tags/coin selection/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-74edfe92").then(n)},meta:{pid:"tags",id:"coin selection"}},{path:"/blog/tags/coin selection/index.html",redirect:"/blog/tags/coin selection/"},{name:"v-4e62fa1c",path:"/blog/tags/development/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4e62fa1c").then(n)},meta:{pid:"tags",id:"development"}},{path:"/blog/tags/development/index.html",redirect:"/blog/tags/development/"},{name:"v-0159a747",path:"/blog/tags/summer of bitcoin/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-0159a747").then(n)},meta:{pid:"tags",id:"summer of bitcoin"}},{path:"/blog/tags/summer of bitcoin/index.html",redirect:"/blog/tags/summer of bitcoin/"},{name:"v-0755ed11",path:"/blog/tags/security/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-0755ed11").then(n)},meta:{pid:"tags",id:"security"}},{path:"/blog/tags/security/index.html",redirect:"/blog/tags/security/"},{name:"v-543950a6",path:"/blog/tags/release/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-543950a6").then(n)},meta:{pid:"tags",id:"release"}},{path:"/blog/tags/release/index.html",redirect:"/blog/tags/release/"},{name:"v-a354115e",path:"/blog/author/Steve Myers/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-a354115e").then(n)},meta:{pid:"author",id:"Steve Myers"}},{path:"/blog/author/Steve Myers/index.html",redirect:"/blog/author/Steve Myers/"},{name:"v-22d0e252",path:"/blog/author/Daniela Brozzoni/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-22d0e252").then(n)},meta:{pid:"author",id:"Daniela Brozzoni"}},{path:"/blog/author/Daniela Brozzoni/index.html",redirect:"/blog/author/Daniela Brozzoni/"},{name:"v-5d54001e",path:"/blog/author/thunderbiscuit/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5d54001e").then(n)},meta:{pid:"author",id:"thunderbiscuit"}},{path:"/blog/author/thunderbiscuit/index.html",redirect:"/blog/author/thunderbiscuit/"},{name:"v-3e6950f4",path:"/blog/author/waterst0ne/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-3e6950f4").then(n)},meta:{pid:"author",id:"waterst0ne"}},{path:"/blog/author/waterst0ne/index.html",redirect:"/blog/author/waterst0ne/"},{name:"v-82e16b5c",path:"/blog/author/Rajarshi Maitra/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-82e16b5c").then(n)},meta:{pid:"author",id:"Rajarshi Maitra"}},{path:"/blog/author/Rajarshi Maitra/index.html",redirect:"/blog/author/Rajarshi Maitra/"},{name:"v-600b5b28",path:"/blog/author/Lloyd Fournier/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-600b5b28").then(n)},meta:{pid:"author",id:"Lloyd Fournier"}},{path:"/blog/author/Lloyd Fournier/index.html",redirect:"/blog/author/Lloyd Fournier/"},{name:"v-37829241",path:"/blog/author/Bitcoin Zavior/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-37829241").then(n)},meta:{pid:"author",id:"Bitcoin Zavior"}},{path:"/blog/author/Bitcoin Zavior/index.html",redirect:"/blog/author/Bitcoin Zavior/"},{name:"v-d2b26530",path:"/blog/author/rorp/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-d2b26530").then(n)},meta:{pid:"author",id:"rorp"}},{path:"/blog/author/rorp/index.html",redirect:"/blog/author/rorp/"},{name:"v-624fd61e",path:"/blog/author/Riccardo Casatta/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-624fd61e").then(n)},meta:{pid:"author",id:"Riccardo Casatta"}},{path:"/blog/author/Riccardo Casatta/index.html",redirect:"/blog/author/Riccardo Casatta/"},{name:"v-6b564fb4",path:"/blog/author/Gabriele Domenichini/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-6b564fb4").then(n)},meta:{pid:"author",id:"Gabriele Domenichini"}},{path:"/blog/author/Gabriele Domenichini/index.html",redirect:"/blog/author/Gabriele Domenichini/"},{name:"v-ad00c09c",path:"/blog/author/Alekos Filini/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-ad00c09c").then(n)},meta:{pid:"author",id:"Alekos Filini"}},{path:"/blog/author/Alekos Filini/index.html",redirect:"/blog/author/Alekos Filini/"},{name:"v-4eeab648",path:"/blog/author/Wszdexdrf/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4eeab648").then(n)},meta:{pid:"author",id:"Wszdexdrf"}},{path:"/blog/author/Wszdexdrf/index.html",redirect:"/blog/author/Wszdexdrf/"},{name:"v-91c10894",path:"/blog/author/Sandipan Dey/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-91c10894").then(n)},meta:{pid:"author",id:"Sandipan Dey"}},{path:"/blog/author/Sandipan Dey/index.html",redirect:"/blog/author/Sandipan Dey/"},{name:"v-a0d840b0",path:"/blog/author/César Alvarez Vallero/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-a0d840b0").then(n)},meta:{pid:"author",id:"César Alvarez Vallero"}},{path:"/blog/author/César Alvarez Vallero/index.html",redirect:"/blog/author/César Alvarez Vallero/"},{name:"v-c3507bb6",path:"/blog/page/2/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-c3507bb6").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/2/index.html",redirect:"/blog/page/2/"},{name:"v-c3507b78",path:"/blog/page/3/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-c3507b78").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/3/index.html",redirect:"/blog/page/3/"},{name:"v-c3507b3a",path:"/blog/page/4/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-c3507b3a").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/4/index.html",redirect:"/blog/page/4/"},{name:"v-73be14ce",path:"/blog/tags/BDK/page/2/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-73be14ce").then(n)},meta:{pid:"tags",id:"BDK"}},{path:"/blog/tags/BDK/page/2/index.html",redirect:"/blog/tags/BDK/page/2/"},{name:"v-5f2ac9cb",path:"/blog/author/Alekos Filini/page/2/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-5f2ac9cb").then(n)},meta:{pid:"author",id:"Alekos Filini"}},{path:"/blog/author/Alekos Filini/page/2/index.html",redirect:"/blog/author/Alekos Filini/page/2/"},{path:"*",component:Fc}],Ec={title:"Bitcoin Dev Kit Documentation",description:"The Bitcoin Dev Kit (BDK) project (originally called Magical Bitcoin 🧙) aims to build a collection of tools and libraries that are designed to be a solid foundation for cross platform Bitcoin wallets, along with a fully working reference implementation wallet called Magical Bitcoin.",base:"/",headTags:[["meta",{name:"viewport",content:"width=device-width,initial-scale=1.0"}],["link",{rel:"preload",href:"/fonts/ibm-plex-mono-400.woff2",as:"font",crossorigin:!0}],["link",{rel:"apple-touch-icon",sizes:"180x180",href:"/img/favicon/apple-touch-icon.png"}],["link",{rel:"manifest",href:"/site.webmanifest"}],["link",{rel:"stylesheet",href:"/css/variables.css"}],["link",{name:"msapplication-config",content:"/browserconfig.xml"}],["link",{name:"msapplication-TileColor",content:"#ffffff"}],["link",{name:"theme-color",content:"#ffffff"}]],pages:[{title:"Home",frontmatter:{home:!0,heroText:"Bitcoin Dev Kit",tagline:"With BDK, you can seamlessly build cross platform mobile wallets",actionText:"Get started",actionLink:"/getting-started/",features:[{title:"Customizable",details:"Designed from the ground up to be easily customized to your application needs: blockchain backends, databases, signers, coin selection, key management and more.",image:"customizable"},{title:"Focus on what matters",details:"All of the low-level Bitcoin logic is handled by us, so you can focus on crafting custom-tailored user experiences.",image:"focus"},{title:"High performance & compact",details:"As lightweight as you need it to be and optimized to run on all modern-day embedded devices such as mobile phones, IoT devices, PoS terminals and more.",image:"mobile"}],meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"With BDK, you can seamlessly build cross platform mobile wallets"},{property:"og:description",content:"We are building native API's for C, Swift, Java & Kotlin so you can easily integrate Bitcoin in your preferred programming language on mobile."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"With BDK, you can seamlessly build cross platform mobile wallets"},{name:"twitter:description",content:"We are building native API's for C, Swift, Java & Kotlin so you can easily integrate Bitcoin in your preferred programming language on mobile."},{name:"twitter:url",content:"https://bitcoindevkit.org/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/",relativePath:"README.md",key:"v-330a32a2",path:"/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"2024 Q1 Project Update",frontmatter:{title:"2024 Q1 Project Update",description:"2024 Q1 update on the BDK project's progress.",authors:["Steve Myers"],date:"2024-03-21",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-03-21T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2024 Q1 Project Update"},{property:"og:description",content:"2024 Q1 update on the BDK project's progress."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q1_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2024 Q1 Project Update"},{name:"twitter:description",content:"2024 Q1 update on the BDK project's progress."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q1_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q1_update.html",relativePath:"_blog/2024_q1_update.md",key:"v-5e744cf7",path:"/blog/_2024-q1-update/",headers:[{level:3,title:"Core BDK",slug:"core-bdk"},{level:3,title:"BDK-FFI",slug:"bdk-ffi"},{level:3,title:"Plans for Next Quarter",slug:"plans-for-next-quarter"},{level:3,title:"BDK contributors spotlight",slug:"bdk-contributors-spotlight"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"2023 Q4 Project Update",frontmatter:{title:"2023 Q4 Project Update",description:"2023 Q4 update on the BDK project's progress.",authors:["Steve Myers","Daniela Brozzoni"],date:"2024-02-20",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-02-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2023 Q4 Project Update"},{property:"og:description",content:"2023 Q4 update on the BDK project's progress."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2023_q4_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2023 Q4 Project Update"},{name:"twitter:description",content:"2023 Q4 update on the BDK project's progress."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2023_q4_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2023_q4_update.html",relativePath:"_blog/2023_q4_update.md",key:"v-2c450c3f",path:"/blog/_2023-q4-update/",headers:[{level:3,title:"This Post",slug:"this-post"},{level:3,title:"End of Year Review",slug:"end-of-year-review"},{level:3,title:"Core BDK",slug:"core-bdk"},{level:3,title:"BDK-FFI",slug:"bdk-ffi"},{level:3,title:"BDK contributors spotlight",slug:"bdk-contributors-spotlight"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"2024 Q2 Update: What Have We Been Up To?",frontmatter:{title:"2024 Q2 Update: What Have We Been Up To?",description:"2024 Q2 Update on the Bitcoin Dev Kit Project",authors:["thunderbiscuit"],date:"2024-07-01",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-07-01T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2024 Q2 Update: What Have We Been Up To?"},{property:"og:description",content:"2024 Q2 Update on the Bitcoin Dev Kit Project"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q2_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2024 Q2 Update: What Have We Been Up To?"},{name:"twitter:description",content:"2024 Q2 Update on the Bitcoin Dev Kit Project"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q2_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q2_update.html",relativePath:"_blog/2024_q2_update.md",key:"v-609f26f9",path:"/blog/_2024-q2-update/",headers:[{level:3,title:"Our Grantees in Action",slug:"our-grantees-in-action"},{level:3,title:"BDK in the Wild",slug:"bdk-in-the-wild"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Call for Proposals: Full-Time Open Source Rust Maintainer",frontmatter:{title:"Call for Proposals: Full-Time Open Source Rust Maintainer",description:"2024 Q3 Request for Applications for a Full-Time Open Source Rust Maintainer Grant",authors:["Steve Myers"],date:"2024-08-20",tags:["BDK","grants"],draft:!1,meta:[{property:"article:published_time",content:"2024-08-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Call for Proposals: Full-Time Open Source Rust Maintainer"},{property:"og:description",content:"2024 Q3 Request for Applications for a Full-Time Open Source Rust Maintainer Grant"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q3_rfp_rust_maintainer/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Call for Proposals: Full-Time Open Source Rust Maintainer"},{name:"twitter:description",content:"2024 Q3 Request for Applications for a Full-Time Open Source Rust Maintainer Grant"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q3_rfp_rust_maintainer/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, grants"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"grants"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q3_rfp_rust_maintainer.html",relativePath:"_blog/2024_q3_rfp_rust_maintainer.md",key:"v-bac76d8e",path:"/blog/_2024-q3-rfp-rust-maintainer/",headers:[{level:2,title:"Grant Overview",slug:"grant-overview"},{level:2,title:"Key Requirements",slug:"key-requirements"},{level:2,title:"Desired Qualifications",slug:"desired-qualifications"},{level:2,title:"Proposal Guidelines",slug:"proposal-guidelines"},{level:2,title:"Evaluation Criteria",slug:"evaluation-criteria"},{level:2,title:"Submission Process",slug:"submission-process"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"2024 Q3 Update: What Have We Been Up To?",frontmatter:{title:"2024 Q3 Update: What Have We Been Up To?",description:"2024 Q3 Update on the Bitcoin Dev Kit Project",authors:["thunderbiscuit"],date:"2024-11-07",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-11-07T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2024 Q3 Update: What Have We Been Up To?"},{property:"og:description",content:"2024 Q3 Update on the Bitcoin Dev Kit Project"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q3_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2024 Q3 Update: What Have We Been Up To?"},{name:"twitter:description",content:"2024 Q3 Update on the Bitcoin Dev Kit Project"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q3_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q3_update.html",relativePath:"_blog/2024_q3_update.md",key:"v-62ca00fb",path:"/blog/_2024-q3-update/",headers:[{level:3,title:"Our Grantees in Action",slug:"our-grantees-in-action"},{level:3,title:"BDK in the Wild",slug:"bdk-in-the-wild"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"bdk-cli basics multi-sig 2 of 3 tutorial",frontmatter:{title:"bdk-cli basics multi-sig 2 of 3 tutorial",description:"Tutorial using command-line to create a 2 of 3 multi-sig Wallet and Spend",authors:["waterst0ne"],date:"2022-10-17",tags:["tutorial","bdk-cli","multi-sig"],hidden:!1,draft:!1,meta:[{property:"article:published_time",content:"2022-10-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"bdk-cli basics multi-sig 2 of 3 tutorial"},{property:"og:description",content:"Tutorial using command-line to create a 2 of 3 multi-sig Wallet and Spend"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk-cli_basics_multisig_2of3/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"bdk-cli basics multi-sig 2 of 3 tutorial"},{name:"twitter:description",content:"Tutorial using command-line to create a 2 of 3 multi-sig Wallet and Spend"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk-cli_basics_multisig_2of3/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, bdk-cli, multi-sig"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"multi-sig"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk-cli_basics_multisig_2of3.html",relativePath:"_blog/bdk-cli_basics_multisig_2of3.md",key:"v-8bd632d6",path:"/blog/bdk-cli-basics-multisig-2of3/",headers:[{level:2,title:"2-of-3 Multi-Signature Descriptor Wallet using bdk-cli",slug:"2-of-3-multi-signature-descriptor-wallet-using-bdk-cli"},{level:2,title:"Overview of the tutorial",slug:"overview-of-the-tutorial"},{level:2,title:"Step 1: Generate the XPRVs (Extended-Keys) and Save to environment variables",slug:"step-1-generate-the-xprvs-extended-keys-and-save-to-environment-variables"},{level:3,title:"1a: Verify XPRV environment variables are Active",slug:"1a-verify-xprv-environment-variables-are-active"},{level:2,title:"Step 2: Generate XPUBs (Extended Public Keys) & Save to environment variables",slug:"step-2-generate-xpubs-extended-public-keys-save-to-environment-variables"},{level:3,title:"2a: Verify XPUB environment variables",slug:"2a-verify-xpub-environment-variables"},{level:2,title:"Step 3: Create Single-Wallet Descriptors",slug:"step-3-create-single-wallet-descriptors"},{level:2,title:"Step 4: Create Multi-Sig-Descriptor Wallets",slug:"step-4-create-multi-sig-descriptor-wallets"},{level:3,title:"4a: Verify Multi-Sig-Descriptor environment variables are active",slug:"4a-verify-multi-sig-descriptor-environment-variables-are-active"},{level:2,title:"Step 5: Generate Receive Address by using Multi-Sig-Descriptor Wallets",slug:"step-5-generate-receive-address-by-using-multi-sig-descriptor-wallets"},{level:2,title:"Step 6: Send Testnet Bitcoin to the newly created receive-address",slug:"step-6-send-testnet-bitcoin-to-the-newly-created-receive-address"},{level:2,title:"Step 7: Sync one of the Multi-Sig Wallets",slug:"step-7-sync-one-of-the-multi-sig-wallets"},{level:2,title:"Step 8: Check Balance Multi-Sig Wallets",slug:"step-8-check-balance-multi-sig-wallets"},{level:2,title:"Step 9: Check Multi-Sig Policies on Descriptor Wallet",slug:"step-9-check-multi-sig-policies-on-descriptor-wallet"},{level:3,title:"SpendingPolicyRequired for complex descriptors",slug:"spendingpolicyrequired-for-complex-descriptors"},{level:2,title:"Step 10: Create a Transaction (PSBT)",slug:"step-10-create-a-transaction-psbt"},{level:3,title:"Export UNSIGNED_PSBT to environment variable",slug:"export-unsigned-psbt-to-environment-variable"},{level:3,title:"Verify UNSIGNED_PSBT environment variable",slug:"verify-unsigned-psbt-environment-variable"},{level:2,title:"Step 11: SIGN the Transaction",slug:"step-11-sign-the-transaction"},{level:3,title:"1st Wallet Signs the transaction",slug:"1st-wallet-signs-the-transaction"},{level:3,title:"2nd Wallet Signs the transaction",slug:"2nd-wallet-signs-the-transaction"},{level:2,title:"Step 12: Broadcast Transaction",slug:"step-12-broadcast-transaction"},{level:3,title:"Verify Transaction",slug:"verify-transaction"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"BDK wallet with Bitcoin core RPC",frontmatter:{title:"BDK wallet with Bitcoin core RPC ",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:!0,draft:!1,meta:[{property:"article:published_time",content:"2021-08-21T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK wallet with Bitcoin core RPC"},{property:"og:description",content:"Tutorial showing usage of Bitcoin core backend with BDK wallet"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/Bitcoin_Core_RPC_Demo/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK wallet with Bitcoin core RPC"},{name:"twitter:description",content:"Tutorial showing usage of Bitcoin core backend with BDK wallet"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/Bitcoin_Core_RPC_Demo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, BDK, Bitcoin Core, RPC, Wallet"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"Bitcoin Core"},{property:"article:tag",content:"RPC"},{property:"article:tag",content:"Wallet"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/Bitcoin_Core_RPC_Demo.html",relativePath:"_blog/Bitcoin_Core_RPC_Demo.md",key:"v-7c0c45f9",path:"/blog/bitcoin-core-rpc-demo/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Prerequisite",slug:"prerequisite"},{level:2,title:"Setting Up",slug:"setting-up"},{level:2,title:"Setting dependencies",slug:"setting-dependencies"},{level:2,title:"Getting Descriptors",slug:"getting-descriptors"},{level:2,title:"Talking to Bitcoin Core Programmatically",slug:"talking-to-bitcoin-core-programmatically"},{level:2,title:"Get some balance in core wallet.",slug:"get-some-balance-in-core-wallet"},{level:2,title:"Setup the BDK wallet",slug:"setup-the-bdk-wallet"},{level:2,title:"Sending Sats Around",slug:"sending-sats-around"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"bdk_core: a new architecture for the Bitcoin Dev Kit",frontmatter:{title:"`bdk_core`: a new architecture for the Bitcoin Dev Kit",description:"A new architecture for the Bitcoin Dev Kit",authors:["Lloyd Fournier"],date:"2022-05-09",tags:["architecture"],draft:!1,meta:[{property:"article:published_time",content:"2022-05-09T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"bdk_core: a new architecture for the Bitcoin Dev Kit"},{property:"og:description",content:"A new architecture for the Bitcoin Dev Kit"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_core_pt1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"bdk_core: a new architecture for the Bitcoin Dev Kit"},{name:"twitter:description",content:"A new architecture for the Bitcoin Dev Kit"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_core_pt1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"architecture"},{property:"article:tag",content:"architecture"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_core_pt1.html",relativePath:"_blog/bdk_core_pt1.md",key:"v-2cebe183",path:"/blog/bdk-core-pt1/",headers:[{level:2,title:"The separation of policy and mechanism",slug:"the-separation-of-policy-and-mechanism"},{level:2,title:"A syncing mechansim without the policy",slug:"a-syncing-mechansim-without-the-policy"},{level:3,title:"A general syncing mechanism",slug:"a-general-syncing-mechanism"},{level:3,title:"How to store and index transactions",slug:"how-to-store-and-index-transactions"},{level:3,title:"Rolling back, rolling forward and syncing to disk",slug:"rolling-back-rolling-forward-and-syncing-to-disk"},{level:2,title:"Examples",slug:"examples"},{level:3,title:"Doing an initial sync of a descriptor that may already contain coins",slug:"doing-an-initial-sync-of-a-descriptor-that-may-already-contain-coins"},{level:3,title:"Doing a sync of a wallet after you already have sync'd",slug:"doing-a-sync-of-a-wallet-after-you-already-have-syncd"},{level:3,title:"Updating state when you get the data in real time",slug:"updating-state-when-you-get-the-data-in-real-time"},{level:2,title:"Feedback",slug:"feedback"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"bdk-rn: Behind the scenes",frontmatter:{title:"`bdk-rn`: Behind the scenes",description:"bdk-rn: React Native version of BitcoinDevKit. Insight into how bdk-rn was developed",authors:["Bitcoin Zavior"],date:"2022-07-10",tags:["BDK-RN","Development","Architecture"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-07-10T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"bdk-rn: Behind the scenes"},{property:"og:description",content:"bdk-rn: React Native version of BitcoinDevKit. Insight into how bdk-rn was developed"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_rn_making_of/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"bdk-rn: Behind the scenes"},{name:"twitter:description",content:"bdk-rn: React Native version of BitcoinDevKit. Insight into how bdk-rn was developed"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_rn_making_of/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK-RN, Development, Architecture"},{property:"article:tag",content:"BDK-RN"},{property:"article:tag",content:"Development"},{property:"article:tag",content:"Architecture"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_rn_making_of.html",relativePath:"_blog/bdk_rn_making_of.md",key:"v-3eaa044d",path:"/blog/bdk-rn-making-of/",headers:[{level:2,title:"React Native Architecture",slug:"react-native-architecture"},{level:2,title:"Native Integration",slug:"native-integration"},{level:2,title:"Android Module",slug:"android-module"},{level:2,title:"References",slug:"references"},{level:2,title:"Feedback",slug:"feedback"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Command Line introduction to Bitcoin Wallet Development using bdk-cli",frontmatter:{title:"Command Line introduction to Bitcoin Wallet Development using bdk-cli",description:"Intro to bdk-cli and wallet dev",authors:["waterst0ne"],date:"2022-09-22",tags:["bdk-cli","basics","novice"],meta:[{property:"article:published_time",content:"2022-09-22T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Command Line introduction to Bitcoin Wallet Development using bdk-cli"},{property:"og:description",content:"Intro to bdk-cli and wallet dev"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_cli_basics/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Command Line introduction to Bitcoin Wallet Development using bdk-cli"},{name:"twitter:description",content:"Intro to bdk-cli and wallet dev"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_cli_basics/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bdk-cli, basics, novice"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"basics"},{property:"article:tag",content:"novice"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_cli_basics.html",relativePath:"_blog/bdk_cli_basics.md",key:"v-0f4d5d15",path:"/blog/bdk-cli-basics/",headers:[{level:2,title:"Tutorial Goals",slug:"tutorial-goals"},{level:2,title:"A few things before you begin:",slug:"a-few-things-before-you-begin"},{level:3,title:"Outline of Tutorial and Installation notes:",slug:"outline-of-tutorial-and-installation-notes"},{level:3,title:"Brief Outline of Tutorial",slug:"brief-outline-of-tutorial"},{level:3,title:"Rust and Cargo installation:",slug:"rust-and-cargo-installation"},{level:3,title:"bdk-cli installation:",slug:"bdk-cli-installation"},{level:3,title:"Emoji Legend:",slug:"emoji-legend"},{level:2,title:"Step 0: Check Version of bdk-cli",slug:"step-0-check-version-of-bdk-cli"},{level:3,title:"Preview of bdk-cli help menu",slug:"preview-of-bdk-cli-help-menu"},{level:2,title:"Step 1: Seed Generate",slug:"step-1-seed-generate"},{level:3,title:"1a: Mnemonic word-list + XPRV (Extended Private Key) :key:",slug:"1a-mnemonic-word-list-xprv-extended-private-key-"},{level:3,title:"1b: Save XPRV (Extended Private Key) into environment variable",slug:"1b-save-xprv-extended-private-key-into-environment-variable"},{level:3,title:"1c: Verify environment variable XPRV_00 is active",slug:"1c-verify-environment-variable-xprv-00-is-active"},{level:3,title:"1d: Create Descriptor and Save into environment variable",slug:"1d-create-descriptor-and-save-into-environment-variable"},{level:3,title:"1e: Verify environment variable my_descriptor is active",slug:"1e-verify-environment-variable-my-descriptor-is-active"},{level:2,title:"Step 2: Generate Receive-Address",slug:"step-2-generate-receive-address"},{level:2,title:"Step 3: Send testnet bitcoin to the newly created receive-address",slug:"step-3-send-testnet-bitcoin-to-the-newly-created-receive-address"},{level:2,title:"Step 4: Sync the wallet",slug:"step-4-sync-the-wallet"},{level:2,title:"Step 5: Check the balance",slug:"step-5-check-the-balance"},{level:2,title:"Step 6: Create Transaction (PSBT)",slug:"step-6-create-transaction-psbt"},{level:3,title:"6a: export PSBT to environment-variable",slug:"6a-export-psbt-to-environment-variable"},{level:2,title:"Step 7: Sign Transaction (PSBT)",slug:"step-7-sign-transaction-psbt"},{level:3,title:"7a: export signed psbt to environment variable",slug:"7a-export-signed-psbt-to-environment-variable"},{level:2,title:"Step 8: Broadcast Transaction",slug:"step-8-broadcast-transaction"},{level:2,title:"Resources",slug:"resources"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"BDK's Scope and Approach to Rust Bindings",frontmatter:{title:"BDK's Scope and Approach to Rust Bindings",description:"An outline of BDK's approach to language bindings and how we intend on supporting others build their own.",authors:["thunderbiscuit"],date:"2023-06-02",tags:["BDK","bindings"],meta:[{property:"article:published_time",content:"2023-06-02T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK's Scope and Approach to Rust Bindings"},{property:"og:description",content:"An outline of BDK's approach to language bindings and how we intend on supporting others build their own."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bindings-scope/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK's Scope and Approach to Rust Bindings"},{name:"twitter:description",content:"An outline of BDK's approach to language bindings and how we intend on supporting others build their own."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bindings-scope/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, bindings"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"bindings"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bindings-scope.html",relativePath:"_blog/bindings-scope.md",key:"v-3875825f",path:"/blog/bindings-scope/",headers:[{level:2,title:"Current architecture",slug:"current-architecture"},{level:2,title:"Moving forward: building a family of libraries",slug:"moving-forward-building-a-family-of-libraries"},{level:2,title:"Why can't we just build one big BDK library with everything in it?",slug:"why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"},{level:2,title:"Are you looking to build Rust bindings yourself?",slug:"are-you-looking-to-build-rust-bindings-yourself"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Using BDK with Tor",frontmatter:{title:"Using BDK with Tor",description:"How to integrate Tor client to sync BDK wallet with tor enabled blockchain service",authors:["rorp"],date:"2023-01-03",tags:["tutorial","tor","wallet","blockchain"],meta:[{property:"article:published_time",content:"2023-01-03T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Using BDK with Tor"},{property:"og:description",content:"How to integrate Tor client to sync BDK wallet with tor enabled blockchain service"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_with_tor/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Using BDK with Tor"},{name:"twitter:description",content:"How to integrate Tor client to sync BDK wallet with tor enabled blockchain service"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_with_tor/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, tor, wallet, blockchain"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"tor"},{property:"article:tag",content:"wallet"},{property:"article:tag",content:"blockchain"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_with_tor.html",relativePath:"_blog/bdk_with_tor.md",key:"v-353b78e1",path:"/blog/bdk-with-tor/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Prerequisite",slug:"prerequisite"},{level:2,title:"Setting Up",slug:"setting-up"},{level:2,title:"ElectrumBlockchain",slug:"electrumblockchain"},{level:2,title:"Blocking EsploraBlockchain",slug:"blocking-esplorablockchain"},{level:2,title:"Asynchronous EsploraBlockchain",slug:"asynchronous-esplorablockchain"},{level:2,title:"CompactFiltersBlockchain",slug:"compactfiltersblockchain"},{level:2,title:"Integrated Tor daemon",slug:"integrated-tor-daemon"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"BDK wallet as a BIP157 SPV light client",frontmatter:{title:"BDK wallet as a BIP157 SPV light client",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"],meta:[{property:"article:published_time",content:"2021-06-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK wallet as a BIP157 SPV light client"},{property:"og:description",content:"Tutorial showing usage of compact filters (BIP157) using bdk-cli command line tools"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/compact_filters_demo/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK wallet as a BIP157 SPV light client"},{name:"twitter:description",content:"Tutorial showing usage of compact filters (BIP157) using bdk-cli command line tools"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/compact_filters_demo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, BDK, bdk-cli, compact_filters, BIP157, Neutrino"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"compact_filters"},{property:"article:tag",content:"BIP157"},{property:"article:tag",content:"Neutrino"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/compact_filters_demo.html",relativePath:"_blog/compact_filters_demo.md",key:"v-07ff1843",path:"/blog/compact-filters-demo/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:3,title:"Compact Filters:",slug:"compact-filters"},{level:3,title:"BDK and Compact filters",slug:"bdk-and-compact-filters"},{level:3,title:"bdk-cli",slug:"bdk-cli"},{level:2,title:"Tutorial Scope",slug:"tutorial-scope"},{level:2,title:"Prerequisites",slug:"prerequisites"},{level:3,title:"Install and run bitcoind",slug:"install-and-run-bitcoind"},{level:3,title:"Install and run bdk-cli",slug:"install-and-run-bdk-cli"},{level:2,title:"Tutorial",slug:"tutorial"},{level:3,title:"Bitcoin Core Wallet Generation",slug:"bitcoin-core-wallet-generation"},{level:3,title:"BDK Wallet Generation",slug:"bdk-wallet-generation"},{level:3,title:"Recieve Coins",slug:"recieve-coins"},{level:3,title:"Creating a transaction.",slug:"creating-a-transaction"},{level:3,title:"Sign and Broadcast the transaction",slug:"sign-and-broadcast-the-transaction"},{level:3,title:"Confirming the Transaction",slug:"confirming-the-transaction"},{level:3,title:"Shutdown Docker",slug:"shutdown-docker"},{level:2,title:"End Words",slug:"end-words"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Making Descriptor-based paper wallets",frontmatter:{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"],meta:[{property:"article:published_time",content:"2021-03-30T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Making Descriptor-based paper wallets"},{property:"og:description",content:"Demonstrate how to create descriptor-based paper wallet and how to spend them with bdk"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/descriptor_based_paper_wallet/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Making Descriptor-based paper wallets"},{name:"twitter:description",content:"Demonstrate how to create descriptor-based paper wallet and how to spend them with bdk"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/descriptor_based_paper_wallet/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"guide, descriptor, paper wallets"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"descriptor"},{property:"article:tag",content:"paper wallets"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/descriptor_based_paper_wallet.html",relativePath:"_blog/descriptor_based_paper_wallet.md",key:"v-9504490e",path:"/blog/descriptor-based-paper-wallet/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"About paper wallets",slug:"about-paper-wallets"},{level:2,title:"Descriptors",slug:"descriptors"},{level:2,title:"Example use case",slug:"example-use-case"},{level:2,title:"Creating the paper wallet",slug:"creating-the-paper-wallet"},{level:2,title:"BDK",slug:"bdk"},{level:2,title:"Funding tx",slug:"funding-tx"},{level:2,title:"Sweep tx",slug:"sweep-tx"},{level:3,title:"Step 1: Alice creates and signs a PSBT",slug:"step-1-alice-creates-and-signs-a-psbt"},{level:3,title:"Step 2: Barbara signs Alice's signed PSBT and broadcasts the tx",slug:"step-2-barbara-signs-alices-signed-psbt-and-broadcasts-the-tx"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"BDK-FLUTTER: Building Flutter Apps with BDK",frontmatter:{title:"BDK-FLUTTER: Building Flutter Apps with BDK",description:"A tutorial and guide to using bdk-flutter for building bitcoin apps",authors:["Bitcoin Zavior"],date:"2022-10-05",tags:["bitcoin","React Native","Flutter","iOS","Android","mobile","bdk-rn","bdk","tutorial","guide","wallet"],meta:[{property:"article:published_time",content:"2022-10-05T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK-FLUTTER: Building Flutter Apps with BDK"},{property:"og:description",content:"A tutorial and guide to using bdk-flutter for building bitcoin apps"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_flutter/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK-FLUTTER: Building Flutter Apps with BDK"},{name:"twitter:description",content:"A tutorial and guide to using bdk-flutter for building bitcoin apps"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_flutter/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bitcoin, React Native, Flutter, iOS, Android, mobile, bdk-rn, bdk, tutorial, guide, wallet"},{property:"article:tag",content:"bitcoin"},{property:"article:tag",content:"React Native"},{property:"article:tag",content:"Flutter"},{property:"article:tag",content:"iOS"},{property:"article:tag",content:"Android"},{property:"article:tag",content:"mobile"},{property:"article:tag",content:"bdk-rn"},{property:"article:tag",content:"bdk"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"wallet"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/exploring_bdk_flutter.html",relativePath:"_blog/exploring_bdk_flutter.md",key:"v-56536559",path:"/blog/exploring-bdk-flutter/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:3,title:"Prerequisites",slug:"prerequisites"},{level:3,title:"Bitcoin Basics",slug:"bitcoin-basics"},{level:2,title:"Bitcoin Dev Kit and bdk-flutter",slug:"bitcoin-dev-kit-and-bdk-flutter"},{level:2,title:"Getting Started",slug:"getting-started"},{level:2,title:"Setting up Flutter app structure",slug:"setting-up-flutter-app-structure"},{level:2,title:"Installing bdk-flutter",slug:"installing-bdk-flutter"},{level:2,title:"Configuring",slug:"configuring"},{level:2,title:"Importing bdk-flutter",slug:"importing-bdk-flutter"},{level:2,title:"Calling bdk-flutter methods",slug:"calling-bdk-flutter-methods"},{level:2,title:"Creating a wallet",slug:"creating-a-wallet"},{level:2,title:"UTXOs and balance",slug:"utxos-and-balance"},{level:2,title:"Restoring a wallet",slug:"restoring-a-wallet"},{level:2,title:"Sending bitcoin",slug:"sending-bitcoin"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"BDK-RN: Building React Native Apps with BDK",frontmatter:{title:"BDK-RN: Building React Native Apps with BDK",description:"A tutorial and guide to using bdk-rn for building bitcoin apps",authors:["Bitcoin Zavior"],date:"2022-08-05",tags:["bitcoin","React Native","iOS","Android","mobile","bdk-rn","bdk","tutorial","guide","wallet"],meta:[{property:"article:published_time",content:"2022-08-05T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK-RN: Building React Native Apps with BDK"},{property:"og:description",content:"A tutorial and guide to using bdk-rn for building bitcoin apps"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_rn/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK-RN: Building React Native Apps with BDK"},{name:"twitter:description",content:"A tutorial and guide to using bdk-rn for building bitcoin apps"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_rn/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bitcoin, React Native, iOS, Android, mobile, bdk-rn, bdk, tutorial, guide, wallet"},{property:"article:tag",content:"bitcoin"},{property:"article:tag",content:"React Native"},{property:"article:tag",content:"iOS"},{property:"article:tag",content:"Android"},{property:"article:tag",content:"mobile"},{property:"article:tag",content:"bdk-rn"},{property:"article:tag",content:"bdk"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"wallet"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/exploring_bdk_rn.html",relativePath:"_blog/exploring_bdk_rn.md",key:"v-f58ec8f2",path:"/blog/exploring-bdk-rn/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:3,title:"Prerequisites",slug:"prerequisites"},{level:3,title:"Bitcoin Basics",slug:"bitcoin-basics"},{level:2,title:"Bitcoin Dev Kit and bdk-rn",slug:"bitcoin-dev-kit-and-bdk-rn"},{level:2,title:"Getting Started",slug:"getting-started"},{level:2,title:"Setting up styles and RN app structure",slug:"setting-up-styles-and-rn-app-structure"},{level:2,title:"Installing bdk-rn",slug:"installing-bdk-rn"},{level:2,title:"Importing bdk-rn",slug:"importing-bdk-rn"},{level:2,title:"Calling bdk-rn methods",slug:"calling-bdk-rn-methods"},{level:2,title:"Creating a wallet",slug:"creating-a-wallet"},{level:2,title:"UTXOs and balance",slug:"utxos-and-balance"},{level:2,title:"Restoring wallet",slug:"restoring-wallet"},{level:2,title:"Sending bitcoin",slug:"sending-bitcoin"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Fee estimation for light-clients (Part 1)",frontmatter:{title:"Fee estimation for light-clients (Part 1)",description:"Applying machine learning to the bitcoin fee estimation problem",authors:["Riccardo Casatta"],date:"2021-01-25",tags:["fee","machine learning"],permalink:"/blog/2021/01/fee-estimation-for-light-clients-part-1/",meta:[{property:"article:published_time",content:"2021-01-25T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Fee estimation for light-clients (Part 1)"},{property:"og:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Fee estimation for light-clients (Part 1)"},{name:"twitter:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"fee, machine learning"},{property:"article:tag",content:"fee"},{property:"article:tag",content:"machine learning"}],layout:"Post"},regularPath:"/_blog/fee_estimation_for_light_clients_part_1.html",relativePath:"_blog/fee_estimation_for_light_clients_part_1.md",key:"v-015729b9",path:"/blog/2021/01/fee-estimation-for-light-clients-part-1/",headers:[{level:2,title:"Introduction: what is fee estimation?",slug:"introduction-what-is-fee-estimation"},{level:2,title:"The problem",slug:"the-problem"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"A Multisig between BDK and Core",frontmatter:{title:"A Multisig between BDK and Core",description:"Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK",authors:["Gabriele Domenichini"],date:"2020-11-18",tags:["guide","descriptor"],meta:[{property:"article:published_time",content:"2020-11-18T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"A Multisig between BDK and Core"},{property:"og:description",content:"Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/descriptors_in_the_wild/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"A Multisig between BDK and Core"},{name:"twitter:description",content:"Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/descriptors_in_the_wild/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"guide, descriptor"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"descriptor"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/descriptors_in_the_wild.html",relativePath:"_blog/descriptors_in_the_wild.md",key:"v-c6756cce",path:"/blog/descriptors-in-the-wild/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"The use case",slug:"the-use-case"},{level:2,title:"The role of Descriptors",slug:"the-role-of-descriptors"},{level:2,title:"Our playground",slug:"our-playground"},{level:3,title:"1. Creating the seeds and the derived Extended Public keys",slug:"1-creating-the-seeds-and-the-derived-extended-public-keys"},{level:3,title:"2. Creation of the multi signature descriptor for each wallet",slug:"2-creation-of-the-multi-signature-descriptor-for-each-wallet"},{level:3,title:"3. Use each other's software to receive testnet coins from a faucet",slug:"3-use-each-others-software-to-receive-testnet-coins-from-a-faucet"},{level:3,title:"4. we return part of the satoshis received back to the faucet",slug:"4-we-return-part-of-the-satoshis-received-back-to-the-faucet"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Fee estimation for light-clients (Part 2)",frontmatter:{title:"Fee estimation for light-clients (Part 2)",description:"Applying machine learning to the bitcoin fee estimation problem",authors:["Riccardo Casatta"],date:"2021-01-25",tags:["fee","machine learning"],permalink:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",meta:[{property:"article:published_time",content:"2021-01-25T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Fee estimation for light-clients (Part 2)"},{property:"og:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Fee estimation for light-clients (Part 2)"},{name:"twitter:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"fee, machine learning"},{property:"article:tag",content:"fee"},{property:"article:tag",content:"machine learning"}],layout:"Post"},regularPath:"/_blog/fee_estimation_for_light_clients_part_2.html",relativePath:"_blog/fee_estimation_for_light_clients_part_2.md",key:"v-2c605799",path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",headers:[{level:2,title:"The dataset",slug:"the-dataset"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Fee estimation for light-clients (Part 3)",frontmatter:{title:"Fee estimation for light-clients (Part 3)",description:"Applying machine learning to the bitcoin fee estimation problem",authors:["Riccardo Casatta"],date:"2021-01-25",tags:["fee","machine learning"],permalink:"/blog/2021/01/fee-estimation-for-light-clients-part-3/",meta:[{property:"article:published_time",content:"2021-01-25T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Fee estimation for light-clients (Part 3)"},{property:"og:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Fee estimation for light-clients (Part 3)"},{name:"twitter:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"fee, machine learning"},{property:"article:tag",content:"fee"},{property:"article:tag",content:"machine learning"}],layout:"Post"},regularPath:"/_blog/fee_estimation_for_light_clients_part_3.html",relativePath:"_blog/fee_estimation_for_light_clients_part_3.md",key:"v-57698579",path:"/blog/2021/01/fee-estimation-for-light-clients-part-3/",headers:[{level:2,title:"The model",slug:"the-model"},{level:2,title:"The prediction phase",slug:"the-prediction-phase"},{level:2,title:"Conclusion and future development",slug:"conclusion-and-future-development"},{level:2,title:"Acknowledgements",slug:"acknowledgements"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"The first BDK Taproot TX: a look at the code (Part 1)",frontmatter:{title:"The first BDK Taproot TX: a look at the code (Part 1)",description:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction",authors:["Alekos Filini"],date:"2021-11-15",tags:["BDK","taproot","miniscript"],permalink:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1",meta:[{property:"article:published_time",content:"2021-11-15T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"The first BDK Taproot TX: a look at the code (Part 1)"},{property:"og:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"The first BDK Taproot TX: a look at the code (Part 1)"},{name:"twitter:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, taproot, miniscript"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"taproot"},{property:"article:tag",content:"miniscript"}],layout:"Post"},regularPath:"/_blog/first_bdk_taproot_tx.html",relativePath:"_blog/first_bdk_taproot_tx.md",key:"v-9145467a",path:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/",headers:[{level:2,title:"Backstory",slug:"backstory"},{level:2,title:"rust-bitcoin",slug:"rust-bitcoin"},{level:2,title:"rust-miniscript",slug:"rust-miniscript"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"The first BDK Taproot TX: a look at the code (Part 2)",frontmatter:{title:"The first BDK Taproot TX: a look at the code (Part 2)",description:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction",authors:["Alekos Filini"],date:"2021-12-10",tags:["BDK","taproot","miniscript"],permalink:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2",meta:[{property:"article:published_time",content:"2021-12-10T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"The first BDK Taproot TX: a look at the code (Part 2)"},{property:"og:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"The first BDK Taproot TX: a look at the code (Part 2)"},{name:"twitter:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, taproot, miniscript"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"taproot"},{property:"article:tag",content:"miniscript"}],layout:"Post"},regularPath:"/_blog/first_bdk_taproot_tx_part_2.html",relativePath:"_blog/first_bdk_taproot_tx_part_2.md",key:"v-2cf72b39",path:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/",headers:[{level:2,title:"Shortcuts",slug:"shortcuts"},{level:2,title:"Utilities",slug:"utilities"},{level:2,title:"Wrap Fallible Methods",slug:"wrap-fallible-methods"},{level:2,title:"Descriptor Metadata",slug:"descriptor-metadata"},{level:2,title:"Policy",slug:"policy"},{level:2,title:"Signer",slug:"signer"},{level:2,title:"PSBT Metadata",slug:"psbt-metadata"},{level:2,title:"descriptor!() Macro",slug:"descriptor-macro"},{level:3,title:"tr() Descriptors",slug:"tr-descriptors"},{level:3,title:"multi_a() Operator",slug:"multi-a-operator"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Getting Started with rust-hwi",frontmatter:{title:"Getting Started with rust-hwi",description:"This post will help one understand and develop for hardware wallets using BDK",authors:["Wszdexdrf"],date:"2022-08-16",tags:["BDK","Development","Hardware Wallets"],draft:!1,meta:[{property:"article:published_time",content:"2022-08-16T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Getting Started with rust-hwi"},{property:"og:description",content:"This post will help one understand and develop for hardware wallets using BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/getting_started_with_rust_hwi/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Getting Started with rust-hwi"},{name:"twitter:description",content:"This post will help one understand and develop for hardware wallets using BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/getting_started_with_rust_hwi/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, Development, Hardware Wallets"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"Development"},{property:"article:tag",content:"Hardware Wallets"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/getting_started_with_rust_hwi.html",relativePath:"_blog/getting_started_with_rust_hwi.md",key:"v-11d64359",path:"/blog/getting-started-with-rust-hwi/",headers:[{level:2,title:"Fundamentals",slug:"fundamentals"},{level:2,title:"Integration with BDK",slug:"integration-with-bdk"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Hidden Powers of Miniscript Policy & Descriptors",frontmatter:{title:"Hidden Powers of Miniscript Policy & Descriptors",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:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-01-02T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Hidden Powers of Miniscript Policy & Descriptors"},{property:"og:description",content:"Introduction to Descriptor and Miniscript, making a Multisig Wallet and Testing Miniscript Policies"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/hidden-power-of-bitcoin/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Hidden Powers of Miniscript Policy & Descriptors"},{name:"twitter:description",content:"Introduction to Descriptor and Miniscript, making a Multisig Wallet and Testing Miniscript Policies"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/hidden-power-of-bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, bdk, bdk-cli, miniscript, descriptor, bitcoin-cli"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"bdk"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"miniscript"},{property:"article:tag",content:"descriptor"},{property:"article:tag",content:"bitcoin-cli"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/hidden-power-of-bitcoin.html",relativePath:"_blog/hidden-power-of-bitcoin.md",key:"v-ab5ba3ce",path:"/blog/hidden-power-of-bitcoin/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Script",slug:"script"},{level:2,title:"Miniscript",slug:"miniscript"},{level:2,title:"Descriptors",slug:"descriptors"},{level:2,title:"Where it all comes together...",slug:"where-it-all-comes-together"},{level:3,title:"Keys and Generating Addresses",slug:"keys-and-generating-addresses"},{level:3,title:"Making a MultiSig Descriptor for Funds",slug:"making-a-multisig-descriptor-for-funds"},{level:2,title:"Retention Bonus - Smart Contract with Bitcoin",slug:"retention-bonus-smart-contract-with-bitcoin"},{level:2,title:"Inspirations",slug:"inspirations"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Hello World!",frontmatter:{title:"Hello World!",description:"Getting started using the BDK library in a very simple Rust project",authors:["Alekos Filini"],date:"2020-12-18",tags:["getting started","rust"],permalink:"/blog/2020/12/hello-world/",meta:[{property:"article:published_time",content:"2020-12-18T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Hello World!"},{property:"og:description",content:"Getting started using the BDK library in a very simple Rust project"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2020/12/hello-world/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Hello World!"},{name:"twitter:description",content:"Getting started using the BDK library in a very simple Rust project"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2020/12/hello-world/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"getting started, rust"},{property:"article:tag",content:"getting started"},{property:"article:tag",content:"rust"}],layout:"Post"},regularPath:"/_blog/hello-world.html",relativePath:"_blog/hello-world.md",key:"v-5d749fce",path:"/blog/2020/12/hello-world/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Design Goals",slug:"design-goals"},{level:2,title:"The Wallet Structure",slug:"the-wallet-structure"},{level:2,title:"Custom Database and Blockchain types",slug:"custom-database-and-blockchain-types"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Improving coin selection in BDK",frontmatter:{title:"Improving coin selection in BDK",description:"A brief description of the work done in the coin selection module in BDK during Summer of Bitcoin 2022",date:"2022-08-17",tags:["coin selection","BDK","development","summer of bitcoin"],authors:["César Alvarez Vallero"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-08-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Improving coin selection in BDK"},{property:"og:description",content:"A brief description of the work done in the coin selection module in BDK during Summer of Bitcoin 2022"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/improving_coin_selection_in_BDK/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Improving coin selection in BDK"},{name:"twitter:description",content:"A brief description of the work done in the coin selection module in BDK during Summer of Bitcoin 2022"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/improving_coin_selection_in_BDK/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"coin selection, BDK, development, summer of bitcoin"},{property:"article:tag",content:"coin selection"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"development"},{property:"article:tag",content:"summer of bitcoin"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/improving_coin_selection_in_BDK.html",relativePath:"_blog/improving_coin_selection_in_BDK.md",key:"v-d0375c8e",path:"/blog/improving-coin-selection-in-bdk/",headers:[{level:2,title:"Waste",slug:"waste"},{level:3,title:"How it works?",slug:"how-it-works"},{level:3,title:"What has been done",slug:"what-has-been-done"},{level:3,title:"Work in progress",slug:"work-in-progress"},{level:2,title:"Further Improvements",slug:"further-improvements"},{level:3,title:"Privacy",slug:"privacy"},{level:3,title:"Flexibility",slug:"flexibility"},{level:2,title:"Conclusion",slug:"conclusion"},{level:2,title:"Acknowledgements",slug:"acknowledgements"},{level:2,title:"References",slug:"references"},{level:3,title:"About coin selection considerations",slug:"about-coin-selection-considerations"},{level:3,title:"About Waste metric",slug:"about-waste-metric"},{level:3,title:"About improving privacy in coin selection",slug:"about-improving-privacy-in-coin-selection"},{level:3,title:"About bdk_core",slug:"about-bdk-core"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Security Advisory: Miniscript MINIMALIF Bug",frontmatter:{title:"Security Advisory: Miniscript MINIMALIF Bug",description:"Security advisory on the recent Miniscript MINIMALIF bug. How to check if you are affected and what to do next.",authors:["Alekos Filini"],date:"2022-04-19",tags:["miniscript","security"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-04-19T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Security Advisory: Miniscript MINIMALIF Bug"},{property:"og:description",content:"Security advisory on the recent Miniscript MINIMALIF bug. How to check if you are affected and what to do next."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/miniscript_vulnerability/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Security Advisory: Miniscript MINIMALIF Bug"},{name:"twitter:description",content:"Security advisory on the recent Miniscript MINIMALIF bug. How to check if you are affected and what to do next."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/miniscript_vulnerability/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"miniscript, security"},{property:"article:tag",content:"miniscript"},{property:"article:tag",content:"security"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/miniscript_vulnerability.html",relativePath:"_blog/miniscript_vulnerability.md",key:"v-10852eea",path:"/blog/miniscript-vulnerability/",headers:[{level:2,title:"How to check if you are vulnerable",slug:"how-to-check-if-you-are-vulnerable"},{level:2,title:"Next steps",slug:"next-steps"},{level:3,title:"If you are affected",slug:"if-you-are-affected"},{level:3,title:"Everybody",slug:"everybody"},{level:2,title:"Consequences of the update",slug:"consequences-of-the-update"},{level:2,title:"Footnote: How we analyzed the blockchain",slug:"footnote-how-we-analyzed-the-blockchain"},{level:2,title:"Correction (2022-04-25)",slug:"correction-2022-04-25"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.2.0",frontmatter:{title:"Release v0.2.0",description:"Announcing the v0.2.0 release of BDK",authors:["Alekos Filini"],date:"2020-12-21",tags:["rust","release"],permalink:"/blog/2020/12/release-v0.2.0/",meta:[{property:"article:published_time",content:"2020-12-21T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.2.0"},{property:"og:description",content:"Announcing the v0.2.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2020/12/release-v0.2.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.2.0"},{name:"twitter:description",content:"Announcing the v0.2.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2020/12/release-v0.2.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.2.0.html",relativePath:"_blog/release-0.2.0.md",key:"v-edd5570e",path:"/blog/2020/12/release-v0.2.0/",headers:[{level:2,title:"What's new in v0.2.0",slug:"whats-new-in-v020"},{level:3,title:"A new name",slug:"a-new-name"},{level:3,title:"Branch and Bound coin selection",slug:"branch-and-bound-coin-selection"},{level:3,title:"Key generation",slug:"key-generation"},{level:3,title:"Generic key types",slug:"generic-key-types"},{level:3,title:"Descriptor templates",slug:"descriptor-templates"},{level:3,title:"Easier creation of Blockchain and Database",slug:"easier-creation-of-blockchain-and-database"},{level:3,title:"descriptor!() macro",slug:"descriptor-macro"},{level:3,title:"Support for sortedmulti()",slug:"support-for-sortedmulti"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.3.0",frontmatter:{title:"Release v0.3.0",description:"Announcing the v0.3.0 release of BDK",authors:["Alekos Filini"],date:"2021-01-20",tags:["rust","release"],permalink:"/blog/2021/01/release-v0.3.0/",meta:[{property:"article:published_time",content:"2021-01-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.3.0"},{property:"og:description",content:"Announcing the v0.3.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/release-v0.3.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.3.0"},{name:"twitter:description",content:"Announcing the v0.3.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/release-v0.3.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.3.0.html",relativePath:"_blog/release-0.3.0.md",key:"v-05df4999",path:"/blog/2021/01/release-v0.3.0/",headers:[{level:2,title:"What's new in v0.3.0",slug:"whats-new-in-v030"},{level:3,title:"Less verbosity when using Wallet::new_offline()",slug:"less-verbosity-when-using-walletnew-offline"},{level:3,title:"No more error conversions in DescriptorTemplate",slug:"no-more-error-conversions-in-descriptortemplate"},{level:3,title:"A new repo for the CLI",slug:"a-new-repo-for-the-cli"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.4.0",frontmatter:{title:"Release v0.4.0",description:"Announcing the v0.4.0 release of BDK",authors:["Alekos Filini"],date:"2021-02-17",tags:["rust","release"],permalink:"/blog/2021/02/release-v0.4.0/",meta:[{property:"article:published_time",content:"2021-02-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.4.0"},{property:"og:description",content:"Announcing the v0.4.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/02/release-v0.4.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.4.0"},{name:"twitter:description",content:"Announcing the v0.4.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/02/release-v0.4.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.4.0.html",relativePath:"_blog/release-0.4.0.md",key:"v-faad828e",path:"/blog/2021/02/release-v0.4.0/",headers:[{level:2,title:"What's new in v0.4.0",slug:"whats-new-in-v040"},{level:3,title:"A new API to build transaction",slug:"a-new-api-to-build-transaction"},{level:3,title:"Upgraded dependencies",slug:"upgraded-dependencies"},{level:3,title:"Compact Filters example",slug:"compact-filters-example"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.6.0",frontmatter:{title:"Release v0.6.0",description:"Announcing the v0.6.0 release of BDK",authors:["Alekos Filini"],date:"2021-04-15",tags:["rust","release"],permalink:"/blog/2021/04/release-v0.6.0/",meta:[{property:"article:published_time",content:"2021-04-15T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.6.0"},{property:"og:description",content:"Announcing the v0.6.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/04/release-v0.6.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.6.0"},{name:"twitter:description",content:"Announcing the v0.6.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/04/release-v0.6.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.6.0.html",relativePath:"_blog/release-0.6.0.md",key:"v-7c3d28f9",path:"/blog/2021/04/release-v0.6.0/",headers:[{level:2,title:"What's new in v0.6.0",slug:"whats-new-in-v060"},{level:3,title:"A new way to generate addresses",slug:"a-new-way-to-generate-addresses"},{level:3,title:"Easier multiparty transaction creation",slug:"easier-multiparty-transaction-creation"},{level:3,title:"Renamed types",slug:"renamed-types"},{level:3,title:"New MSRV",slug:"new-msrv"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.5.0",frontmatter:{title:"Release v0.5.0",description:"Announcing the v0.5.0 release of BDK",authors:["Alekos Filini"],date:"2021-03-18",tags:["rust","release"],permalink:"/blog/2021/03/release-v0.5.0/",meta:[{property:"article:published_time",content:"2021-03-18T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.5.0"},{property:"og:description",content:"Announcing the v0.5.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/03/release-v0.5.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.5.0"},{name:"twitter:description",content:"Announcing the v0.5.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/03/release-v0.5.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.5.0.html",relativePath:"_blog/release-0.5.0.md",key:"v-0119984e",path:"/blog/2021/03/release-v0.5.0/",headers:[{level:2,title:"What's new in v0.5.0",slug:"whats-new-in-v050"},{level:3,title:"Dual Licensing",slug:"dual-licensing"},{level:3,title:"Spending foreign UTXOs",slug:"spending-foreign-utxos"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.7.0",frontmatter:{title:"Release v0.7.0",description:"Announcing the v0.7.0 release of BDK",authors:["Alekos Filini"],date:"2021-05-17",tags:["rust","release"],permalink:"/blog/2021/05/release-v0.7.0/",meta:[{property:"article:published_time",content:"2021-05-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.7.0"},{property:"og:description",content:"Announcing the v0.7.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/05/release-v0.7.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.7.0"},{name:"twitter:description",content:"Announcing the v0.7.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/05/release-v0.7.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.7.0.html",relativePath:"_blog/release-0.7.0.md",key:"v-0df1c3ce",path:"/blog/2021/05/release-v0.7.0/",headers:[{level:2,title:"What's new in v0.7.0",slug:"whats-new-in-v070"},{level:3,title:"New Signing API",slug:"new-signing-api"},{level:3,title:"Support Timelocks in the policy Module",slug:"support-timelocks-in-the-policy-module"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.8.0",frontmatter:{title:"Release v0.8.0",description:"Announcing the v0.8.0 release of BDK",authors:["Alekos Filini"],date:"2021-06-14",tags:["rust","release"],permalink:"/blog/2021/06/release-v0.8.0/",meta:[{property:"article:published_time",content:"2021-06-14T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.8.0"},{property:"og:description",content:"Announcing the v0.8.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/06/release-v0.8.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.8.0"},{name:"twitter:description",content:"Announcing the v0.8.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/06/release-v0.8.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.8.0.html",relativePath:"_blog/release-0.8.0.md",key:"v-75d11339",path:"/blog/2021/06/release-v0.8.0/",headers:[{level:2,title:"What's new in v0.8.0",slug:"whats-new-in-v080"},{level:3,title:"Getting the Derivation Index",slug:"getting-the-derivation-index"},{level:3,title:"Explicitly Enable non-ALL Sighashes",slug:"explicitly-enable-non-all-sighashes"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Release v0.9.0",frontmatter:{title:"Release v0.9.0",description:"Announcing the v0.9.0 release of BDK",authors:["Alekos Filini"],date:"2021-07-11",tags:["rust","release"],permalink:"/blog/2021/07/release-v0.9.0/",meta:[{property:"article:published_time",content:"2021-07-11T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.9.0"},{property:"og:description",content:"Announcing the v0.9.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/07/release-v0.9.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.9.0"},{name:"twitter:description",content:"Announcing the v0.9.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/07/release-v0.9.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.9.0.html",relativePath:"_blog/release-0.9.0.md",key:"v-1ac9ef4e",path:"/blog/2021/07/release-v0.9.0/",headers:[{level:2,title:"What's new in v0.9.0",slug:"whats-new-in-v090"},{level:2,title:"Bitcoin Core Blockchain Backend",slug:"bitcoin-core-blockchain-backend"},{level:2,title:"Updated TransactionDetails Struct",slug:"updated-transactiondetails-struct"},{level:2,title:"Verify Downloaded TXs",slug:"verify-downloaded-txs"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"The Road to BDK 1.0",frontmatter:{title:"The Road to BDK 1.0",description:"Outlining the plan for the 1.0 release of BDK",authors:["Alekos Filini"],date:"2022-10-03",tags:["architecture"],draft:!1,meta:[{property:"article:published_time",content:"2022-10-03T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"The Road to BDK 1.0"},{property:"og:description",content:"Outlining the plan for the 1.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/road_to_bdk_1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"The Road to BDK 1.0"},{name:"twitter:description",content:"Outlining the plan for the 1.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/road_to_bdk_1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"architecture"},{property:"article:tag",content:"architecture"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/road_to_bdk_1.html",relativePath:"_blog/road_to_bdk_1.md",key:"v-55969f39",path:"/blog/road-to-bdk-1/",headers:[{level:2,title:"Goals",slug:"goals"},{level:3,title:"Stable API",slug:"stable-api"},{level:3,title:"Upstreaming our code",slug:"upstreaming-our-code"},{level:3,title:"Partially Syncing a Wallet",slug:"partially-syncing-a-wallet"},{level:3,title:"no_std",slug:"no-std"},{level:3,title:"Lower MSRV",slug:"lower-msrv"},{level:2,title:"Architecture",slug:"architecture"},{level:2,title:"Timeline",slug:"timeline"},{level:2,title:"Feature Freezing BDK",slug:"feature-freezing-bdk"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Spending Policy Decoded",frontmatter:{title:"Spending Policy Decoded",description:"Demonstrate how to use a descriptor wallet with different spending policies",authors:["Steve Myers","thunderbiscuit"],date:"2021-02-23",tags:["guide","descriptor"],meta:[{property:"article:published_time",content:"2021-02-23T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Spending Policy Decoded"},{property:"og:description",content:"Demonstrate how to use a descriptor wallet with different spending policies"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/spending_policy_demo/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Spending Policy Decoded"},{name:"twitter:description",content:"Demonstrate how to use a descriptor wallet with different spending policies"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/spending_policy_demo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"guide, descriptor"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"descriptor"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/spending_policy_demo.html",relativePath:"_blog/spending_policy_demo.md",key:"v-8534b9c2",path:"/blog/spending-policy-demo/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Initial Setup",slug:"initial-setup"},{level:3,title:"Step 0: Install a recent version bdk-cli",slug:"step-0-install-a-recent-version-bdk-cli"},{level:3,title:"Step 1: Generate private extended keys",slug:"step-1-generate-private-extended-keys"},{level:3,title:"Step 2: Extract private extended keys",slug:"step-2-extract-private-extended-keys"},{level:3,title:"Step 3: Derive public extended keys",slug:"step-3-derive-public-extended-keys"},{level:3,title:"Step 4: Create wallet descriptors for each participant",slug:"step-4-create-wallet-descriptors-for-each-participant"},{level:2,title:"Policy A. Three signatures",slug:"policy-a-three-signatures"},{level:3,title:"Step 1a: Create a testnet segwit0 receive address",slug:"step-1a-create-a-testnet-segwit0-receive-address"},{level:3,title:"Step 2a: Send testnet bitcoin from a faucet to receive address",slug:"step-2a-send-testnet-bitcoin-from-a-faucet-to-receive-address"},{level:3,title:"Step 3a: Sync participant wallets and confirm balance",slug:"step-3a-sync-participant-wallets-and-confirm-balance"},{level:3,title:"Step 4a: View wallet spending policies",slug:"step-4a-view-wallet-spending-policies"},{level:3,title:"Step 5a: Create spending transaction",slug:"step-5a-create-spending-transaction"},{level:3,title:"Step 6a: Sign and finalize PSBTs",slug:"step-6a-sign-and-finalize-psbts"},{level:3,title:"Step 7a: Broadcast finalized PSBT",slug:"step-7a-broadcast-finalized-psbt"},{level:3,title:"Step 8a: Confirm transaction included in a testnet block",slug:"step-8a-confirm-transaction-included-in-a-testnet-block"},{level:2,title:"Policy B. Two signatures after a relative time lock",slug:"policy-b-two-signatures-after-a-relative-time-lock"},{level:3,title:"Step 1b: Create a new testnet receive address",slug:"step-1b-create-a-new-testnet-receive-address"},{level:3,title:"Step 2b: Fund new address from testnet faucet",slug:"step-2b-fund-new-address-from-testnet-faucet"},{level:3,title:"Step 3b: Sync wallet and confirm wallet balance",slug:"step-3b-sync-wallet-and-confirm-wallet-balance"},{level:3,title:"Step 4b: Create spending transaction",slug:"step-4b-create-spending-transaction"},{level:3,title:"Step 5b: Sign and finalize PSBTs",slug:"step-5b-sign-and-finalize-psbts"},{level:3,title:"Step 6b: Broadcast finalized PSBT",slug:"step-6b-broadcast-finalized-psbt"},{level:3,title:"Step 7b: View confirmed transaction",slug:"step-7b-view-confirmed-transaction"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Using BDK with hardware wallets",frontmatter:{title:"Using BDK with hardware wallets",description:"Tutorial showing how to send funds to a HW and then spend from it using BDK",authors:["Daniela Brozzoni"],date:"2022-10-27",tags:["BDK","Development","Hardware Wallets"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-10-27T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Using BDK with hardware wallets"},{property:"og:description",content:"Tutorial showing how to send funds to a HW and then spend from it using BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/using_bdk_with_hardware_wallets/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Using BDK with hardware wallets"},{name:"twitter:description",content:"Tutorial showing how to send funds to a HW and then spend from it using BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/using_bdk_with_hardware_wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, Development, Hardware Wallets"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"Development"},{property:"article:tag",content:"Hardware Wallets"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/using_bdk_with_hardware_wallets.html",relativePath:"_blog/using_bdk_with_hardware_wallets.md",key:"v-aeb70fce",path:"/blog/using-bdk-with-hardware-wallets/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Prerequisites",slug:"prerequisites"},{level:2,title:"Initial setup",slug:"initial-setup"},{level:2,title:"Finding the hardware wallet",slug:"finding-the-hardware-wallet"},{level:2,title:"Receiving funds",slug:"receiving-funds"},{level:2,title:"Spending funds",slug:"spending-funds"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Why Do We Build Bindings?",frontmatter:{title:"Why Do We Build Bindings?",description:"A post exploring why the Bitcoin Dev Kit Foundation produces language bindings for its libraries",authors:["thunderbiscuit"],date:"2024-05-07",tags:["bindings"],meta:[{property:"article:published_time",content:"2024-05-07T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Why Do We Build Bindings?"},{property:"og:description",content:"A post exploring why the Bitcoin Dev Kit Foundation produces language bindings for its libraries"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/why-bindings/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Why Do We Build Bindings?"},{name:"twitter:description",content:"A post exploring why the Bitcoin Dev Kit Foundation produces language bindings for its libraries"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/why-bindings/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bindings"},{property:"article:tag",content:"bindings"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/why-bindings.html",relativePath:"_blog/why-bindings.md",key:"v-4dc135e3",path:"/blog/why-bindings/",headers:[{level:2,title:"Awesome! Producing Bindings Must Be Easy Right?",slug:"awesome-producing-bindings-must-be-easy-right"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"All",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/all/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/all/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/all.html",relativePath:"adoption/all.md",key:"v-4d760891",path:"/adoption/all/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Custodial",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/custodial/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/custodial/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/custodial.html",relativePath:"adoption/custodial.md",key:"v-30c0037b",path:"/adoption/custodial/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Desktop",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/desktop/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/desktop/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/desktop.html",relativePath:"adoption/desktop.md",key:"v-4bb7844a",path:"/adoption/desktop/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Exchange",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/exchange/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/exchange/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/exchange.html",relativePath:"adoption/exchange.md",key:"v-b936290e",path:"/adoption/exchange/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Hardware",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/hardware/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/hardware/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/hardware.html",relativePath:"adoption/hardware.md",key:"v-7afdbb4e",path:"/adoption/hardware/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Infrastructure",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/infrastructure/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/infrastructure/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/infrastructure.html",relativePath:"adoption/infrastructure.md",key:"v-4e0b610e",path:"/adoption/infrastructure/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Mobile",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/mobile/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/mobile.html",relativePath:"adoption/mobile.md",key:"v-a7c24c4e",path:"/adoption/mobile/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Web",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/web/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/web/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/web.html",relativePath:"adoption/web.md",key:"v-17019aeb",path:"/adoption/web/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Compiler",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Compiler"},{property:"og:description",content:'If you want to play around with more complicated spending policies, you\'ll start to find it harder and harder to manually create the descriptors. This is where the miniscript compiler comes in! The `bdk` library\nincludes a very simple compiler that can produce a descriptor given a spending policy. The syntax used to encode the spending policy is very well described in this pagehttp://bitcoin.sipa.be/miniscript/,\nspecifically in the "Policy to Miniscript compiler". The compiler included in BDK does basically the same job, but produces descriptors for `rust-miniscript` that have some minor differences from\nthe ones made by the C++ implementation used in that website.'},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/compiler/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Compiler"},{name:"twitter:description",content:'If you want to play around with more complicated spending policies, you\'ll start to find it harder and harder to manually create the descriptors. This is where the miniscript compiler comes in! The `bdk` library\nincludes a very simple compiler that can produce a descriptor given a spending policy. The syntax used to encode the spending policy is very well described in this pagehttp://bitcoin.sipa.be/miniscript/,\nspecifically in the "Policy to Miniscript compiler". The compiler included in BDK does basically the same job, but produces descriptors for `rust-miniscript` that have some minor differences from\nthe ones made by the C++ implementation used in that website.'},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/compiler/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/compiler.html",relativePath:"bdk-cli/compiler.md",key:"v-7a315e41",path:"/bdk-cli/compiler/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Installation",slug:"installation"},{level:2,title:"Usage",slug:"usage"},{level:2,title:"Example",slug:"example"},{level:2,title:"Troubleshooting",slug:"troubleshooting"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Concept",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Concept"},{property:"og:description",content:"Now, in order to better grasp some of the design choices made by BDK, it's important to understand the main concept driving the development of this project, and the goal that it's trying to\nachieve."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/concept/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Concept"},{name:"twitter:description",content:"Now, in order to better grasp some of the design choices made by BDK, it's important to understand the main concept driving the development of this project, and the goal that it's trying to\nachieve."},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/concept/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/concept.html",relativePath:"bdk-cli/concept.md",key:"v-f611a14e",path:"/bdk-cli/concept/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Installation",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Installation"},{property:"og:description",content:"The only requirement to run the `bdk-cli` tool is a Linux/macOS system with a fairly recent Rust\ntoolchain installed. Since Linux distros tend to lag behind with updates, the quickest way to\ninstall the Rust compiler and Cargo is rustup.rshttps://rustup.rs/. You can head there and\nfollow their instructions, after which you can test if everything went fine by running"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/installation/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Installation"},{name:"twitter:description",content:"The only requirement to run the `bdk-cli` tool is a Linux/macOS system with a fairly recent Rust\ntoolchain installed. Since Linux distros tend to lag behind with updates, the quickest way to\ninstall the Rust compiler and Cargo is rustup.rshttps://rustup.rs/. You can head there and\nfollow their instructions, after which you can test if everything went fine by running"},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/installation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/installation.html",relativePath:"bdk-cli/installation.md",key:"v-3acb6e6a",path:"/bdk-cli/installation/",headers:[{level:2,title:"Requirements",slug:"requirements"},{level:2,title:"Installing the bdk-cli tool",slug:"installing-the-bdk-cli-tool"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Interface",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Interface"},{property:"og:description",content:"Remember the `bdk-cli --help` command you ran before? Let's analyze its output here to figure out the interface:"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/interface/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Interface"},{name:"twitter:description",content:"Remember the `bdk-cli --help` command you ran before? Let's analyze its output here to figure out the interface:"},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/interface/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/interface.html",relativePath:"bdk-cli/interface.md",key:"v-496cb7f9",path:"/bdk-cli/interface/",headers:[{level:2,title:"Flags",slug:"flags"},{level:3,title:"Verbosity",slug:"verbosity"},{level:2,title:"Options",slug:"options"},{level:2,title:"Subcommands",slug:"subcommands"},{level:2,title:"key",slug:"key"},{level:3,title:"generate",slug:"generate"},{level:3,title:"restore",slug:"restore"},{level:3,title:"derive",slug:"derive"},{level:2,title:"wallet",slug:"wallet"},{level:3,title:"Options",slug:"options-2"},{level:2,title:"Subcommands",slug:"subcommands-2"},{level:3,title:"broadcast",slug:"broadcast"},{level:3,title:"bump_fee",slug:"bump-fee"},{level:3,title:"combine_psbt",slug:"combine-psbt"},{level:3,title:"create_tx",slug:"create-tx"},{level:3,title:"extract_psbt",slug:"extract-psbt"},{level:3,title:"finalize_psbt",slug:"finalize-psbt"},{level:3,title:"get_balance",slug:"get-balance"},{level:3,title:"get_new_address",slug:"get-new-address"},{level:3,title:"list_transactions",slug:"list-transactions"},{level:3,title:"list_unspent",slug:"list-unspent"},{level:3,title:"policies",slug:"policies"},{level:3,title:"public_descriptor",slug:"public-descriptor"},{level:3,title:"help",slug:"help"},{level:3,title:"sign",slug:"sign"},{level:3,title:"sync",slug:"sync"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Introduction",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Introduction"},{property:"og:description",content:"This can also be used as an example application to create your own command line bitcoin wallet tool using bdk."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/introduction/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Introduction"},{name:"twitter:description",content:"This can also be used as an example application to create your own command line bitcoin wallet tool using bdk."},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/introduction.html",relativePath:"bdk-cli/introduction.md",key:"v-0b3b65ea",path:"/bdk-cli/introduction/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Playground",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Playground"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/playground/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Playground"},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/playground/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/playground.html",relativePath:"bdk-cli/playground.md",key:"v-a76bccee",path:"/bdk-cli/playground/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Regtest",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Regtest"},{property:"og:description",content:"Running the `bdk-cli` tool in regtest requires having a local Electrum server set-up. There are two main implementations, `electrs`https://github.com/romanz/electrs in Rust and `ElectrumX`https://github.com/spesmilo/electrumx in Python. Since the Rust toolchain is already required to\nuse BDK, this page will focus mostly on the former."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/regtest/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Regtest"},{name:"twitter:description",content:"Running the `bdk-cli` tool in regtest requires having a local Electrum server set-up. There are two main implementations, `electrs`https://github.com/romanz/electrs in Rust and `ElectrumX`https://github.com/spesmilo/electrumx in Python. Since the Rust toolchain is already required to\nuse BDK, this page will focus mostly on the former."},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/regtest/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/regtest.html",relativePath:"bdk-cli/regtest.md",key:"v-05d01c19",path:"/bdk-cli/regtest/",headers:[{level:2,title:"Troubleshooting",slug:"troubleshooting"},{level:2,title:"Bonus: Docker",slug:"bonus-docker"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{frontmatter:{cases:!0,sidebar:!1,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",actionText:"Add your project",actionLink:"https://github.com/orgs/bitcoindevkit/discussions/64",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/case-studies/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/case-studies/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/case-studies.html",relativePath:"case-studies.md",key:"v-11bf335e",path:"/case-studies/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Descriptors",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Descriptors"},{property:"og:description",content:'Descriptors are a compact and semi-standard way to easily encode, or "describe", how scripts and subsequently, addresses of a wallet should be generated. They can be especially helpful when working with multisigs or even\nmore complex scripts, where the structure of the script itself is not trivial. They are a big step forward in making wallets more portable across different tools and apps, because for the first time they create a common\nlanguage to describe a full bitcoin script that developers can use and integrate in their software.'},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/descriptors/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Descriptors"},{name:"twitter:description",content:'Descriptors are a compact and semi-standard way to easily encode, or "describe", how scripts and subsequently, addresses of a wallet should be generated. They can be especially helpful when working with multisigs or even\nmore complex scripts, where the structure of the script itself is not trivial. They are a big step forward in making wallets more portable across different tools and apps, because for the first time they create a common\nlanguage to describe a full bitcoin script that developers can use and integrate in their software.'},{name:"twitter:url",content:"https://bitcoindevkit.org/descriptors/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/descriptors/",relativePath:"descriptors/README.md",key:"v-a9236c10",path:"/descriptors/",headers:[{level:3,title:"Compatibility Matrix",slug:"compatibility-matrix"},{level:3,title:"Examples",slug:"examples"},{level:3,title:"Implementation Details",slug:"implementation-details"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Examples",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Examples"},{property:"og:description",content:"Click the links below and learn from community-built example projects."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/examples/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Examples"},{name:"twitter:description",content:"Click the links below and learn from community-built example projects."},{name:"twitter:url",content:"https://bitcoindevkit.org/examples/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/examples/",relativePath:"examples/README.md",key:"v-29f9f21c",path:"/examples/",headers:[{level:2,title:"BDK-CLI",slug:"bdk-cli"},{level:2,title:"DevkitWallet",slug:"devkitwallet"},{level:2,title:"Padawan Wallet",slug:"padawan-wallet"},{level:2,title:"BDKSwiftExampleWallet",slug:"bdkswiftexamplewallet"},{level:2,title:"Tatooine",slug:"tatooine"},{level:2,title:"SEBA Bank Proof of reserves",slug:"seba-bank-proof-of-reserves"},{level:2,title:"Stackmate",slug:"stackmate"},{level:2,title:"Spotbit",slug:"spotbit"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Bitcoin Dev Kit Foundation",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/about/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/about/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/about.html",relativePath:"foundation/about.md",key:"v-3750297a",path:"/foundation/about/",headers:[{level:2,title:"Board",slug:"board"},{level:2,title:"Operations",slug:"operations"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Become a Member",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information on how to become a member of the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information on how to become a member of the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/become-a-member/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information on how to become a member of the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/become-a-member/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/become-a-member.html",relativePath:"foundation/become-a-member.md",key:"v-71ef7c85",path:"/foundation/become-a-member/",headers:[{level:2,title:"Membership Fee Information",slug:"membership-fee-information"},{level:3,title:"Silver Tier Sliding Scale",slug:"silver-tier-sliding-scale"},{level:3,title:"Ready to apply?",slug:"ready-to-apply"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Current Grantees (Full-Time)",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/grantees/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/grantees/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/grantees.html",relativePath:"foundation/grantees.md",key:"v-105750ce",path:"/foundation/grantees/",headers:[{level:2,title:"thunderbiscuit",slug:"thunderbiscuit"},{level:2,title:"Matthew Ramsden",slug:"matthew-ramsden"},{level:2,title:"ValuedMammal",slug:"valuedmammal"},{level:2,title:"Wei Chen",slug:"wei-chen"},{level:2,title:"Evan Lin",slug:"evan-lin"},{level:2,title:"Nymius",slug:"nymius"},{level:2,title:"Manuel Gatti",slug:"manuel-gatti"},{level:2,title:"Leonardo Souza",slug:"leonardo-souza"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Bitcoin Dev Kit Foundation",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/",relativePath:"foundation/index.md",key:"v-c152529c",path:"/foundation/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Grants Program",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/grants/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/grants/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/grants.html",relativePath:"foundation/grants.md",key:"v-08589c4e",path:"/foundation/grants/",headers:[{level:2,title:"Grant Requirements",slug:"grant-requirements"},{level:2,title:"Full-time grants",slug:"full-time-grants"},{level:3,title:"Rust",slug:"rust"},{level:3,title:"Mobile / language bindings",slug:"mobile-language-bindings"},{level:2,title:"Project grants",slug:"project-grants"},{level:2,title:"Applying",slug:"applying"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Members",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/members/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/members/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/members.html",relativePath:"foundation/members.md",key:"v-4a4b61eb",path:"/foundation/members/",headers:[{level:2,title:"Platinum",slug:"platinum"},{level:2,title:"Gold",slug:"gold"},{level:2,title:"Silver",slug:"silver"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Supporters",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/supporters/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/supporters/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/supporters.html",relativePath:"foundation/supporters.md",key:"v-50aa6d4e",path:"/foundation/supporters/",codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{title:"Bitcoin Dev Kit",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin Dev Kit"},{property:"og:description",content:"The Bitcoin Dev Kit BDKhttps://github.com/bitcoindevkit project originally called Magical Bitcoin 🧙 aims to build a collection of tools and libraries that are designed to be a solid foundation for cross platform Bitcoin wallets, along with a fully working reference implementation wallets for various platforms.\nAll BDK components are designed to be lightweight and modular so that they can be adapted for virtually any use-case: from single-sig mobile wallets to multi-billion-dollar cold storage vaults."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/getting-started/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin Dev Kit"},{name:"twitter:description",content:"The Bitcoin Dev Kit BDKhttps://github.com/bitcoindevkit project originally called Magical Bitcoin 🧙 aims to build a collection of tools and libraries that are designed to be a solid foundation for cross platform Bitcoin wallets, along with a fully working reference implementation wallets for various platforms.\nAll BDK components are designed to be lightweight and modular so that they can be adapted for virtually any use-case: from single-sig mobile wallets to multi-billion-dollar cold storage vaults."},{name:"twitter:url",content:"https://bitcoindevkit.org/getting-started/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/getting-started.html",relativePath:"getting-started.md",key:"v-4bcdac39",path:"/getting-started/",headers:[{level:2,title:"Initial Configuration",slug:"initial-configuration"},{level:2,title:"Internal Features",slug:"internal-features"},{level:2,title:"Playground",slug:"playground"},{level:2,title:"Descriptors",slug:"descriptors"}],codeSwitcherOptions:{},lastUpdated:"11/21/2024, 4:44:27 PM",lastUpdatedTimestamp:1732207467e3},{frontmatter:{layout:"IndexPost",title:"Blog",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/",key:"v-424df898",path:"/blog/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Tags",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/",key:"v-619df59e",path:"/blog/tags/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Authors",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/",key:"v-b0968728",path:"/blog/author/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"BDK ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BDK/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BDK/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BDK/",key:"v-5f2600b8",path:"/blog/tags/BDK/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"project ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/project/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/project/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/project/",key:"v-398e8fd4",path:"/blog/tags/project/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"grants ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/grants/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/grants/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/grants/",key:"v-9d39d64c",path:"/blog/tags/grants/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"tutorial ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/tutorial/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/tutorial/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/tutorial/",key:"v-da8c869a",path:"/blog/tags/tutorial/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bdk-cli ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bdk-cli/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bdk-cli/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bdk-cli/",key:"v-c711ccde",path:"/blog/tags/bdk-cli/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"multi-sig ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/multi-sig/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/multi-sig/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/multi-sig/",key:"v-655ee4a0",path:"/blog/tags/multi-sig/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Bitcoin Core ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Bitcoin Core/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Bitcoin Core/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Bitcoin%20Core/",key:"v-62bbf2ad",path:"/blog/tags/Bitcoin Core/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"RPC ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/RPC/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/RPC/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/RPC/",key:"v-5f171cb0",path:"/blog/tags/RPC/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Wallet ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Wallet/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Wallet/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Wallet/",key:"v-4696dfd8",path:"/blog/tags/Wallet/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"architecture ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/architecture/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/architecture/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/architecture/",key:"v-c4494744",path:"/blog/tags/architecture/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"BDK-RN ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BDK-RN/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BDK-RN/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BDK-RN/",key:"v-876cfade",path:"/blog/tags/BDK-RN/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Development ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Development/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Development/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Development/",key:"v-3acc51dc",path:"/blog/tags/Development/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Architecture ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Architecture/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Architecture/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Architecture/",key:"v-650ae784",path:"/blog/tags/Architecture/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"basics ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/basics/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/basics/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/basics/",key:"v-e646a928",path:"/blog/tags/basics/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"novice ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/novice/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/novice/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/novice/",key:"v-1fb58ffb",path:"/blog/tags/novice/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bindings ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bindings/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bindings/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bindings/",key:"v-1296a8fa",path:"/blog/tags/bindings/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"tor ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/tor/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/tor/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/tor/",key:"v-5ef73f54",path:"/blog/tags/tor/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"wallet ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/wallet/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/wallet/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/wallet/",key:"v-39437010",path:"/blog/tags/wallet/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"blockchain ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/blockchain/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/blockchain/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/blockchain/",key:"v-7c8563fd",path:"/blog/tags/blockchain/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"compact_filters ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/compact_filters/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/compact_filters/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/compact_filters/",key:"v-baacba64",path:"/blog/tags/compact_filters/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"BIP157 ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BIP157/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BIP157/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BIP157/",key:"v-75ccd5f2",path:"/blog/tags/BIP157/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Neutrino ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Neutrino/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Neutrino/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Neutrino/",key:"v-4fed1c23",path:"/blog/tags/Neutrino/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"guide ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/guide/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/guide/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/guide/",key:"v-a9e0285e",path:"/blog/tags/guide/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"descriptor ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/descriptor/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/descriptor/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/descriptor/",key:"v-733ed37c",path:"/blog/tags/descriptor/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"paper wallets ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/paper wallets/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/paper wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/paper%20wallets/",key:"v-1144be8a",path:"/blog/tags/paper wallets/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bitcoin ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bitcoin/",key:"v-915f8322",path:"/blog/tags/bitcoin/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"React Native ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/React Native/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/React Native/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/React%20Native/",key:"v-bf53d4d4",path:"/blog/tags/React Native/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Flutter ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Flutter/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Flutter/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Flutter/",key:"v-07eeb15e",path:"/blog/tags/Flutter/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"iOS ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/iOS/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/iOS/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/iOS/",key:"v-5f023740",path:"/blog/tags/iOS/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Android ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Android/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Android/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Android/",key:"v-414e735e",path:"/blog/tags/Android/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"mobile ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/mobile/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/mobile/",key:"v-2c94bf22",path:"/blog/tags/mobile/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bdk-rn ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bdk-rn/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bdk-rn/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bdk-rn/",key:"v-dd212a9e",path:"/blog/tags/bdk-rn/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bdk ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bdk/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bdk/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bdk/",key:"v-5f07f0f8",path:"/blog/tags/bdk/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"fee ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/fee/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/fee/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/fee/",key:"v-5f0447f2",path:"/blog/tags/fee/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"machine learning ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/machine learning/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/machine learning/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/machine%20learning/",key:"v-e2317b12",path:"/blog/tags/machine learning/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"taproot ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/taproot/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/taproot/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/taproot/",key:"v-57f3a168",path:"/blog/tags/taproot/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"miniscript ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/miniscript/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/miniscript/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/miniscript/",key:"v-ef7c3fa2",path:"/blog/tags/miniscript/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Hardware Wallets ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Hardware Wallets/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Hardware Wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Hardware%20Wallets/",key:"v-640144b2",path:"/blog/tags/Hardware Wallets/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bitcoin-cli ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin-cli/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin-cli/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bitcoin-cli/",key:"v-01a03a08",path:"/blog/tags/bitcoin-cli/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"getting started ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/getting started/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/getting started/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/getting%20started/",key:"v-79c3de4b",path:"/blog/tags/getting started/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"rust ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/rust/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/rust/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/rust/",key:"v-3fee41ed",path:"/blog/tags/rust/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"coin selection ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/coin selection/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/coin selection/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/coin%20selection/",key:"v-74edfe92",path:"/blog/tags/coin selection/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"development ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/development/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/development/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/development/",key:"v-4e62fa1c",path:"/blog/tags/development/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"summer of bitcoin ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/summer of bitcoin/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/summer of bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/summer%20of%20bitcoin/",key:"v-0159a747",path:"/blog/tags/summer of bitcoin/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"security ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/security/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/security/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/security/",key:"v-0755ed11",path:"/blog/tags/security/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"release ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/release/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/release/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/release/",key:"v-543950a6",path:"/blog/tags/release/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Steve Myers ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Steve Myers/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Steve Myers/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Steve%20Myers/",key:"v-a354115e",path:"/blog/author/Steve Myers/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Daniela Brozzoni ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Daniela Brozzoni/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Daniela Brozzoni/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Daniela%20Brozzoni/",key:"v-22d0e252",path:"/blog/author/Daniela Brozzoni/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"thunderbiscuit ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/thunderbiscuit/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/thunderbiscuit/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/thunderbiscuit/",key:"v-5d54001e",path:"/blog/author/thunderbiscuit/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"waterst0ne ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/waterst0ne/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/waterst0ne/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/waterst0ne/",key:"v-3e6950f4",path:"/blog/author/waterst0ne/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Rajarshi Maitra ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Rajarshi Maitra/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Rajarshi Maitra/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Rajarshi%20Maitra/",key:"v-82e16b5c",path:"/blog/author/Rajarshi Maitra/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Lloyd Fournier ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Lloyd Fournier/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Lloyd Fournier/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Lloyd%20Fournier/",key:"v-600b5b28",path:"/blog/author/Lloyd Fournier/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Bitcoin Zavior ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Bitcoin Zavior/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Bitcoin Zavior/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Bitcoin%20Zavior/",key:"v-37829241",path:"/blog/author/Bitcoin Zavior/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"rorp ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/rorp/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/rorp/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/rorp/",key:"v-d2b26530",path:"/blog/author/rorp/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Riccardo Casatta ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Riccardo Casatta/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Riccardo Casatta/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Riccardo%20Casatta/",key:"v-624fd61e",path:"/blog/author/Riccardo Casatta/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Gabriele Domenichini ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Gabriele Domenichini/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Gabriele Domenichini/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Gabriele%20Domenichini/",key:"v-6b564fb4",path:"/blog/author/Gabriele Domenichini/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Alekos Filini ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Alekos%20Filini/",key:"v-ad00c09c",path:"/blog/author/Alekos Filini/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Wszdexdrf ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Wszdexdrf/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Wszdexdrf/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Wszdexdrf/",key:"v-4eeab648",path:"/blog/author/Wszdexdrf/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Sandipan Dey ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Sandipan Dey/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Sandipan Dey/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Sandipan%20Dey/",key:"v-91c10894",path:"/blog/author/Sandipan Dey/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"César Alvarez Vallero ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/César Alvarez Vallero/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/César Alvarez Vallero/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/C%C3%A9sar%20Alvarez%20Vallero/",key:"v-a0d840b0",path:"/blog/author/César Alvarez Vallero/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 2",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/page/2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/page/2/",key:"v-c3507bb6",path:"/blog/page/2/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 3",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/page/3/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/page/3/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/page/3/",key:"v-c3507b78",path:"/blog/page/3/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 4",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/page/4/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/page/4/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/page/4/",key:"v-c3507b3a",path:"/blog/page/4/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"BDK - Page 2",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BDK/page/2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BDK/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BDK/page/2/",key:"v-73be14ce",path:"/blog/tags/BDK/page/2/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Alekos Filini - Page 2",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/page/2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Alekos%20Filini/page/2/",key:"v-5f2ac9cb",path:"/blog/author/Alekos Filini/page/2/",codeSwitcherOptions:{}}],themeConfig:{domain:"https://bitcoindevkit.org",logo:"/img/logo.svg",displayAllHeaders:!1,repo:"bitcoindevkit/bitcoindevkit.org",docsDir:"docs",editLinks:!0,sidebarDepth:0,nav:[{text:"Docs",link:"/getting-started/"},{text:"Adoption",link:"/adoption/all.md"},{text:"Foundation",link:"/foundation/"},{text:"Blog",link:"/blog/"}],sidebar:{"/adoption/":[{title:"Built With BDK",collapsable:!1,children:[["/adoption/all.md","All"],["/adoption/mobile.md","Mobile"],["/adoption/desktop.md","Desktop"],["/adoption/hardware.md","Hardware"],["/adoption/web.md","Web"],["/adoption/custodial.md","Custodial"],["/adoption/exchange.md","Exchange"],["/adoption/infrastructure.md","Infrastructure"]]}],"/_blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/foundation/":[{title:"Foundation",collapsable:!1,children:[["/foundation/about.md","About Us"],["/foundation/supporters.md","Supporters"],["/foundation/grantees.md","Grantees"],["/foundation/grants.md","Grants"],["/foundation/members.md","Members"]]}],"/":[{title:"Documentation",collapsable:!1,children:[["/getting-started","Getting Started"],{title:"BDK-CLI",collapsable:!0,children:["/bdk-cli/introduction","/bdk-cli/installation","/bdk-cli/concept","/bdk-cli/interface","/bdk-cli/regtest","/bdk-cli/compiler","/bdk-cli/playground"]},"/descriptors/","/examples/"]},{title:"API Reference",collapsable:!1,children:[["https://docs.rs/bdk_wallet/","Rust Stable Docs"],["https://bitcoindevkit.org/docs-rs/bdk/nightly/latest/bdk_wallet/","Rust Nightly Docs"],["https://bitcoindevkit.org/android/","Android Docs"],["https://bitcoindevkit.org/jvm/","Kotlin/JVM Docs"],["https://bitcoindevkit.org/java/","Java Docs"]]}]},footer:{links:[{title:"Docs",children:[{text:"Getting Started",link:"/getting-started/"},{text:"BDK-CLI",link:"/bdk-cli/installation/"},{text:"Descriptors",link:"/descriptors/"}]},{title:"Community",children:[{text:"GitHub",link:"https://github.com/bitcoindevkit",rel:"noopener noreferrer"},{text:"Nostr",link:"nostr:npub13dk3dke4zm9vdkucm7f6vv7vhqgkevgg3gju9kr2wzumz7nrykdq0dgnvc",rel:"noopener noreferrer"},{text:"Twitter",link:"https://twitter.com/intent/follow?screen_name=bitcoindevkit",rel:"noopener noreferrer"},{text:"Chat on Discord",link:"https://discord.gg/dstn4dQ",rel:"noopener noreferrer"}]},{title:"More",children:[{text:"Blog",link:"/blog/"},{text:"Supporters",link:"/foundation/supporters/"},{text:"BDK Foundation",link:"/foundation/"}]}],copyright:"Copyright © 2024 BDK Developers"}}},{COLOR_MODES:$c,STORE_ATTR:jc,setColorMode:Mc}=n(111),Rc=t=>"Enter"===t.code||13===(t.keyCode||t.which),Ic=t=>{const e=t.target.matches("#algolia-search-input")&&Rc(t);(t.target.matches(".ds-dropdown-menu *")||e)&&document.getElementById("algolia-search-input").blur(),t.target.matches(".ytEmbed")&&(t.preventDefault(),(t=>{const e=t.querySelector("iframe[data-src]");if(e){const t=e.getAttribute("data-src");e.setAttribute("src",t)}})(t.target))};if("undefined"==typeof process||"server"!==process.env.VUE_ENV){const t=window.matchMedia("(prefers-color-scheme: dark)").matches?$c[1]:$c[0],e=window.localStorage.getItem(jc);Mc($c.includes(e)?e:t)}n(242);Vn.component("Badge",()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,397))),Vn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,387))),Vn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,388)));n(243);var Uc={props:{color:{required:!1,default:"rgb(66, 185, 131)"}}},Nc=(n(244),Object(Sc.a)(Uc,(function(){return(0,this._self._c)("div",{staticClass:"spinner",style:{background:this.color}})}),[],!1,null,"1bbcb91a",null).exports);const Lc={name:"Mermaid",props:{id:{type:String,required:!0},graph:{type:String,required:!0}},data:()=>({svg:void 0}),render(t){return void 0===this.svg?t("Loading"):t("div",{domProps:{innerHTML:this.svg,style:"width: 100%"}})},mounted(){n.e(99).then(n.t.bind(null,383,7)).then(t=>{t.initialize({startOnLoad:!0});let e=document.createElement("div");document.body.appendChild(e),t.render(this.id,this.graph,t=>{this.svg=t,document.body.removeChild(e)},e)})},components:{Loading:Nc}};var Wc=n(94),zc=n.n(Wc);n(245);Vn.component("CodeSwitcher",()=>n.e(44).then(n.bind(null,396)));var qc={tags:{BDK:{key:"BDK",scope:"tags",path:"/blog/tags/BDK/",pageKeys:["v-5e744cf7","v-2c450c3f","v-609f26f9","v-bac76d8e","v-62ca00fb","v-7c0c45f9","v-3875825f","v-07ff1843","v-9145467a","v-2cf72b39","v-11d64359","v-d0375c8e","v-aeb70fce"]},project:{key:"project",scope:"tags",path:"/blog/tags/project/",pageKeys:["v-5e744cf7","v-2c450c3f","v-609f26f9","v-62ca00fb"]},grants:{key:"grants",scope:"tags",path:"/blog/tags/grants/",pageKeys:["v-bac76d8e"]},tutorial:{key:"tutorial",scope:"tags",path:"/blog/tags/tutorial/",pageKeys:["v-8bd632d6","v-7c0c45f9","v-353b78e1","v-07ff1843","v-56536559","v-f58ec8f2","v-ab5ba3ce"]},"bdk-cli":{key:"bdk-cli",scope:"tags",path:"/blog/tags/bdk-cli/",pageKeys:["v-8bd632d6","v-0f4d5d15","v-07ff1843","v-ab5ba3ce"]},"multi-sig":{key:"multi-sig",scope:"tags",path:"/blog/tags/multi-sig/",pageKeys:["v-8bd632d6"]},"Bitcoin Core":{key:"Bitcoin Core",scope:"tags",path:"/blog/tags/Bitcoin Core/",pageKeys:["v-7c0c45f9"]},RPC:{key:"RPC",scope:"tags",path:"/blog/tags/RPC/",pageKeys:["v-7c0c45f9"]},Wallet:{key:"Wallet",scope:"tags",path:"/blog/tags/Wallet/",pageKeys:["v-7c0c45f9"]},architecture:{key:"architecture",scope:"tags",path:"/blog/tags/architecture/",pageKeys:["v-2cebe183","v-55969f39"]},"BDK-RN":{key:"BDK-RN",scope:"tags",path:"/blog/tags/BDK-RN/",pageKeys:["v-3eaa044d"]},Development:{key:"Development",scope:"tags",path:"/blog/tags/Development/",pageKeys:["v-3eaa044d","v-11d64359","v-aeb70fce"]},Architecture:{key:"Architecture",scope:"tags",path:"/blog/tags/Architecture/",pageKeys:["v-3eaa044d"]},basics:{key:"basics",scope:"tags",path:"/blog/tags/basics/",pageKeys:["v-0f4d5d15"]},novice:{key:"novice",scope:"tags",path:"/blog/tags/novice/",pageKeys:["v-0f4d5d15"]},bindings:{key:"bindings",scope:"tags",path:"/blog/tags/bindings/",pageKeys:["v-3875825f","v-4dc135e3"]},tor:{key:"tor",scope:"tags",path:"/blog/tags/tor/",pageKeys:["v-353b78e1"]},wallet:{key:"wallet",scope:"tags",path:"/blog/tags/wallet/",pageKeys:["v-353b78e1","v-56536559","v-f58ec8f2"]},blockchain:{key:"blockchain",scope:"tags",path:"/blog/tags/blockchain/",pageKeys:["v-353b78e1"]},compact_filters:{key:"compact_filters",scope:"tags",path:"/blog/tags/compact_filters/",pageKeys:["v-07ff1843"]},BIP157:{key:"BIP157",scope:"tags",path:"/blog/tags/BIP157/",pageKeys:["v-07ff1843"]},Neutrino:{key:"Neutrino",scope:"tags",path:"/blog/tags/Neutrino/",pageKeys:["v-07ff1843"]},guide:{key:"guide",scope:"tags",path:"/blog/tags/guide/",pageKeys:["v-9504490e","v-56536559","v-f58ec8f2","v-c6756cce","v-8534b9c2"]},descriptor:{key:"descriptor",scope:"tags",path:"/blog/tags/descriptor/",pageKeys:["v-9504490e","v-c6756cce","v-ab5ba3ce","v-8534b9c2"]},"paper wallets":{key:"paper wallets",scope:"tags",path:"/blog/tags/paper wallets/",pageKeys:["v-9504490e"]},bitcoin:{key:"bitcoin",scope:"tags",path:"/blog/tags/bitcoin/",pageKeys:["v-56536559","v-f58ec8f2"]},"React Native":{key:"React Native",scope:"tags",path:"/blog/tags/React Native/",pageKeys:["v-56536559","v-f58ec8f2"]},Flutter:{key:"Flutter",scope:"tags",path:"/blog/tags/Flutter/",pageKeys:["v-56536559"]},iOS:{key:"iOS",scope:"tags",path:"/blog/tags/iOS/",pageKeys:["v-56536559","v-f58ec8f2"]},Android:{key:"Android",scope:"tags",path:"/blog/tags/Android/",pageKeys:["v-56536559","v-f58ec8f2"]},mobile:{key:"mobile",scope:"tags",path:"/blog/tags/mobile/",pageKeys:["v-56536559","v-f58ec8f2"]},"bdk-rn":{key:"bdk-rn",scope:"tags",path:"/blog/tags/bdk-rn/",pageKeys:["v-56536559","v-f58ec8f2"]},bdk:{key:"bdk",scope:"tags",path:"/blog/tags/bdk/",pageKeys:["v-56536559","v-f58ec8f2","v-ab5ba3ce"]},fee:{key:"fee",scope:"tags",path:"/blog/tags/fee/",pageKeys:["v-015729b9","v-2c605799","v-57698579"]},"machine learning":{key:"machine learning",scope:"tags",path:"/blog/tags/machine learning/",pageKeys:["v-015729b9","v-2c605799","v-57698579"]},taproot:{key:"taproot",scope:"tags",path:"/blog/tags/taproot/",pageKeys:["v-9145467a","v-2cf72b39"]},miniscript:{key:"miniscript",scope:"tags",path:"/blog/tags/miniscript/",pageKeys:["v-9145467a","v-2cf72b39","v-ab5ba3ce","v-10852eea"]},"Hardware Wallets":{key:"Hardware Wallets",scope:"tags",path:"/blog/tags/Hardware Wallets/",pageKeys:["v-11d64359","v-aeb70fce"]},"bitcoin-cli":{key:"bitcoin-cli",scope:"tags",path:"/blog/tags/bitcoin-cli/",pageKeys:["v-ab5ba3ce"]},"getting started":{key:"getting started",scope:"tags",path:"/blog/tags/getting started/",pageKeys:["v-5d749fce"]},rust:{key:"rust",scope:"tags",path:"/blog/tags/rust/",pageKeys:["v-5d749fce","v-edd5570e","v-05df4999","v-faad828e","v-7c3d28f9","v-0119984e","v-0df1c3ce","v-75d11339","v-1ac9ef4e"]},"coin selection":{key:"coin selection",scope:"tags",path:"/blog/tags/coin selection/",pageKeys:["v-d0375c8e"]},development:{key:"development",scope:"tags",path:"/blog/tags/development/",pageKeys:["v-d0375c8e"]},"summer of bitcoin":{key:"summer of bitcoin",scope:"tags",path:"/blog/tags/summer of bitcoin/",pageKeys:["v-d0375c8e"]},security:{key:"security",scope:"tags",path:"/blog/tags/security/",pageKeys:["v-10852eea"]},release:{key:"release",scope:"tags",path:"/blog/tags/release/",pageKeys:["v-edd5570e","v-05df4999","v-faad828e","v-7c3d28f9","v-0119984e","v-0df1c3ce","v-75d11339","v-1ac9ef4e"]}},author:{"Steve Myers":{key:"Steve Myers",scope:"author",path:"/blog/author/Steve Myers/",pageKeys:["v-5e744cf7","v-2c450c3f","v-bac76d8e","v-9504490e","v-8534b9c2"]},"Daniela Brozzoni":{key:"Daniela Brozzoni",scope:"author",path:"/blog/author/Daniela Brozzoni/",pageKeys:["v-2c450c3f","v-aeb70fce"]},thunderbiscuit:{key:"thunderbiscuit",scope:"author",path:"/blog/author/thunderbiscuit/",pageKeys:["v-609f26f9","v-62ca00fb","v-3875825f","v-8534b9c2","v-4dc135e3"]},waterst0ne:{key:"waterst0ne",scope:"author",path:"/blog/author/waterst0ne/",pageKeys:["v-8bd632d6","v-0f4d5d15"]},"Rajarshi Maitra":{key:"Rajarshi Maitra",scope:"author",path:"/blog/author/Rajarshi Maitra/",pageKeys:["v-7c0c45f9","v-07ff1843","v-ab5ba3ce"]},"Lloyd Fournier":{key:"Lloyd Fournier",scope:"author",path:"/blog/author/Lloyd Fournier/",pageKeys:["v-2cebe183"]},"Bitcoin Zavior":{key:"Bitcoin Zavior",scope:"author",path:"/blog/author/Bitcoin Zavior/",pageKeys:["v-3eaa044d","v-56536559","v-f58ec8f2"]},rorp:{key:"rorp",scope:"author",path:"/blog/author/rorp/",pageKeys:["v-353b78e1"]},"Riccardo Casatta":{key:"Riccardo Casatta",scope:"author",path:"/blog/author/Riccardo Casatta/",pageKeys:["v-9504490e","v-015729b9","v-2c605799","v-57698579"]},"Gabriele Domenichini":{key:"Gabriele Domenichini",scope:"author",path:"/blog/author/Gabriele Domenichini/",pageKeys:["v-c6756cce"]},"Alekos Filini":{key:"Alekos Filini",scope:"author",path:"/blog/author/Alekos Filini/",pageKeys:["v-9145467a","v-2cf72b39","v-5d749fce","v-10852eea","v-edd5570e","v-05df4999","v-faad828e","v-7c3d28f9","v-0119984e","v-0df1c3ce","v-75d11339","v-1ac9ef4e","v-55969f39"]},Wszdexdrf:{key:"Wszdexdrf",scope:"author",path:"/blog/author/Wszdexdrf/",pageKeys:["v-11d64359"]},"Sandipan Dey":{key:"Sandipan Dey",scope:"author",path:"/blog/author/Sandipan Dey/",pageKeys:["v-ab5ba3ce"]},"César Alvarez Vallero":{key:"César Alvarez Vallero",scope:"author",path:"/blog/author/César Alvarez Vallero/",pageKeys:["v-d0375c8e"]}}};class Hc{constructor(t,e){this._metaMap=Object.assign({},t),Object.keys(this._metaMap).forEach(t=>{const{pageKeys:n}=this._metaMap[t];this._metaMap[t].pages=n.map(t=>function(t,e){for(let n=0;n{const{pages:n,path:i}=this._metaMap[e];t.push({name:e,pages:n,path:i})}),t}getItemByName(t){return this._metaMap[t]}}var Vc={blog:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},tags:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},author:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1}},Gc={blog:function(t,e,n){return t.pid===n&&t.id===e},tags:function(t,e,n){const i=e;return["tags"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})},author:function(t,e,n){const i=e;return["author","authors"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})}},Zc=[{pid:"blog",id:"blog",filter:Gc.blog,sorter:Vc.blog,pages:[{path:"/blog/",interval:[0,9]},{path:"/blog/page/2/",interval:[10,19]},{path:"/blog/page/3/",interval:[20,29]},{path:"/blog/page/4/",interval:[30,39]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/BDK/",interval:[0,9]},{path:"/blog/tags/BDK/page/2/",interval:[10,13]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"project",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/project/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"grants",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/grants/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tutorial",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/tutorial/",interval:[0,7]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-cli",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bdk-cli/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"multi-sig",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/multi-sig/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Bitcoin Core",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Bitcoin Core/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"RPC",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/RPC/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Wallet",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Wallet/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"architecture",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/architecture/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK-RN",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/BDK-RN/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Development",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Development/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Architecture",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Architecture/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"basics",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/basics/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"novice",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/novice/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bindings",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bindings/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tor",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/tor/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"wallet",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/wallet/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"blockchain",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/blockchain/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"compact_filters",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/compact_filters/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BIP157",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/BIP157/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Neutrino",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Neutrino/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"guide",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/guide/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"descriptor",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/descriptor/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"paper wallets",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/paper wallets/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bitcoin/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"React Native",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/React Native/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Flutter",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Flutter/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"iOS",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/iOS/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Android",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Android/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"mobile",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/mobile/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-rn",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bdk-rn/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bdk/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"fee",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/fee/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"machine learning",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/machine learning/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"taproot",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/taproot/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"miniscript",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/miniscript/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Hardware Wallets",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Hardware Wallets/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin-cli",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bitcoin-cli/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"getting started",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/getting started/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"rust",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/rust/",interval:[0,9]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"coin selection",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/coin selection/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"development",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/development/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"summer of bitcoin",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/summer of bitcoin/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"security",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/security/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"release",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/release/",interval:[0,8]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Steve Myers",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Steve Myers/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Daniela Brozzoni",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Daniela Brozzoni/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"thunderbiscuit",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/thunderbiscuit/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"waterst0ne",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/waterst0ne/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Rajarshi Maitra",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Rajarshi Maitra/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Lloyd Fournier",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Lloyd Fournier/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Bitcoin Zavior",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Bitcoin Zavior/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"rorp",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/rorp/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Riccardo Casatta",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Riccardo Casatta/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Gabriele Domenichini",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Gabriele Domenichini/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Alekos Filini",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Alekos Filini/",interval:[0,9]},{path:"/blog/author/Alekos Filini/page/2/",interval:[10,13]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Wszdexdrf",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Wszdexdrf/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Sandipan Dey",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Sandipan Dey/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"César Alvarez Vallero",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/César Alvarez Vallero/",interval:[0,1]}],prevText:"Prev",nextText:"Next"}],Qc=n(95);const Xc=n.n(Qc)()("plugin-blog:pagination");class Jc{constructor(t,e,n){Xc("pagination",t);const{pages:i,prevText:o,nextText:r}=t,{path:a}=n;this._prevText=o,this._nextText=r;for(let t=0,e=i.length;tt.filter(e,t.id,t.pid)).sort(t.sorter)}setIndexPage(t){this._indexPage=t}get length(){return this._paginationPages.length}get pages(){const[t,e]=this._currentPage.interval;return this._matchedPages.slice(t,e+1)}get hasPrev(){return 0!==this.paginationIndex}get prevLink(){return this.hasPrev?this.paginationIndex-1==0&&this._indexPage?this._indexPage:this._paginationPages[this.paginationIndex-1].path:null}get hasNext(){return this.paginationIndex!==this.length-1}get nextLink(){return this.hasNext?this._paginationPages[this.paginationIndex+1].path:null}get prevText(){return this._prevText}get nextText(){return this._nextText}getSpecificPageLink(t){return this._paginationPages[t].path}}const Yc=new class{constructor(t){this.paginations=t}get pages(){return Vn.$vuepress.$get("siteData").pages}getPagination(t,e,n){Xc("id",e),Xc("pid",t);const i=this.paginations.filter(n=>n.id===e&&n.pid===t)[0];return new Jc(i,this.pages,n)}}(Zc);var tl={comment:{enabled:!1,service:""},email:{enabled:!1},feed:{rss:!1,atom:!1,json:!1}},el=[({router:t})=>{"undefined"!=typeof process&&"server"===process.env.VUE_ENV||t.onReady(()=>{const{app:e}=t;e.$once("hook:mounted",()=>{setTimeout(()=>{const{hash:t}=document.location;if(t.length>1){const e=t.substring(1),n=document.getElementById(e);n&&n.scrollIntoView()}},500)}),document.addEventListener("click",Ic),document.addEventListener("keyup",t=>{Rc(t)&&Ic(t)})})},{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({Vue:t})=>{t.component("CodeCopy",Tc)},({Vue:t})=>{t.component("Mermaid",Lc)},({Vue:t})=>t.use(zc.a),{},{},({Vue:t})=>{const e=Object.keys(qc).map(t=>{const e=qc[t],n="$"+t;return{[n](){const{pages:t}=this.$site;return new Hc(e,t)},["$current"+(t.charAt(0).toUpperCase()+t.slice(1))](){const t=this.$route.meta.id;return this[n].getItemByName(t)}}}).reduce((t,e)=>(Object.assign(t,e),t),{});e.$frontmatterKey=function(){const t=this["$"+this.$route.meta.id];return t||null},t.mixin({computed:e})},({Vue:t})=>{t.mixin({computed:{$pagination(){return this.$route.meta.pid&&this.$route.meta.id?this.$getPagination(this.$route.meta.pid,this.$route.meta.id):null}},methods:{$getPagination(t,e){return e=e||t,Yc.getPagination(t,e,this.$route)}}})},({Vue:t})=>{const e={$service:()=>tl};t.mixin({computed:e})}],nl=[];class il extends class{constructor(){this.store=new Vn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Vn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(il.prototype,{getPageAsyncComponent:cc,getLayoutAsyncComponent:lc,getAsyncComponent:sc,getVueComponent:pc});var ol={install(t){const e=new il;t.$vuepress=e,t.prototype.$vuepress=e}};function rl(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var al={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return uc("pageKey",e),Vn.component(e)||Vn.component(e,cc(e)),Vn.component(e)?t(e):t("")}},cl={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},ll={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},sl=(n(248),n(249),Object(Sc.a)(ll,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),pl={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Vn.config.productionTip=!1,Vn.use(qa),Vn.use(ol),Vn.mixin(function(t,e,n=Vn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const i=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(i)),r={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),r),{computed:r}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const i in t)"/"===i?n=t[i]:0===this.$page.path.indexOf(i)&&(e=t[i]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,i=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?i?i+" | "+n:n:i||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Vn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,i)=>{if(rl(t,e.path))i();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";rl(t,n)?i(n):i()}else i();else{const n=e.path+"/",o=e.path+".html";rl(t,o)?i(o):rl(t,n)?i(n):i()}})}(n);const i={};try{await Promise.all(el.filter(t=>"function"==typeof t).map(e=>e({Vue:Vn,options:i,router:n,siteData:Ec,isServer:t})))}catch(t){console.error(t)}return{app:new Vn(Object.assign(i,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},nl.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file +var i=Object.freeze({}),o=Array.isArray;function r(t){return null==t}function a(t){return null!=t}function c(t){return!0===t}function l(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function s(t){return"function"==typeof t}function p(t){return null!==t&&"object"==typeof t}var d=Object.prototype.toString;function u(t){return"[object Object]"===d.call(t)}function g(t){return"[object RegExp]"===d.call(t)}function h(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function m(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function f(t){return null==t?"":Array.isArray(t)||u(t)&&t.toString===d?JSON.stringify(t,v,2):String(t)}function v(t,e){return e&&e.__v_isRef?e.value:e}function b(t){var e=parseFloat(t);return isNaN(e)?t:e}function y(t,e){for(var n=Object.create(null),i=t.split(","),o=0;o-1)return t.splice(i,1)}}var _=Object.prototype.hasOwnProperty;function B(t,e){return _.call(t,e)}function D(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var x=/-(\w)/g,P=D((function(t){return t.replace(x,(function(t,e){return e?e.toUpperCase():""}))})),K=D((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),S=/\B([A-Z])/g,T=D((function(t){return t.replace(S,"-$1").toLowerCase()}));var O=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var i=arguments.length;return i?i>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function C(t,e){e=e||0;for(var n=t.length-e,i=new Array(n);n--;)i[n]=t[n+e];return i}function F(t,e){for(var n in e)t[n]=e[n];return t}function A(t){for(var e={},n=0;n0,Y=Q&&Q.indexOf("edge/")>0;Q&&Q.indexOf("android");var tt=Q&&/iphone|ipad|ipod|ios/.test(Q);Q&&/chrome\/\d+/.test(Q),Q&&/phantomjs/.test(Q);var et,nt=Q&&Q.match(/firefox\/(\d+)/),it={}.watch,ot=!1;if(Z)try{var rt={};Object.defineProperty(rt,"passive",{get:function(){ot=!0}}),window.addEventListener("test-passive",null,rt)}catch(t){}var at=function(){return void 0===et&&(et=!Z&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),et},ct=Z&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function lt(t){return"function"==typeof t&&/native code/.test(t.toString())}var st,pt="undefined"!=typeof Symbol&<(Symbol)&&"undefined"!=typeof Reflect&<(Reflect.ownKeys);st="undefined"!=typeof Set&<(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var dt=null;function ut(t){void 0===t&&(t=null),t||dt&&dt._scope.off(),dt=t,t&&t._scope.on()}var gt=function(){function t(t,e,n,i,o,r,a,c){this.tag=t,this.data=e,this.children=n,this.text=i,this.elm=o,this.ns=void 0,this.context=r,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=c,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),ht=function(t){void 0===t&&(t="");var e=new gt;return e.text=t,e.isComment=!0,e};function mt(t){return new gt(void 0,void 0,void 0,String(t))}function ft(t){var e=new gt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}"function"==typeof SuppressedError&&SuppressedError;var vt=0,bt=[],yt=function(){function t(){this._pending=!1,this.id=vt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,bt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,i=e.length;n0&&(Qt((s=t(s,"".concat(n||"","_").concat(i)))[0])&&Qt(d)&&(u[p]=mt(d.text+s[0].text),s.shift()),u.push.apply(u,s)):l(s)?Qt(d)?u[p]=mt(d.text+s):""!==s&&u.push(mt(s)):Qt(s)&&Qt(d)?u[p]=mt(d.text+s.text):(c(e._isVList)&&a(s.tag)&&r(s.key)&&a(n)&&(s.key="__vlist".concat(n,"_").concat(i,"__")),u.push(s)));return u}(t):void 0}function Qt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Xt(t,e){var n,i,r,c,l=null;if(o(t)||"string"==typeof t)for(l=new Array(t.length),n=0,i=t.length;n0,c=e?!!e.$stable:!a,l=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(c&&o&&o!==i&&l===o.$key&&!a&&!o.$hasNormal)return o;for(var s in r={},e)e[s]&&"$"!==s[0]&&(r[s]=fe(t,n,s,e[s]))}else r={};for(var p in n)p in r||(r[p]=ve(n,p));return e&&Object.isExtensible(e)&&(e._normalized=r),H(r,"$stable",c),H(r,"$key",l),H(r,"$hasNormal",a),r}function fe(t,e,n,i){var r=function(){var e=dt;ut(t);var n=arguments.length?i.apply(null,arguments):i({}),r=(n=n&&"object"==typeof n&&!o(n)?[n]:Zt(n))&&n[0];return ut(e),n&&(!r||1===n.length&&r.isComment&&!he(r))?void 0:n};return i.proxy&&Object.defineProperty(e,n,{get:r,enumerable:!0,configurable:!0}),r}function ve(t,e){return function(){return t[e]}}function be(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),ye(e,t.$attrs,i,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ye(t._listenersProxy={},t.$listeners,i,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||ke(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:O(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return Ut(t,e,n)}))}}}function ye(t,e,n,i,o){var r=!1;for(var a in e)a in t?e[a]!==n[a]&&(r=!0):(r=!0,we(t,a,i,o));for(var a in t)a in e||(r=!0,delete t[a]);return r}function we(t,e,n,i){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[i][e]}})}function ke(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var _e=null;function Be(t,e){return(t.__esModule||pt&&"Module"===t[Symbol.toStringTag])&&(t=t.default),p(t)?e.extend(t):t}function De(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(sn=function(){return pn.now()})}var dn=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function un(){var t,e;for(ln=sn(),an=!0,en.sort(dn),cn=0;cncn&&en[n].id>t.id;)n--;en.splice(n+1,0,t)}else en.push(t);rn||(rn=!0,Ie(un))}}function hn(t,e){if(t){for(var n=Object.create(null),i=pt?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(r&&!B(o,"default"))a=!1;else if(""===a||a===T(t)){var l=jn(String,o.type);(l<0||c-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!g(t)&&t.test(e)}function Xn(t,e){var n=t.cache,i=t.keys,o=t._vnode,r=t.$vnode;for(var a in n){var c=n[a];if(c){var l=c.name;l&&!e(l)&&Jn(n,a,i,o)}}r.componentOptions.children=void 0}function Jn(t,e,n,i){var o=t[e];!o||i&&o.tag===i.tag||o.componentInstance.$destroy(),t[e]=null,k(n,e)}Vn.prototype._init=function(t){var e=this;e._uid=qn++,e._isVue=!0,e.__v_skip=!0,e._scope=new Lt(!0),e._scope.parent=void 0,e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),i=e._parentVnode;n.parent=e.parent,n._parentVnode=i;var o=i.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=On(Hn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ze(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=ue(e._renderChildren,o),t.$scopedSlots=n?me(t.$parent,n.data.scopedSlots,t.$slots):i,t._c=function(e,n,i,o){return xe(t,e,n,i,o,!1)},t.$createElement=function(e,n,i,o){return xe(t,e,n,i,o,!0)};var r=n&&n.data;Ft(t,"$attrs",r&&r.attrs||i,null,!0),Ft(t,"$listeners",e._parentListeners||i,null,!0)}(e),tn(e,"beforeCreate",void 0,!1),function(t){var e=hn(t.$options.inject,t);e&&(St(!1),Object.keys(e).forEach((function(n){Ft(t,n,e[n])})),St(!0))}(e),In(e),function(t){var e=t.$options.provide;if(e){var n=s(e)?e.call(t):e;if(!p(n))return;for(var i=Wt(t),o=pt?Reflect.ownKeys(n):Object.keys(n),r=0;r1?C(n):n;for(var i=C(arguments,1),o='event handler for "'.concat(t,'"'),r=0,a=n.length;rparseInt(this.max)&&Jn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Jn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Xn(t,(function(t){return Qn(e,t)}))})),this.$watch("exclude",(function(e){Xn(t,(function(t){return!Qn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=De(t),n=e&&e.componentOptions;if(n){var i=Zn(n),o=this.include,r=this.exclude;if(o&&(!i||!Qn(o,i))||r&&i&&Qn(r,i))return e;var a=this.cache,c=this.keys,l=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[l]?(e.componentInstance=a[l].componentInstance,k(c,l),c.push(l)):(this.vnodeToCache=e,this.keyToCache=l),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return W}};Object.defineProperty(t,"config",e),t.util={warn:Bn,extend:F,mergeOptions:On,defineReactive:Ft},t.set=At,t.delete=Et,t.nextTick=Ie,t.observable=function(t){return Ct(t),t},t.options=Object.create(null),N.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,F(t.options.components,ti),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=C(arguments,1);return n.unshift(this),s(t.install)?t.install.apply(t,n):s(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=On(this.options,t),this}}(t),Gn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&u(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&s(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Vn),Object.defineProperty(Vn.prototype,"$isServer",{get:at}),Object.defineProperty(Vn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Vn,"FunctionalRenderContext",{value:mn}),Vn.version="2.7.16";var ei=y("style,class"),ni=y("input,textarea,option,select,progress"),ii=y("contenteditable,draggable,spellcheck"),oi=y("events,caret,typing,plaintext-only"),ri=y("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ai="http://www.w3.org/1999/xlink",ci=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},li=function(t){return ci(t)?t.slice(6,t.length):""},si=function(t){return null==t||!1===t};function pi(t){for(var e=t.data,n=t,i=t;a(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(e=di(i.data,e));for(;a(n=n.parent);)n&&n.data&&(e=di(e,n.data));return function(t,e){if(a(t)||a(e))return ui(t,gi(e));return""}(e.staticClass,e.class)}function di(t,e){return{staticClass:ui(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function ui(t,e){return t?e?t+" "+e:t:e||""}function gi(t){return Array.isArray(t)?function(t){for(var e,n="",i=0,o=t.length;i-1?Mi(t,e,n):ri(e)?si(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):ii(e)?t.setAttribute(e,function(t,e){return si(e)||"false"===e?"false":"contenteditable"===t&&oi(e)?e:"true"}(e,n)):ci(e)?si(n)?t.removeAttributeNS(ai,li(e)):t.setAttributeNS(ai,e,n):Mi(t,e,n)}function Mi(t,e,n){if(si(n))t.removeAttribute(e);else{if(X&&!J&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var i=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",i)};t.addEventListener("input",i),t.__ieph=!0}t.setAttribute(e,n)}}var Ri={create:$i,update:$i};function Ii(t,e){var n=e.elm,i=e.data,o=t.data;if(!(r(i.staticClass)&&r(i.class)&&(r(o)||r(o.staticClass)&&r(o.class)))){var c=pi(e),l=n._transitionClasses;a(l)&&(c=ui(c,gi(l))),c!==n._prevClass&&(n.setAttribute("class",c),n._prevClass=c)}}var Ui,Ni={create:Ii,update:Ii};function Li(t,e,n){var i=Ui;return function o(){var r=e.apply(null,arguments);null!==r&&qi(t,o,n,i)}}var Wi=Ce&&!(nt&&Number(nt[1])<=53);function zi(t,e,n,i){if(Wi){var o=ln,r=e;e=r._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return r.apply(this,arguments)}}Ui.addEventListener(t,e,ot?{capture:n,passive:i}:n)}function qi(t,e,n,i){(i||Ui).removeEventListener(t,e._wrapper||e,n)}function Hi(t,e){if(!r(t.data.on)||!r(e.data.on)){var n=e.data.on||{},i=t.data.on||{};Ui=e.elm||t.elm,function(t){if(a(t.__r)){var e=X?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Ht(n,i,zi,qi,Li,e.context),Ui=void 0}}var Vi,Gi={create:Hi,update:Hi,destroy:function(t){return Hi(t,Di)}};function Zi(t,e){if(!r(t.data.domProps)||!r(e.data.domProps)){var n,i,o=e.elm,l=t.data.domProps||{},s=e.data.domProps||{};for(n in(a(s.__ob__)||c(s._v_attr_proxy))&&(s=e.data.domProps=F({},s)),l)n in s||(o[n]="");for(n in s){if(i=s[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),i===l[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=i;var p=r(i)?"":String(i);Qi(o,p)&&(o.value=p)}else if("innerHTML"===n&&fi(o.tagName)&&r(o.innerHTML)){(Vi=Vi||document.createElement("div")).innerHTML="".concat(i,"");for(var d=Vi.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;d.firstChild;)o.appendChild(d.firstChild)}else if(i!==l[n])try{o[n]=i}catch(t){}}}}function Qi(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,i=t._vModifiers;if(a(i)){if(i.number)return b(n)!==b(e);if(i.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Xi={create:Zi,update:Zi},Ji=D((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var i=t.split(n);i.length>1&&(e[i[0].trim()]=i[1].trim())}})),e}));function Yi(t){var e=to(t.style);return t.staticStyle?F(t.staticStyle,e):e}function to(t){return Array.isArray(t)?A(t):"string"==typeof t?Ji(t):t}var eo,no=/^--/,io=/\s*!important$/,oo=function(t,e,n){if(no.test(e))t.style.setProperty(e,n);else if(io.test(n))t.style.setProperty(T(e),n.replace(io,""),"important");else{var i=ao(e);if(Array.isArray(n))for(var o=0,r=n.length;o-1?e.split(so).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function uo(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(so).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),i=" "+e+" ";n.indexOf(i)>=0;)n=n.replace(i," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function go(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&F(e,ho(t.name||"v")),F(e,t),e}return"string"==typeof t?ho(t):void 0}}var ho=D((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),mo=Z&&!J,fo="transition",vo="transitionend",bo="animation",yo="animationend";mo&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(fo="WebkitTransition",vo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(bo="WebkitAnimation",yo="webkitAnimationEnd"));var wo=Z?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function ko(t){wo((function(){wo(t)}))}function _o(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),po(t,e))}function Bo(t,e){t._transitionClasses&&k(t._transitionClasses,e),uo(t,e)}function Do(t,e,n){var i=Po(t,e),o=i.type,r=i.timeout,a=i.propCount;if(!o)return n();var c="transition"===o?vo:yo,l=0,s=function(){t.removeEventListener(c,p),n()},p=function(e){e.target===t&&++l>=a&&s()};setTimeout((function(){l0&&(n="transition",p=a,d=r.length):"animation"===e?s>0&&(n="animation",p=s,d=l.length):d=(n=(p=Math.max(a,s))>0?a>s?"transition":"animation":null)?"transition"===n?r.length:l.length:0,{type:n,timeout:p,propCount:d,hasTransform:"transition"===n&&xo.test(i[fo+"Property"])}}function Ko(t,e){for(;t.length1}function Ao(t,e){!0!==e.data.show&&To(e)}var Eo=function(t){var e,n,i={},s=t.modules,p=t.nodeOps;for(e=0;eh?w(t,r(n[v+1])?null:n[v+1].elm,n,g,v,i):g>v&&_(e,d,h)}(d,m,v,n,s):a(v)?(a(t.text)&&p.setTextContent(d,""),w(d,null,v,0,v.length-1,n)):a(m)?_(m,0,m.length-1):a(t.text)&&p.setTextContent(d,""):t.text!==e.text&&p.setTextContent(d,e.text),a(h)&&a(g=h.hook)&&a(g=g.postpatch)&&g(t,e)}}}function P(t,e,n){if(c(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var i=0;i-1,a.selected!==r&&(a.selected=r);else if(M(Io(a),i))return void(t.selectedIndex!==c&&(t.selectedIndex=c));o||(t.selectedIndex=-1)}}function Ro(t,e){return e.every((function(e){return!M(e,t)}))}function Io(t){return"_value"in t?t._value:t.value}function Uo(t){t.target.composing=!0}function No(t){t.target.composing&&(t.target.composing=!1,Lo(t.target,"input"))}function Lo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Wo(t){return!t.componentInstance||t.data&&t.data.transition?t:Wo(t.componentInstance._vnode)}var zo={model:$o,show:{bind:function(t,e,n){var i=e.value,o=(n=Wo(n)).data&&n.data.transition,r=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;i&&o?(n.data.show=!0,To(n,(function(){t.style.display=r}))):t.style.display=i?r:"none"},update:function(t,e,n){var i=e.value;!i!=!e.oldValue&&((n=Wo(n)).data&&n.data.transition?(n.data.show=!0,i?To(n,(function(){t.style.display=t.__vOriginalDisplay})):Oo(n,(function(){t.style.display="none"}))):t.style.display=i?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,i,o){o||(t.style.display=t.__vOriginalDisplay)}}},qo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Ho(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ho(De(e.children)):t}function Vo(t){var e={},n=t.$options;for(var i in n.propsData)e[i]=t[i];var o=n._parentListeners;for(var i in o)e[P(i)]=o[i];return e}function Go(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Zo=function(t){return t.tag||he(t)},Qo=function(t){return"show"===t.name},Xo={name:"transition",props:qo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Zo)).length){0;var i=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var r=Ho(o);if(!r)return o;if(this._leaving)return Go(t,o);var a="__transition-".concat(this._uid,"-");r.key=null==r.key?r.isComment?a+"comment":a+r.tag:l(r.key)?0===String(r.key).indexOf(a)?r.key:a+r.key:r.key;var c=(r.data||(r.data={})).transition=Vo(this),s=this._vnode,p=Ho(s);if(r.data.directives&&r.data.directives.some(Qo)&&(r.data.show=!0),p&&p.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(r,p)&&!he(p)&&(!p.componentInstance||!p.componentInstance._vnode.isComment)){var d=p.data.transition=F({},c);if("out-in"===i)return this._leaving=!0,Vt(d,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Go(t,o);if("in-out"===i){if(he(r))return s;var u,g=function(){u()};Vt(c,"afterEnter",g),Vt(c,"enterCancelled",g),Vt(d,"delayLeave",(function(t){u=t}))}}return o}}},Jo=F({tag:String,moveClass:String},qo);function Yo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function tr(t){t.data.newPos=t.elm.getBoundingClientRect()}function er(t){var e=t.data.pos,n=t.data.newPos,i=e.left-n.left,o=e.top-n.top;if(i||o){t.data.moved=!0;var r=t.elm.style;r.transform=r.WebkitTransform="translate(".concat(i,"px,").concat(o,"px)"),r.transitionDuration="0s"}}delete Jo.mode;var nr={Transition:Xo,TransitionGroup:{props:Jo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,i){var o=Xe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,i)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),i=this.prevChildren=this.children,o=this.$slots.default||[],r=this.children=[],a=Vo(this),c=0;c-1?bi[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:bi[t]=/HTMLUnknownElement/.test(e.toString())},F(Vn.options.directives,zo),F(Vn.options.components,nr),Vn.prototype.__patch__=Z?Eo:E,Vn.prototype.$mount=function(t,e){return function(t,e,n){var i;t.$el=e,t.$options.render||(t.$options.render=ht),tn(t,"beforeMount"),i=function(){t._update(t._render(),n)},new qe(t,i,E,{before:function(){t._isMounted&&!t._isDestroyed&&tn(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var r=0;r=0&&(e=t.slice(i),t=t.slice(0,i));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),s=e&&e.path||"/",p=l.path?Br(l.path,s,n||o.append):s,d=function(t,e,n){void 0===e&&(e={});var i,o=n||pr;try{i=o(t||"")}catch(t){i={}}for(var r in e){var a=e[r];i[r]=Array.isArray(a)?a.map(sr):sr(a)}return i}(l.query,o.query,i&&i.options.parseQuery),u=o.hash||l.hash;return u&&"#"!==u.charAt(0)&&(u="#"+u),{_normalized:!0,path:p,query:d,hash:u}}var zr,qr=function(){},Hr={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,i=this.$route,o=n.resolve(this.to,i,this.append),r=o.location,a=o.route,c=o.href,l={},s=n.options.linkActiveClass,p=n.options.linkExactActiveClass,d=null==s?"router-link-active":s,u=null==p?"router-link-exact-active":p,g=null==this.activeClass?d:this.activeClass,h=null==this.exactActiveClass?u:this.exactActiveClass,m=a.redirectedFrom?gr(null,Wr(a.redirectedFrom),null,n):a;l[h]=br(i,m,this.exactPath),l[g]=this.exact||this.exactPath?l[h]:function(t,e){return 0===t.path.replace(ur,"/").indexOf(e.path.replace(ur,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(i,m);var f=l[h]?this.ariaCurrentValue:null,v=function(t){Vr(t)&&(e.replace?n.replace(r,qr):n.push(r,qr))},b={click:Vr};Array.isArray(this.event)?this.event.forEach((function(t){b[t]=v})):b[this.event]=v;var y={class:l},w=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:c,route:a,navigate:v,isActive:l[g],isExactActive:l[h]});if(w){if(1===w.length)return w[0];if(w.length>1||!w.length)return 0===w.length?t():t("span",{},w)}if("a"===this.tag)y.on=b,y.attrs={href:c,"aria-current":f};else{var k=function t(e){var n;if(e)for(var i=0;i-1&&(c.params[u]=n.params[u]);return c.path=Lr(p.path,c.params),l(p,c,a)}if(c.path){c.params={};for(var g=0;g-1}function Da(t,e){return Ba(t)&&t._isRouter&&(null==e||t.type===e)}function xa(t,e,n){var i=function(o){o>=t.length?n():t[o]?e(t[o],(function(){i(o+1)})):i(o+1)};i(0)}function Pa(t){return function(e,n,i){var o=!1,r=0,a=null;Ka(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){o=!0,r++;var l,s=Oa((function(e){var o;((o=e).__esModule||Ta&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:zr.extend(e),n.components[c]=e,--r<=0&&i()})),p=Oa((function(t){var e="Failed to resolve async component "+c+": "+t;a||(a=Ba(t)?t:new Error(e),i(a))}));try{l=t(s,p)}catch(t){p(t)}if(l)if("function"==typeof l.then)l.then(s,p);else{var d=l.component;d&&"function"==typeof d.then&&d.then(s,p)}}})),o||i()}}function Ka(t,e){return Sa(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Sa(t){return Array.prototype.concat.apply([],t)}var Ta="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Oa(t){var e=!1;return function(){for(var n=[],i=arguments.length;i--;)n[i]=arguments[i];if(!e)return e=!0,t.apply(this,n)}}var Ca=function(t,e){this.router=t,this.base=function(t){if(!t)if(Gr){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=mr,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Fa(t,e,n,i){var o=Ka(t,(function(t,i,o,r){var a=function(t,e){"function"!=typeof t&&(t=zr.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,i,o,r)})):n(a,i,o,r)}));return Sa(i?o.reverse():o)}function Aa(t,e){if(e)return function(){return t.apply(e,arguments)}}Ca.prototype.listen=function(t){this.cb=t},Ca.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Ca.prototype.onError=function(t){this.errorCbs.push(t)},Ca.prototype.transitionTo=function(t,e,n){var i,o=this;try{i=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var r=this.current;this.confirmTransition(i,(function(){o.updateRoute(i),e&&e(i),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(i,r)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(i)})))}),(function(t){n&&n(t),t&&!o.ready&&(Da(t,ba.redirected)&&r===mr||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},Ca.prototype.confirmTransition=function(t,e,n){var i=this,o=this.current;this.pending=t;var r,a,c=function(t){!Da(t)&&Ba(t)&&(i.errorCbs.length?i.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},l=t.matched.length-1,s=o.matched.length-1;if(br(t,o)&&l===s&&t.matched[l]===o.matched[s])return this.ensureURL(),t.hash&&aa(this.router,o,t,!1),c(((a=ka(r=o,t,ba.duplicated,'Avoided redundant navigation to current location: "'+r.fullPath+'".')).name="NavigationDuplicated",a));var p=function(t,e){var n,i=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,i=ma&&n;i&&this.listeners.push(ra());var o=function(){var n=t.current,o=$a(t.base);t.current===mr&&o===t._startLocation||t.transitionTo(o,(function(t){i&&aa(e,t,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){fa(Dr(i.base+t.fullPath)),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){va(Dr(i.base+t.fullPath)),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if($a(this.base)!==this.current.fullPath){var e=Dr(this.base+this.current.fullPath);t?fa(e):va(e)}},e.prototype.getCurrentLocation=function(){return $a(this.base)},e}(Ca);function $a(t){var e=window.location.pathname,n=e.toLowerCase(),i=t.toLowerCase();return!t||n!==i&&0!==n.indexOf(Dr(i+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var ja=function(t){function e(e,n,i){t.call(this,e,n),i&&function(t){var e=$a(t);if(!/^\/#/.test(e))return window.location.replace(Dr(t+"/#"+e)),!0}(this.base)||Ma()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=ma&&e;n&&this.listeners.push(ra());var i=function(){var e=t.current;Ma()&&t.transitionTo(Ra(),(function(i){n&&aa(t.router,i,e,!0),ma||Na(i.fullPath)}))},o=ma?"popstate":"hashchange";window.addEventListener(o,i),this.listeners.push((function(){window.removeEventListener(o,i)}))}},e.prototype.push=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){Ua(t.fullPath),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this,o=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),aa(i.router,t,o,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ra()!==e&&(t?Ua(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ra()},e}(Ca);function Ma(){var t=Ra();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ra(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Ia(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ua(t){ma?fa(Ia(t)):window.location.hash=t}function Na(t){ma?va(Ia(t)):window.location.replace(Ia(t))}var La=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index+1).concat(t),i.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var i=this;this.transitionTo(t,(function(t){i.stack=i.stack.slice(0,i.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var i=this.stack[n];this.confirmTransition(i,(function(){var t=e.current;e.index=n,e.updateRoute(i),e.router.afterHooks.forEach((function(e){e&&e(i,t)}))}),(function(t){Da(t,ba.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Ca),Wa=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Xr(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ma&&!1!==t.fallback,this.fallback&&(e="hash"),Gr||(e="abstract"),this.mode=e,e){case"history":this.history=new Ea(this,t.base);break;case"hash":this.history=new ja(this,t.base,this.fallback);break;case"abstract":this.history=new La(this,t.base);break;default:0}},za={currentRoute:{configurable:!0}};Wa.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},za.currentRoute.get=function(){return this.history&&this.history.current},Wa.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof Ea||n instanceof ja){var i=function(t){n.setupListeners(),function(t){var i=n.current,o=e.options.scrollBehavior;ma&&o&&"fullPath"in t&&aa(e,t,i,!1)}(t)};n.transitionTo(n.getCurrentLocation(),i,i)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Wa.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},Wa.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},Wa.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},Wa.prototype.onReady=function(t,e){this.history.onReady(t,e)},Wa.prototype.onError=function(t){this.history.onError(t)},Wa.prototype.push=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.push(t,e,n)}));this.history.push(t,e,n)},Wa.prototype.replace=function(t,e,n){var i=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){i.history.replace(t,e,n)}));this.history.replace(t,e,n)},Wa.prototype.go=function(t){this.history.go(t)},Wa.prototype.back=function(){this.go(-1)},Wa.prototype.forward=function(){this.go(1)},Wa.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Wa.prototype.resolve=function(t,e,n){var i=Wr(t,e=e||this.history.current,n,this),o=this.match(i,e),r=o.redirectedFrom||o.fullPath;return{location:i,route:o,href:function(t,e,n){var i="hash"===n?"#"+e:e;return t?Dr(t+"/"+i):i}(this.history.base,r,this.mode),normalizedTo:i,resolved:o}},Wa.prototype.getRoutes=function(){return this.matcher.getRoutes()},Wa.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==mr&&this.history.transitionTo(this.history.getCurrentLocation())},Wa.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==mr&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Wa.prototype,za);var qa=Wa;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Wa.install=function t(e){if(!t.installed||zr!==e){t.installed=!0,zr=e;var n=function(t){return void 0!==t},i=function(t,e){var i=t.$options._parentVnode;n(i)&&n(i=i.data)&&n(i=i.registerRouteInstance)&&i(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,i(this,this)},destroyed:function(){i(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",kr),e.component("RouterLink",Hr);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Wa.version="3.6.5",Wa.isNavigationFailure=Da,Wa.NavigationFailureType=ba,Wa.START_LOCATION=mr,Gr&&window.Vue&&window.Vue.use(Wa);n(53);n(100),n(46);var Va={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(23)]).then(n.bind(null,325)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(22)]).then(n.bind(null,286)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(32)]).then(n.bind(null,261)),"components/Home":()=>Promise.all([n.e(0),n.e(27)]).then(n.bind(null,326)),"components/NavLink":()=>n.e(43).then(n.bind(null,253)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(20)]).then(n.bind(null,275)),"components/Navbar":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,285)),"components/Page":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,297)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(28)]).then(n.bind(null,287)),"components/PageNav":()=>Promise.all([n.e(0),n.e(24)]).then(n.bind(null,288)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,268)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(33)]).then(n.bind(null,328)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,264)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(30)]).then(n.bind(null,262)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,255)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,397)),"global-components/CodeBlock":()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,387)),"global-components/CodeGroup":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,388)),"layouts/404":()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,389)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,390)),NotFound:()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,389)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,390)),"components/Cases":()=>Promise.all([n.e(0),n.e(25)]).then(n.bind(null,327)),"components/Footer":()=>Promise.all([n.e(0),n.e(26)]).then(n.bind(null,269)),"components/LayoutWrap":()=>Promise.all([n.e(0),n.e(1),n.e(17)]).then(n.bind(null,276)),"components/PostMeta":()=>Promise.all([n.e(0),n.e(29)]).then(n.bind(null,298)),"layouts/DirectoryPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,391)),"layouts/FrontmatterKey":()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,392)),"layouts/FrontmatterPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,393)),"layouts/IndexPost":()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,324)),"layouts/Post":()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,394)),DirectoryPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,391)),FrontmatterKey:()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,392)),FrontmatterPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,393)),IndexPost:()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,324)),Post:()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,394))},Ga={"v-330a32a2":()=>n.e(45).then(n.bind(null,398)),"v-2c450c3f":()=>n.e(46).then(n.bind(null,399)),"v-5e744cf7":()=>n.e(47).then(n.bind(null,400)),"v-bac76d8e":()=>n.e(49).then(n.bind(null,401)),"v-609f26f9":()=>n.e(48).then(n.bind(null,402)),"v-7c0c45f9":()=>n.e(51).then(n.bind(null,403)),"v-8bd632d6":()=>n.e(52).then(n.bind(null,404)),"v-62ca00fb":()=>n.e(50).then(n.bind(null,405)),"v-0f4d5d15":()=>n.e(53).then(n.bind(null,406)),"v-2cebe183":()=>n.e(34).then(n.bind(null,407)),"v-3eaa044d":()=>n.e(31).then(n.bind(null,408)),"v-353b78e1":()=>n.e(54).then(n.bind(null,409)),"v-3875825f":()=>n.e(55).then(n.bind(null,410)),"v-07ff1843":()=>n.e(56).then(n.bind(null,411)),"v-9504490e":()=>n.e(57).then(n.bind(null,412)),"v-c6756cce":()=>n.e(58).then(n.bind(null,413)),"v-f58ec8f2":()=>n.e(21).then(n.bind(null,414)),"v-56536559":()=>n.e(19).then(n.bind(null,415)),"v-2c605799":()=>n.e(60).then(n.bind(null,416)),"v-57698579":()=>n.e(61).then(n.bind(null,417)),"v-015729b9":()=>n.e(59).then(n.bind(null,418)),"v-9145467a":()=>n.e(62).then(n.bind(null,419)),"v-2cf72b39":()=>n.e(63).then(n.bind(null,420)),"v-11d64359":()=>n.e(64).then(n.bind(null,421)),"v-5d749fce":()=>n.e(65).then(n.bind(null,422)),"v-ab5ba3ce":()=>n.e(66).then(n.bind(null,423)),"v-d0375c8e":()=>n.e(67).then(n.bind(null,424)),"v-10852eea":()=>n.e(68).then(n.bind(null,425)),"v-05df4999":()=>n.e(70).then(n.bind(null,426)),"v-edd5570e":()=>n.e(69).then(n.bind(null,427)),"v-0119984e":()=>n.e(72).then(n.bind(null,428)),"v-faad828e":()=>n.e(71).then(n.bind(null,429)),"v-7c3d28f9":()=>n.e(73).then(n.bind(null,430)),"v-0df1c3ce":()=>n.e(74).then(n.bind(null,431)),"v-75d11339":()=>n.e(75).then(n.bind(null,432)),"v-1ac9ef4e":()=>n.e(76).then(n.bind(null,433)),"v-55969f39":()=>n.e(77).then(n.bind(null,434)),"v-aeb70fce":()=>n.e(79).then(n.bind(null,435)),"v-4dc135e3":()=>n.e(80).then(n.bind(null,436)),"v-8534b9c2":()=>n.e(78).then(n.bind(null,437)),"v-4d760891":()=>Promise.all([n.e(0),n.e(35)]).then(n.bind(null,438)),"v-30c0037b":()=>Promise.all([n.e(0),n.e(36)]).then(n.bind(null,439)),"v-4bb7844a":()=>Promise.all([n.e(0),n.e(37)]).then(n.bind(null,440)),"v-b936290e":()=>Promise.all([n.e(0),n.e(38)]).then(n.bind(null,441)),"v-4e0b610e":()=>Promise.all([n.e(0),n.e(40)]).then(n.bind(null,442)),"v-a7c24c4e":()=>Promise.all([n.e(0),n.e(41)]).then(n.bind(null,443)),"v-17019aeb":()=>Promise.all([n.e(0),n.e(42)]).then(n.bind(null,444)),"v-7afdbb4e":()=>Promise.all([n.e(0),n.e(39)]).then(n.bind(null,445)),"v-7a315e41":()=>n.e(81).then(n.bind(null,446)),"v-f611a14e":()=>n.e(82).then(n.bind(null,447)),"v-3acb6e6a":()=>n.e(83).then(n.bind(null,448)),"v-496cb7f9":()=>n.e(84).then(n.bind(null,395)),"v-a76bccee":()=>n.e(86).then(n.bind(null,449)),"v-0b3b65ea":()=>n.e(85).then(n.bind(null,450)),"v-05d01c19":()=>n.e(87).then(n.bind(null,451)),"v-11bf335e":()=>n.e(88).then(n.bind(null,452)),"v-a9236c10":()=>n.e(89).then(n.bind(null,453)),"v-29f9f21c":()=>n.e(90).then(n.bind(null,454)),"v-3750297a":()=>n.e(91).then(n.bind(null,455)),"v-71ef7c85":()=>n.e(92).then(n.bind(null,456)),"v-105750ce":()=>n.e(93).then(n.bind(null,457)),"v-08589c4e":()=>n.e(94).then(n.bind(null,458)),"v-4a4b61eb":()=>n.e(96).then(n.bind(null,459)),"v-c152529c":()=>n.e(95).then(n.bind(null,460)),"v-50aa6d4e":()=>n.e(97).then(n.bind(null,461)),"v-4bcdac39":()=>n.e(98).then(n.bind(null,462))};function Za(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Qa=/-(\w)/g,Xa=Za(t=>t.replace(Qa,(t,e)=>e?e.toUpperCase():"")),Ja=/\B([A-Z])/g,Ya=Za(t=>t.replace(Ja,"-$1").toLowerCase()),tc=Za(t=>t.charAt(0).toUpperCase()+t.slice(1));function ec(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(tc(Xa(e))):t(tc(e))||t(Ya(e))}const nc=Object.assign({},Va,Ga),ic=t=>nc[t],oc=t=>Ga[t],rc=t=>Va[t],ac=t=>Vn.component(t);function cc(t){return ec(oc,t)}function lc(t){return ec(rc,t)}function sc(t){return ec(ic,t)}function pc(t){return ec(ac,t)}function dc(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!pc(t)&&sc(t)){const e=await sc(t)();Vn.component(t,e.default)}}))}function uc(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var gc=n(91),hc=n.n(gc),mc=n(92),fc=n.n(mc),vc={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${fc()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=yc(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=wc(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return hc()([{name:"description",content:this.$description}],t,this.siteMeta,kc)},updateCanonicalLink(){bc(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",yc(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){wc(null,this.currentMetaTags),bc()}};function bc(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function yc(t=""){return t?``:""}function wc(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function kc(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var _c=n(93),Bc={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(_c)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),i=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=r.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Dc=n(22),xc=n.n(Dc),Pc={mounted(){xc.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Vn.component(t.name)||xc.a.start(),n()}),this.$router.afterEach(()=>{xc.a.done(),this.isSidebarOpen=!1})}},Kc={props:{parent:Object,code:String,options:{align:String,color:String,backgroundTransition:Boolean,backgroundColor:String,successText:String,staticIcon:Boolean}},data:()=>({success:!1,originalBackground:null,originalTransition:null}),computed:{alignStyle(){let t={};return t[this.options.align]="7.5px",t},iconClass(){return this.options.staticIcon?"":"hover"}},mounted(){this.originalTransition=this.parent.style.transition,this.originalBackground=this.parent.style.background},beforeDestroy(){this.parent.style.transition=this.originalTransition,this.parent.style.background=this.originalBackground},methods:{hexToRgb(t){let e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null},copyToClipboard(t){if(navigator.clipboard)navigator.clipboard.writeText(this.code).then(()=>{this.setSuccessTransitions()},()=>{});else{let t=document.createElement("textarea");document.body.appendChild(t),t.value=this.code,t.select(),document.execCommand("Copy"),t.remove(),this.setSuccessTransitions()}},setSuccessTransitions(){if(clearTimeout(this.successTimeout),this.options.backgroundTransition){this.parent.style.transition="background 350ms";let t=this.hexToRgb(this.options.backgroundColor);this.parent.style.background=`rgba(${t.r}, ${t.g}, ${t.b}, 0.1)`}this.success=!0,this.successTimeout=setTimeout(()=>{this.options.backgroundTransition&&(this.parent.style.background=this.originalBackground,this.parent.style.transition=this.originalTransition),this.success=!1},500)}}},Sc=(n(240),n(7)),Tc=Object(Sc.a)(Kc,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"code-copy"},[e("svg",{class:t.iconClass,style:t.alignStyle,attrs:{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},on:{click:t.copyToClipboard}},[e("path",{attrs:{fill:"none",d:"M0 0h24v24H0z"}}),t._v(" "),e("path",{attrs:{fill:t.options.color,d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}})]),t._v(" "),e("span",{class:t.success?"success":"",style:t.alignStyle},[t._v("\n "+t._s(t.options.successText)+"\n ")])])}),[],!1,null,"49140617",null).exports,Oc=(n(241),[vc,Bc,Pc,{updated(){this.update()},methods:{update(){setTimeout(()=>{document.querySelectorAll('div[class*="language-"] pre').forEach(t=>{if(t.classList.contains("code-copy-added"))return;let e=new(Vn.extend(Tc));e.options={align:"bottom",color:"#8F979E",backgroundTransition:!1,backgroundColor:"#0075b8",successText:"Copied!",staticIcon:!0},e.code=t.innerText,e.parent=t,e.$mount(),t.classList.add("code-copy-added"),t.appendChild(e.$el)})},100)}}}]),Cc={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return uc("layout",t),Vn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},Fc=Object(Sc.a)(Cc,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(Fc,"mixins",Oc);const Ac=[{name:"v-330a32a2",path:"/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-330a32a2").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-2c450c3f",path:"/blog/_2023-q4-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2c450c3f").then(n)}},{path:"/blog/_2023-q4-update/index.html",redirect:"/blog/_2023-q4-update/"},{path:"/_blog/2023_q4_update.html",redirect:"/blog/_2023-q4-update/"},{name:"v-5e744cf7",path:"/blog/_2024-q1-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-5e744cf7").then(n)}},{path:"/blog/_2024-q1-update/index.html",redirect:"/blog/_2024-q1-update/"},{path:"/_blog/2024_q1_update.html",redirect:"/blog/_2024-q1-update/"},{name:"v-bac76d8e",path:"/blog/_2024-q3-rfp-rust-maintainer/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-bac76d8e").then(n)}},{path:"/blog/_2024-q3-rfp-rust-maintainer/index.html",redirect:"/blog/_2024-q3-rfp-rust-maintainer/"},{path:"/_blog/2024_q3_rfp_rust_maintainer.html",redirect:"/blog/_2024-q3-rfp-rust-maintainer/"},{name:"v-609f26f9",path:"/blog/_2024-q2-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-609f26f9").then(n)}},{path:"/blog/_2024-q2-update/index.html",redirect:"/blog/_2024-q2-update/"},{path:"/_blog/2024_q2_update.html",redirect:"/blog/_2024-q2-update/"},{name:"v-7c0c45f9",path:"/blog/bitcoin-core-rpc-demo/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-7c0c45f9").then(n)}},{path:"/blog/bitcoin-core-rpc-demo/index.html",redirect:"/blog/bitcoin-core-rpc-demo/"},{path:"/_blog/Bitcoin_Core_RPC_Demo.html",redirect:"/blog/bitcoin-core-rpc-demo/"},{name:"v-8bd632d6",path:"/blog/bdk-cli-basics-multisig-2of3/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-8bd632d6").then(n)}},{path:"/blog/bdk-cli-basics-multisig-2of3/index.html",redirect:"/blog/bdk-cli-basics-multisig-2of3/"},{path:"/_blog/bdk-cli_basics_multisig_2of3.html",redirect:"/blog/bdk-cli-basics-multisig-2of3/"},{name:"v-62ca00fb",path:"/blog/_2024-q3-update/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-62ca00fb").then(n)}},{path:"/blog/_2024-q3-update/index.html",redirect:"/blog/_2024-q3-update/"},{path:"/_blog/2024_q3_update.html",redirect:"/blog/_2024-q3-update/"},{name:"v-0f4d5d15",path:"/blog/bdk-cli-basics/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-0f4d5d15").then(n)}},{path:"/blog/bdk-cli-basics/index.html",redirect:"/blog/bdk-cli-basics/"},{path:"/_blog/bdk_cli_basics.html",redirect:"/blog/bdk-cli-basics/"},{name:"v-2cebe183",path:"/blog/bdk-core-pt1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2cebe183").then(n)}},{path:"/blog/bdk-core-pt1/index.html",redirect:"/blog/bdk-core-pt1/"},{path:"/_blog/bdk_core_pt1.html",redirect:"/blog/bdk-core-pt1/"},{name:"v-3eaa044d",path:"/blog/bdk-rn-making-of/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-3eaa044d").then(n)}},{path:"/blog/bdk-rn-making-of/index.html",redirect:"/blog/bdk-rn-making-of/"},{path:"/_blog/bdk_rn_making_of.html",redirect:"/blog/bdk-rn-making-of/"},{name:"v-353b78e1",path:"/blog/bdk-with-tor/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-353b78e1").then(n)}},{path:"/blog/bdk-with-tor/index.html",redirect:"/blog/bdk-with-tor/"},{path:"/_blog/bdk_with_tor.html",redirect:"/blog/bdk-with-tor/"},{name:"v-3875825f",path:"/blog/bindings-scope/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-3875825f").then(n)}},{path:"/blog/bindings-scope/index.html",redirect:"/blog/bindings-scope/"},{path:"/_blog/bindings-scope.html",redirect:"/blog/bindings-scope/"},{name:"v-07ff1843",path:"/blog/compact-filters-demo/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-07ff1843").then(n)}},{path:"/blog/compact-filters-demo/index.html",redirect:"/blog/compact-filters-demo/"},{path:"/_blog/compact_filters_demo.html",redirect:"/blog/compact-filters-demo/"},{name:"v-9504490e",path:"/blog/descriptor-based-paper-wallet/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-9504490e").then(n)}},{path:"/blog/descriptor-based-paper-wallet/index.html",redirect:"/blog/descriptor-based-paper-wallet/"},{path:"/_blog/descriptor_based_paper_wallet.html",redirect:"/blog/descriptor-based-paper-wallet/"},{name:"v-c6756cce",path:"/blog/descriptors-in-the-wild/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-c6756cce").then(n)}},{path:"/blog/descriptors-in-the-wild/index.html",redirect:"/blog/descriptors-in-the-wild/"},{path:"/_blog/descriptors_in_the_wild.html",redirect:"/blog/descriptors-in-the-wild/"},{name:"v-f58ec8f2",path:"/blog/exploring-bdk-rn/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-f58ec8f2").then(n)}},{path:"/blog/exploring-bdk-rn/index.html",redirect:"/blog/exploring-bdk-rn/"},{path:"/_blog/exploring_bdk_rn.html",redirect:"/blog/exploring-bdk-rn/"},{name:"v-56536559",path:"/blog/exploring-bdk-flutter/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-56536559").then(n)}},{path:"/blog/exploring-bdk-flutter/index.html",redirect:"/blog/exploring-bdk-flutter/"},{path:"/_blog/exploring_bdk_flutter.html",redirect:"/blog/exploring-bdk-flutter/"},{name:"v-2c605799",path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2c605799").then(n)}},{path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/index.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{path:"/_blog/fee_estimation_for_light_clients_part_2.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{name:"v-57698579",path:"/blog/2021/01/fee-estimation-for-light-clients-part-3/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-57698579").then(n)}},{path:"/blog/2021/01/fee-estimation-for-light-clients-part-3/index.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{path:"/_blog/fee_estimation_for_light_clients_part_3.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{name:"v-015729b9",path:"/blog/2021/01/fee-estimation-for-light-clients-part-1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-015729b9").then(n)}},{path:"/blog/2021/01/fee-estimation-for-light-clients-part-1/index.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{path:"/_blog/fee_estimation_for_light_clients_part_1.html",redirect:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{name:"v-9145467a",path:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-9145467a").then(n)}},{path:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/index.html",redirect:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{path:"/_blog/first_bdk_taproot_tx.html",redirect:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{name:"v-2cf72b39",path:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-2cf72b39").then(n)}},{path:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/index.html",redirect:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{path:"/_blog/first_bdk_taproot_tx_part_2.html",redirect:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{name:"v-11d64359",path:"/blog/getting-started-with-rust-hwi/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-11d64359").then(n)}},{path:"/blog/getting-started-with-rust-hwi/index.html",redirect:"/blog/getting-started-with-rust-hwi/"},{path:"/_blog/getting_started_with_rust_hwi.html",redirect:"/blog/getting-started-with-rust-hwi/"},{name:"v-5d749fce",path:"/blog/2020/12/hello-world/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-5d749fce").then(n)}},{path:"/blog/2020/12/hello-world/index.html",redirect:"/blog/2020/12/hello-world/"},{path:"/_blog/hello-world.html",redirect:"/blog/2020/12/hello-world/"},{name:"v-ab5ba3ce",path:"/blog/hidden-power-of-bitcoin/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-ab5ba3ce").then(n)}},{path:"/blog/hidden-power-of-bitcoin/index.html",redirect:"/blog/hidden-power-of-bitcoin/"},{path:"/_blog/hidden-power-of-bitcoin.html",redirect:"/blog/hidden-power-of-bitcoin/"},{name:"v-d0375c8e",path:"/blog/improving-coin-selection-in-bdk/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-d0375c8e").then(n)}},{path:"/blog/improving-coin-selection-in-bdk/index.html",redirect:"/blog/improving-coin-selection-in-bdk/"},{path:"/_blog/improving_coin_selection_in_BDK.html",redirect:"/blog/improving-coin-selection-in-bdk/"},{name:"v-10852eea",path:"/blog/miniscript-vulnerability/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-10852eea").then(n)}},{path:"/blog/miniscript-vulnerability/index.html",redirect:"/blog/miniscript-vulnerability/"},{path:"/_blog/miniscript_vulnerability.html",redirect:"/blog/miniscript-vulnerability/"},{name:"v-05df4999",path:"/blog/2021/01/release-v0.3.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-05df4999").then(n)}},{path:"/blog/2021/01/release-v0.3.0/index.html",redirect:"/blog/2021/01/release-v0.3.0/"},{path:"/_blog/release-0.3.0.html",redirect:"/blog/2021/01/release-v0.3.0/"},{name:"v-edd5570e",path:"/blog/2020/12/release-v0.2.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-edd5570e").then(n)}},{path:"/blog/2020/12/release-v0.2.0/index.html",redirect:"/blog/2020/12/release-v0.2.0/"},{path:"/_blog/release-0.2.0.html",redirect:"/blog/2020/12/release-v0.2.0/"},{name:"v-0119984e",path:"/blog/2021/03/release-v0.5.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-0119984e").then(n)}},{path:"/blog/2021/03/release-v0.5.0/index.html",redirect:"/blog/2021/03/release-v0.5.0/"},{path:"/_blog/release-0.5.0.html",redirect:"/blog/2021/03/release-v0.5.0/"},{name:"v-faad828e",path:"/blog/2021/02/release-v0.4.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-faad828e").then(n)}},{path:"/blog/2021/02/release-v0.4.0/index.html",redirect:"/blog/2021/02/release-v0.4.0/"},{path:"/_blog/release-0.4.0.html",redirect:"/blog/2021/02/release-v0.4.0/"},{name:"v-7c3d28f9",path:"/blog/2021/04/release-v0.6.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-7c3d28f9").then(n)}},{path:"/blog/2021/04/release-v0.6.0/index.html",redirect:"/blog/2021/04/release-v0.6.0/"},{path:"/_blog/release-0.6.0.html",redirect:"/blog/2021/04/release-v0.6.0/"},{name:"v-0df1c3ce",path:"/blog/2021/05/release-v0.7.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-0df1c3ce").then(n)}},{path:"/blog/2021/05/release-v0.7.0/index.html",redirect:"/blog/2021/05/release-v0.7.0/"},{path:"/_blog/release-0.7.0.html",redirect:"/blog/2021/05/release-v0.7.0/"},{name:"v-75d11339",path:"/blog/2021/06/release-v0.8.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-75d11339").then(n)}},{path:"/blog/2021/06/release-v0.8.0/index.html",redirect:"/blog/2021/06/release-v0.8.0/"},{path:"/_blog/release-0.8.0.html",redirect:"/blog/2021/06/release-v0.8.0/"},{name:"v-1ac9ef4e",path:"/blog/2021/07/release-v0.9.0/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-1ac9ef4e").then(n)}},{path:"/blog/2021/07/release-v0.9.0/index.html",redirect:"/blog/2021/07/release-v0.9.0/"},{path:"/_blog/release-0.9.0.html",redirect:"/blog/2021/07/release-v0.9.0/"},{name:"v-55969f39",path:"/blog/road-to-bdk-1/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-55969f39").then(n)}},{path:"/blog/road-to-bdk-1/index.html",redirect:"/blog/road-to-bdk-1/"},{path:"/_blog/road_to_bdk_1.html",redirect:"/blog/road-to-bdk-1/"},{name:"v-aeb70fce",path:"/blog/using-bdk-with-hardware-wallets/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-aeb70fce").then(n)}},{path:"/blog/using-bdk-with-hardware-wallets/index.html",redirect:"/blog/using-bdk-with-hardware-wallets/"},{path:"/_blog/using_bdk_with_hardware_wallets.html",redirect:"/blog/using-bdk-with-hardware-wallets/"},{name:"v-4dc135e3",path:"/blog/why-bindings/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-4dc135e3").then(n)}},{path:"/blog/why-bindings/index.html",redirect:"/blog/why-bindings/"},{path:"/_blog/why-bindings.html",redirect:"/blog/why-bindings/"},{name:"v-8534b9c2",path:"/blog/spending-policy-demo/",component:Fc,beforeEnter:(t,e,n)=>{dc("Post","v-8534b9c2").then(n)}},{path:"/blog/spending-policy-demo/index.html",redirect:"/blog/spending-policy-demo/"},{path:"/_blog/spending_policy_demo.html",redirect:"/blog/spending-policy-demo/"},{name:"v-4d760891",path:"/adoption/all/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4d760891").then(n)}},{path:"/adoption/all/index.html",redirect:"/adoption/all/"},{path:"/adoption/all.html",redirect:"/adoption/all/"},{name:"v-30c0037b",path:"/adoption/custodial/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-30c0037b").then(n)}},{path:"/adoption/custodial/index.html",redirect:"/adoption/custodial/"},{path:"/adoption/custodial.html",redirect:"/adoption/custodial/"},{name:"v-4bb7844a",path:"/adoption/desktop/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4bb7844a").then(n)}},{path:"/adoption/desktop/index.html",redirect:"/adoption/desktop/"},{path:"/adoption/desktop.html",redirect:"/adoption/desktop/"},{name:"v-b936290e",path:"/adoption/exchange/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-b936290e").then(n)}},{path:"/adoption/exchange/index.html",redirect:"/adoption/exchange/"},{path:"/adoption/exchange.html",redirect:"/adoption/exchange/"},{name:"v-4e0b610e",path:"/adoption/infrastructure/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4e0b610e").then(n)}},{path:"/adoption/infrastructure/index.html",redirect:"/adoption/infrastructure/"},{path:"/adoption/infrastructure.html",redirect:"/adoption/infrastructure/"},{name:"v-a7c24c4e",path:"/adoption/mobile/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-a7c24c4e").then(n)}},{path:"/adoption/mobile/index.html",redirect:"/adoption/mobile/"},{path:"/adoption/mobile.html",redirect:"/adoption/mobile/"},{name:"v-17019aeb",path:"/adoption/web/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-17019aeb").then(n)}},{path:"/adoption/web/index.html",redirect:"/adoption/web/"},{path:"/adoption/web.html",redirect:"/adoption/web/"},{name:"v-7afdbb4e",path:"/adoption/hardware/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-7afdbb4e").then(n)}},{path:"/adoption/hardware/index.html",redirect:"/adoption/hardware/"},{path:"/adoption/hardware.html",redirect:"/adoption/hardware/"},{name:"v-7a315e41",path:"/bdk-cli/compiler/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-7a315e41").then(n)}},{path:"/bdk-cli/compiler/index.html",redirect:"/bdk-cli/compiler/"},{path:"/bdk-cli/compiler.html",redirect:"/bdk-cli/compiler/"},{name:"v-f611a14e",path:"/bdk-cli/concept/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-f611a14e").then(n)}},{path:"/bdk-cli/concept/index.html",redirect:"/bdk-cli/concept/"},{path:"/bdk-cli/concept.html",redirect:"/bdk-cli/concept/"},{name:"v-3acb6e6a",path:"/bdk-cli/installation/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-3acb6e6a").then(n)}},{path:"/bdk-cli/installation/index.html",redirect:"/bdk-cli/installation/"},{path:"/bdk-cli/installation.html",redirect:"/bdk-cli/installation/"},{name:"v-496cb7f9",path:"/bdk-cli/interface/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-496cb7f9").then(n)}},{path:"/bdk-cli/interface/index.html",redirect:"/bdk-cli/interface/"},{path:"/bdk-cli/interface.html",redirect:"/bdk-cli/interface/"},{name:"v-a76bccee",path:"/bdk-cli/playground/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-a76bccee").then(n)}},{path:"/bdk-cli/playground/index.html",redirect:"/bdk-cli/playground/"},{path:"/bdk-cli/playground.html",redirect:"/bdk-cli/playground/"},{name:"v-0b3b65ea",path:"/bdk-cli/introduction/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-0b3b65ea").then(n)}},{path:"/bdk-cli/introduction/index.html",redirect:"/bdk-cli/introduction/"},{path:"/bdk-cli/introduction.html",redirect:"/bdk-cli/introduction/"},{name:"v-05d01c19",path:"/bdk-cli/regtest/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-05d01c19").then(n)}},{path:"/bdk-cli/regtest/index.html",redirect:"/bdk-cli/regtest/"},{path:"/bdk-cli/regtest.html",redirect:"/bdk-cli/regtest/"},{name:"v-11bf335e",path:"/case-studies/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-11bf335e").then(n)}},{path:"/case-studies/index.html",redirect:"/case-studies/"},{path:"/case-studies.html",redirect:"/case-studies/"},{name:"v-a9236c10",path:"/descriptors/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-a9236c10").then(n)}},{path:"/descriptors/index.html",redirect:"/descriptors/"},{name:"v-29f9f21c",path:"/examples/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-29f9f21c").then(n)}},{path:"/examples/index.html",redirect:"/examples/"},{name:"v-3750297a",path:"/foundation/about/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-3750297a").then(n)}},{path:"/foundation/about/index.html",redirect:"/foundation/about/"},{path:"/foundation/about.html",redirect:"/foundation/about/"},{name:"v-71ef7c85",path:"/foundation/become-a-member/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-71ef7c85").then(n)}},{path:"/foundation/become-a-member/index.html",redirect:"/foundation/become-a-member/"},{path:"/foundation/become-a-member.html",redirect:"/foundation/become-a-member/"},{name:"v-105750ce",path:"/foundation/grantees/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-105750ce").then(n)}},{path:"/foundation/grantees/index.html",redirect:"/foundation/grantees/"},{path:"/foundation/grantees.html",redirect:"/foundation/grantees/"},{name:"v-08589c4e",path:"/foundation/grants/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-08589c4e").then(n)}},{path:"/foundation/grants/index.html",redirect:"/foundation/grants/"},{path:"/foundation/grants.html",redirect:"/foundation/grants/"},{name:"v-4a4b61eb",path:"/foundation/members/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4a4b61eb").then(n)}},{path:"/foundation/members/index.html",redirect:"/foundation/members/"},{path:"/foundation/members.html",redirect:"/foundation/members/"},{name:"v-c152529c",path:"/foundation/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-c152529c").then(n)}},{path:"/foundation/index.html",redirect:"/foundation/"},{name:"v-50aa6d4e",path:"/foundation/supporters/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-50aa6d4e").then(n)}},{path:"/foundation/supporters/index.html",redirect:"/foundation/supporters/"},{path:"/foundation/supporters.html",redirect:"/foundation/supporters/"},{name:"v-4bcdac39",path:"/getting-started/",component:Fc,beforeEnter:(t,e,n)=>{dc("Layout","v-4bcdac39").then(n)}},{path:"/getting-started/index.html",redirect:"/getting-started/"},{path:"/getting-started.html",redirect:"/getting-started/"},{name:"v-424df898",path:"/blog/",component:Fc,beforeEnter:(t,e,n)=>{dc("IndexPost","v-424df898").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/index.html",redirect:"/blog/"},{name:"v-619df59e",path:"/blog/tags/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterKey","v-619df59e").then(n)},meta:{pid:"tags",id:"tags"}},{path:"/blog/tags/index.html",redirect:"/blog/tags/"},{name:"v-b0968728",path:"/blog/author/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterKey","v-b0968728").then(n)},meta:{pid:"author",id:"author"}},{path:"/blog/author/index.html",redirect:"/blog/author/"},{name:"v-5f2600b8",path:"/blog/tags/BDK/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f2600b8").then(n)},meta:{pid:"tags",id:"BDK"}},{path:"/blog/tags/BDK/index.html",redirect:"/blog/tags/BDK/"},{name:"v-398e8fd4",path:"/blog/tags/project/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-398e8fd4").then(n)},meta:{pid:"tags",id:"project"}},{path:"/blog/tags/project/index.html",redirect:"/blog/tags/project/"},{name:"v-9d39d64c",path:"/blog/tags/grants/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-9d39d64c").then(n)},meta:{pid:"tags",id:"grants"}},{path:"/blog/tags/grants/index.html",redirect:"/blog/tags/grants/"},{name:"v-da8c869a",path:"/blog/tags/tutorial/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-da8c869a").then(n)},meta:{pid:"tags",id:"tutorial"}},{path:"/blog/tags/tutorial/index.html",redirect:"/blog/tags/tutorial/"},{name:"v-62bbf2ad",path:"/blog/tags/Bitcoin Core/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-62bbf2ad").then(n)},meta:{pid:"tags",id:"Bitcoin Core"}},{path:"/blog/tags/Bitcoin Core/index.html",redirect:"/blog/tags/Bitcoin Core/"},{name:"v-5f171cb0",path:"/blog/tags/RPC/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f171cb0").then(n)},meta:{pid:"tags",id:"RPC"}},{path:"/blog/tags/RPC/index.html",redirect:"/blog/tags/RPC/"},{name:"v-4696dfd8",path:"/blog/tags/Wallet/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4696dfd8").then(n)},meta:{pid:"tags",id:"Wallet"}},{path:"/blog/tags/Wallet/index.html",redirect:"/blog/tags/Wallet/"},{name:"v-c711ccde",path:"/blog/tags/bdk-cli/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-c711ccde").then(n)},meta:{pid:"tags",id:"bdk-cli"}},{path:"/blog/tags/bdk-cli/index.html",redirect:"/blog/tags/bdk-cli/"},{name:"v-655ee4a0",path:"/blog/tags/multi-sig/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-655ee4a0").then(n)},meta:{pid:"tags",id:"multi-sig"}},{path:"/blog/tags/multi-sig/index.html",redirect:"/blog/tags/multi-sig/"},{name:"v-e646a928",path:"/blog/tags/basics/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-e646a928").then(n)},meta:{pid:"tags",id:"basics"}},{path:"/blog/tags/basics/index.html",redirect:"/blog/tags/basics/"},{name:"v-1fb58ffb",path:"/blog/tags/novice/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-1fb58ffb").then(n)},meta:{pid:"tags",id:"novice"}},{path:"/blog/tags/novice/index.html",redirect:"/blog/tags/novice/"},{name:"v-c4494744",path:"/blog/tags/architecture/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-c4494744").then(n)},meta:{pid:"tags",id:"architecture"}},{path:"/blog/tags/architecture/index.html",redirect:"/blog/tags/architecture/"},{name:"v-876cfade",path:"/blog/tags/BDK-RN/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-876cfade").then(n)},meta:{pid:"tags",id:"BDK-RN"}},{path:"/blog/tags/BDK-RN/index.html",redirect:"/blog/tags/BDK-RN/"},{name:"v-3acc51dc",path:"/blog/tags/Development/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-3acc51dc").then(n)},meta:{pid:"tags",id:"Development"}},{path:"/blog/tags/Development/index.html",redirect:"/blog/tags/Development/"},{name:"v-650ae784",path:"/blog/tags/Architecture/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-650ae784").then(n)},meta:{pid:"tags",id:"Architecture"}},{path:"/blog/tags/Architecture/index.html",redirect:"/blog/tags/Architecture/"},{name:"v-5ef73f54",path:"/blog/tags/tor/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5ef73f54").then(n)},meta:{pid:"tags",id:"tor"}},{path:"/blog/tags/tor/index.html",redirect:"/blog/tags/tor/"},{name:"v-39437010",path:"/blog/tags/wallet/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-39437010").then(n)},meta:{pid:"tags",id:"wallet"}},{path:"/blog/tags/wallet/index.html",redirect:"/blog/tags/wallet/"},{name:"v-7c8563fd",path:"/blog/tags/blockchain/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-7c8563fd").then(n)},meta:{pid:"tags",id:"blockchain"}},{path:"/blog/tags/blockchain/index.html",redirect:"/blog/tags/blockchain/"},{name:"v-1296a8fa",path:"/blog/tags/bindings/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-1296a8fa").then(n)},meta:{pid:"tags",id:"bindings"}},{path:"/blog/tags/bindings/index.html",redirect:"/blog/tags/bindings/"},{name:"v-baacba64",path:"/blog/tags/compact_filters/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-baacba64").then(n)},meta:{pid:"tags",id:"compact_filters"}},{path:"/blog/tags/compact_filters/index.html",redirect:"/blog/tags/compact_filters/"},{name:"v-75ccd5f2",path:"/blog/tags/BIP157/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-75ccd5f2").then(n)},meta:{pid:"tags",id:"BIP157"}},{path:"/blog/tags/BIP157/index.html",redirect:"/blog/tags/BIP157/"},{name:"v-4fed1c23",path:"/blog/tags/Neutrino/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4fed1c23").then(n)},meta:{pid:"tags",id:"Neutrino"}},{path:"/blog/tags/Neutrino/index.html",redirect:"/blog/tags/Neutrino/"},{name:"v-a9e0285e",path:"/blog/tags/guide/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-a9e0285e").then(n)},meta:{pid:"tags",id:"guide"}},{path:"/blog/tags/guide/index.html",redirect:"/blog/tags/guide/"},{name:"v-733ed37c",path:"/blog/tags/descriptor/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-733ed37c").then(n)},meta:{pid:"tags",id:"descriptor"}},{path:"/blog/tags/descriptor/index.html",redirect:"/blog/tags/descriptor/"},{name:"v-1144be8a",path:"/blog/tags/paper wallets/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-1144be8a").then(n)},meta:{pid:"tags",id:"paper wallets"}},{path:"/blog/tags/paper wallets/index.html",redirect:"/blog/tags/paper wallets/"},{name:"v-915f8322",path:"/blog/tags/bitcoin/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-915f8322").then(n)},meta:{pid:"tags",id:"bitcoin"}},{path:"/blog/tags/bitcoin/index.html",redirect:"/blog/tags/bitcoin/"},{name:"v-bf53d4d4",path:"/blog/tags/React Native/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-bf53d4d4").then(n)},meta:{pid:"tags",id:"React Native"}},{path:"/blog/tags/React Native/index.html",redirect:"/blog/tags/React Native/"},{name:"v-5f023740",path:"/blog/tags/iOS/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f023740").then(n)},meta:{pid:"tags",id:"iOS"}},{path:"/blog/tags/iOS/index.html",redirect:"/blog/tags/iOS/"},{name:"v-414e735e",path:"/blog/tags/Android/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-414e735e").then(n)},meta:{pid:"tags",id:"Android"}},{path:"/blog/tags/Android/index.html",redirect:"/blog/tags/Android/"},{name:"v-2c94bf22",path:"/blog/tags/mobile/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-2c94bf22").then(n)},meta:{pid:"tags",id:"mobile"}},{path:"/blog/tags/mobile/index.html",redirect:"/blog/tags/mobile/"},{name:"v-dd212a9e",path:"/blog/tags/bdk-rn/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-dd212a9e").then(n)},meta:{pid:"tags",id:"bdk-rn"}},{path:"/blog/tags/bdk-rn/index.html",redirect:"/blog/tags/bdk-rn/"},{name:"v-5f07f0f8",path:"/blog/tags/bdk/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f07f0f8").then(n)},meta:{pid:"tags",id:"bdk"}},{path:"/blog/tags/bdk/index.html",redirect:"/blog/tags/bdk/"},{name:"v-07eeb15e",path:"/blog/tags/Flutter/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-07eeb15e").then(n)},meta:{pid:"tags",id:"Flutter"}},{path:"/blog/tags/Flutter/index.html",redirect:"/blog/tags/Flutter/"},{name:"v-5f0447f2",path:"/blog/tags/fee/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5f0447f2").then(n)},meta:{pid:"tags",id:"fee"}},{path:"/blog/tags/fee/index.html",redirect:"/blog/tags/fee/"},{name:"v-e2317b12",path:"/blog/tags/machine learning/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-e2317b12").then(n)},meta:{pid:"tags",id:"machine learning"}},{path:"/blog/tags/machine learning/index.html",redirect:"/blog/tags/machine learning/"},{name:"v-57f3a168",path:"/blog/tags/taproot/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-57f3a168").then(n)},meta:{pid:"tags",id:"taproot"}},{path:"/blog/tags/taproot/index.html",redirect:"/blog/tags/taproot/"},{name:"v-ef7c3fa2",path:"/blog/tags/miniscript/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-ef7c3fa2").then(n)},meta:{pid:"tags",id:"miniscript"}},{path:"/blog/tags/miniscript/index.html",redirect:"/blog/tags/miniscript/"},{name:"v-640144b2",path:"/blog/tags/Hardware Wallets/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-640144b2").then(n)},meta:{pid:"tags",id:"Hardware Wallets"}},{path:"/blog/tags/Hardware Wallets/index.html",redirect:"/blog/tags/Hardware Wallets/"},{name:"v-79c3de4b",path:"/blog/tags/getting started/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-79c3de4b").then(n)},meta:{pid:"tags",id:"getting started"}},{path:"/blog/tags/getting started/index.html",redirect:"/blog/tags/getting started/"},{name:"v-3fee41ed",path:"/blog/tags/rust/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-3fee41ed").then(n)},meta:{pid:"tags",id:"rust"}},{path:"/blog/tags/rust/index.html",redirect:"/blog/tags/rust/"},{name:"v-01a03a08",path:"/blog/tags/bitcoin-cli/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-01a03a08").then(n)},meta:{pid:"tags",id:"bitcoin-cli"}},{path:"/blog/tags/bitcoin-cli/index.html",redirect:"/blog/tags/bitcoin-cli/"},{name:"v-74edfe92",path:"/blog/tags/coin selection/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-74edfe92").then(n)},meta:{pid:"tags",id:"coin selection"}},{path:"/blog/tags/coin selection/index.html",redirect:"/blog/tags/coin selection/"},{name:"v-4e62fa1c",path:"/blog/tags/development/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4e62fa1c").then(n)},meta:{pid:"tags",id:"development"}},{path:"/blog/tags/development/index.html",redirect:"/blog/tags/development/"},{name:"v-0159a747",path:"/blog/tags/summer of bitcoin/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-0159a747").then(n)},meta:{pid:"tags",id:"summer of bitcoin"}},{path:"/blog/tags/summer of bitcoin/index.html",redirect:"/blog/tags/summer of bitcoin/"},{name:"v-0755ed11",path:"/blog/tags/security/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-0755ed11").then(n)},meta:{pid:"tags",id:"security"}},{path:"/blog/tags/security/index.html",redirect:"/blog/tags/security/"},{name:"v-543950a6",path:"/blog/tags/release/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-543950a6").then(n)},meta:{pid:"tags",id:"release"}},{path:"/blog/tags/release/index.html",redirect:"/blog/tags/release/"},{name:"v-a354115e",path:"/blog/author/Steve Myers/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-a354115e").then(n)},meta:{pid:"author",id:"Steve Myers"}},{path:"/blog/author/Steve Myers/index.html",redirect:"/blog/author/Steve Myers/"},{name:"v-22d0e252",path:"/blog/author/Daniela Brozzoni/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-22d0e252").then(n)},meta:{pid:"author",id:"Daniela Brozzoni"}},{path:"/blog/author/Daniela Brozzoni/index.html",redirect:"/blog/author/Daniela Brozzoni/"},{name:"v-5d54001e",path:"/blog/author/thunderbiscuit/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-5d54001e").then(n)},meta:{pid:"author",id:"thunderbiscuit"}},{path:"/blog/author/thunderbiscuit/index.html",redirect:"/blog/author/thunderbiscuit/"},{name:"v-82e16b5c",path:"/blog/author/Rajarshi Maitra/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-82e16b5c").then(n)},meta:{pid:"author",id:"Rajarshi Maitra"}},{path:"/blog/author/Rajarshi Maitra/index.html",redirect:"/blog/author/Rajarshi Maitra/"},{name:"v-3e6950f4",path:"/blog/author/waterst0ne/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-3e6950f4").then(n)},meta:{pid:"author",id:"waterst0ne"}},{path:"/blog/author/waterst0ne/index.html",redirect:"/blog/author/waterst0ne/"},{name:"v-600b5b28",path:"/blog/author/Lloyd Fournier/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-600b5b28").then(n)},meta:{pid:"author",id:"Lloyd Fournier"}},{path:"/blog/author/Lloyd Fournier/index.html",redirect:"/blog/author/Lloyd Fournier/"},{name:"v-37829241",path:"/blog/author/Bitcoin Zavior/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-37829241").then(n)},meta:{pid:"author",id:"Bitcoin Zavior"}},{path:"/blog/author/Bitcoin Zavior/index.html",redirect:"/blog/author/Bitcoin Zavior/"},{name:"v-d2b26530",path:"/blog/author/rorp/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-d2b26530").then(n)},meta:{pid:"author",id:"rorp"}},{path:"/blog/author/rorp/index.html",redirect:"/blog/author/rorp/"},{name:"v-624fd61e",path:"/blog/author/Riccardo Casatta/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-624fd61e").then(n)},meta:{pid:"author",id:"Riccardo Casatta"}},{path:"/blog/author/Riccardo Casatta/index.html",redirect:"/blog/author/Riccardo Casatta/"},{name:"v-6b564fb4",path:"/blog/author/Gabriele Domenichini/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-6b564fb4").then(n)},meta:{pid:"author",id:"Gabriele Domenichini"}},{path:"/blog/author/Gabriele Domenichini/index.html",redirect:"/blog/author/Gabriele Domenichini/"},{name:"v-ad00c09c",path:"/blog/author/Alekos Filini/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-ad00c09c").then(n)},meta:{pid:"author",id:"Alekos Filini"}},{path:"/blog/author/Alekos Filini/index.html",redirect:"/blog/author/Alekos Filini/"},{name:"v-4eeab648",path:"/blog/author/Wszdexdrf/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-4eeab648").then(n)},meta:{pid:"author",id:"Wszdexdrf"}},{path:"/blog/author/Wszdexdrf/index.html",redirect:"/blog/author/Wszdexdrf/"},{name:"v-91c10894",path:"/blog/author/Sandipan Dey/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-91c10894").then(n)},meta:{pid:"author",id:"Sandipan Dey"}},{path:"/blog/author/Sandipan Dey/index.html",redirect:"/blog/author/Sandipan Dey/"},{name:"v-a0d840b0",path:"/blog/author/César Alvarez Vallero/",component:Fc,beforeEnter:(t,e,n)=>{dc("FrontmatterPagination","v-a0d840b0").then(n)},meta:{pid:"author",id:"César Alvarez Vallero"}},{path:"/blog/author/César Alvarez Vallero/index.html",redirect:"/blog/author/César Alvarez Vallero/"},{name:"v-c3507bb6",path:"/blog/page/2/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-c3507bb6").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/2/index.html",redirect:"/blog/page/2/"},{name:"v-c3507b78",path:"/blog/page/3/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-c3507b78").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/3/index.html",redirect:"/blog/page/3/"},{name:"v-c3507b3a",path:"/blog/page/4/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-c3507b3a").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/4/index.html",redirect:"/blog/page/4/"},{name:"v-73be14ce",path:"/blog/tags/BDK/page/2/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-73be14ce").then(n)},meta:{pid:"tags",id:"BDK"}},{path:"/blog/tags/BDK/page/2/index.html",redirect:"/blog/tags/BDK/page/2/"},{name:"v-5f2ac9cb",path:"/blog/author/Alekos Filini/page/2/",component:Fc,beforeEnter:(t,e,n)=>{dc("DirectoryPagination","v-5f2ac9cb").then(n)},meta:{pid:"author",id:"Alekos Filini"}},{path:"/blog/author/Alekos Filini/page/2/index.html",redirect:"/blog/author/Alekos Filini/page/2/"},{path:"*",component:Fc}],Ec={title:"Bitcoin Dev Kit Documentation",description:"The Bitcoin Dev Kit (BDK) project (originally called Magical Bitcoin 🧙) aims to build a collection of tools and libraries that are designed to be a solid foundation for cross platform Bitcoin wallets, along with a fully working reference implementation wallet called Magical Bitcoin.",base:"/",headTags:[["meta",{name:"viewport",content:"width=device-width,initial-scale=1.0"}],["link",{rel:"preload",href:"/fonts/ibm-plex-mono-400.woff2",as:"font",crossorigin:!0}],["link",{rel:"apple-touch-icon",sizes:"180x180",href:"/img/favicon/apple-touch-icon.png"}],["link",{rel:"manifest",href:"/site.webmanifest"}],["link",{rel:"stylesheet",href:"/css/variables.css"}],["link",{name:"msapplication-config",content:"/browserconfig.xml"}],["link",{name:"msapplication-TileColor",content:"#ffffff"}],["link",{name:"theme-color",content:"#ffffff"}]],pages:[{title:"Home",frontmatter:{home:!0,heroText:"Bitcoin Dev Kit",tagline:"With BDK, you can seamlessly build cross platform mobile wallets",actionText:"Get started",actionLink:"/getting-started/",features:[{title:"Customizable",details:"Designed from the ground up to be easily customized to your application needs: blockchain backends, databases, signers, coin selection, key management and more.",image:"customizable"},{title:"Focus on what matters",details:"All of the low-level Bitcoin logic is handled by us, so you can focus on crafting custom-tailored user experiences.",image:"focus"},{title:"High performance & compact",details:"As lightweight as you need it to be and optimized to run on all modern-day embedded devices such as mobile phones, IoT devices, PoS terminals and more.",image:"mobile"}],meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"With BDK, you can seamlessly build cross platform mobile wallets"},{property:"og:description",content:"We are building native API's for C, Swift, Java & Kotlin so you can easily integrate Bitcoin in your preferred programming language on mobile."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"With BDK, you can seamlessly build cross platform mobile wallets"},{name:"twitter:description",content:"We are building native API's for C, Swift, Java & Kotlin so you can easily integrate Bitcoin in your preferred programming language on mobile."},{name:"twitter:url",content:"https://bitcoindevkit.org/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/",relativePath:"README.md",key:"v-330a32a2",path:"/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"2023 Q4 Project Update",frontmatter:{title:"2023 Q4 Project Update",description:"2023 Q4 update on the BDK project's progress.",authors:["Steve Myers","Daniela Brozzoni"],date:"2024-02-20",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-02-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2023 Q4 Project Update"},{property:"og:description",content:"2023 Q4 update on the BDK project's progress."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2023_q4_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2023 Q4 Project Update"},{name:"twitter:description",content:"2023 Q4 update on the BDK project's progress."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2023_q4_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2023_q4_update.html",relativePath:"_blog/2023_q4_update.md",key:"v-2c450c3f",path:"/blog/_2023-q4-update/",headers:[{level:3,title:"This Post",slug:"this-post"},{level:3,title:"End of Year Review",slug:"end-of-year-review"},{level:3,title:"Core BDK",slug:"core-bdk"},{level:3,title:"BDK-FFI",slug:"bdk-ffi"},{level:3,title:"BDK contributors spotlight",slug:"bdk-contributors-spotlight"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"2024 Q1 Project Update",frontmatter:{title:"2024 Q1 Project Update",description:"2024 Q1 update on the BDK project's progress.",authors:["Steve Myers"],date:"2024-03-21",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-03-21T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2024 Q1 Project Update"},{property:"og:description",content:"2024 Q1 update on the BDK project's progress."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q1_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2024 Q1 Project Update"},{name:"twitter:description",content:"2024 Q1 update on the BDK project's progress."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q1_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q1_update.html",relativePath:"_blog/2024_q1_update.md",key:"v-5e744cf7",path:"/blog/_2024-q1-update/",headers:[{level:3,title:"Core BDK",slug:"core-bdk"},{level:3,title:"BDK-FFI",slug:"bdk-ffi"},{level:3,title:"Plans for Next Quarter",slug:"plans-for-next-quarter"},{level:3,title:"BDK contributors spotlight",slug:"bdk-contributors-spotlight"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Call for Proposals: Full-Time Open Source Rust Maintainer",frontmatter:{title:"Call for Proposals: Full-Time Open Source Rust Maintainer",description:"2024 Q3 Request for Applications for a Full-Time Open Source Rust Maintainer Grant",authors:["Steve Myers"],date:"2024-08-20",tags:["BDK","grants"],draft:!1,meta:[{property:"article:published_time",content:"2024-08-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Call for Proposals: Full-Time Open Source Rust Maintainer"},{property:"og:description",content:"2024 Q3 Request for Applications for a Full-Time Open Source Rust Maintainer Grant"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q3_rfp_rust_maintainer/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Call for Proposals: Full-Time Open Source Rust Maintainer"},{name:"twitter:description",content:"2024 Q3 Request for Applications for a Full-Time Open Source Rust Maintainer Grant"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q3_rfp_rust_maintainer/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, grants"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"grants"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q3_rfp_rust_maintainer.html",relativePath:"_blog/2024_q3_rfp_rust_maintainer.md",key:"v-bac76d8e",path:"/blog/_2024-q3-rfp-rust-maintainer/",headers:[{level:2,title:"Grant Overview",slug:"grant-overview"},{level:2,title:"Key Requirements",slug:"key-requirements"},{level:2,title:"Desired Qualifications",slug:"desired-qualifications"},{level:2,title:"Proposal Guidelines",slug:"proposal-guidelines"},{level:2,title:"Evaluation Criteria",slug:"evaluation-criteria"},{level:2,title:"Submission Process",slug:"submission-process"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"2024 Q2 Update: What Have We Been Up To?",frontmatter:{title:"2024 Q2 Update: What Have We Been Up To?",description:"2024 Q2 Update on the Bitcoin Dev Kit Project",authors:["thunderbiscuit"],date:"2024-07-01",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-07-01T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2024 Q2 Update: What Have We Been Up To?"},{property:"og:description",content:"2024 Q2 Update on the Bitcoin Dev Kit Project"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q2_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2024 Q2 Update: What Have We Been Up To?"},{name:"twitter:description",content:"2024 Q2 Update on the Bitcoin Dev Kit Project"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q2_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q2_update.html",relativePath:"_blog/2024_q2_update.md",key:"v-609f26f9",path:"/blog/_2024-q2-update/",headers:[{level:3,title:"Our Grantees in Action",slug:"our-grantees-in-action"},{level:3,title:"BDK in the Wild",slug:"bdk-in-the-wild"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"BDK wallet with Bitcoin core RPC",frontmatter:{title:"BDK wallet with Bitcoin core RPC ",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:!0,draft:!1,meta:[{property:"article:published_time",content:"2021-08-21T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK wallet with Bitcoin core RPC"},{property:"og:description",content:"Tutorial showing usage of Bitcoin core backend with BDK wallet"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/Bitcoin_Core_RPC_Demo/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK wallet with Bitcoin core RPC"},{name:"twitter:description",content:"Tutorial showing usage of Bitcoin core backend with BDK wallet"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/Bitcoin_Core_RPC_Demo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, BDK, Bitcoin Core, RPC, Wallet"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"Bitcoin Core"},{property:"article:tag",content:"RPC"},{property:"article:tag",content:"Wallet"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/Bitcoin_Core_RPC_Demo.html",relativePath:"_blog/Bitcoin_Core_RPC_Demo.md",key:"v-7c0c45f9",path:"/blog/bitcoin-core-rpc-demo/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Prerequisite",slug:"prerequisite"},{level:2,title:"Setting Up",slug:"setting-up"},{level:2,title:"Setting dependencies",slug:"setting-dependencies"},{level:2,title:"Getting Descriptors",slug:"getting-descriptors"},{level:2,title:"Talking to Bitcoin Core Programmatically",slug:"talking-to-bitcoin-core-programmatically"},{level:2,title:"Get some balance in core wallet.",slug:"get-some-balance-in-core-wallet"},{level:2,title:"Setup the BDK wallet",slug:"setup-the-bdk-wallet"},{level:2,title:"Sending Sats Around",slug:"sending-sats-around"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"bdk-cli basics multi-sig 2 of 3 tutorial",frontmatter:{title:"bdk-cli basics multi-sig 2 of 3 tutorial",description:"Tutorial using command-line to create a 2 of 3 multi-sig Wallet and Spend",authors:["waterst0ne"],date:"2022-10-17",tags:["tutorial","bdk-cli","multi-sig"],hidden:!1,draft:!1,meta:[{property:"article:published_time",content:"2022-10-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"bdk-cli basics multi-sig 2 of 3 tutorial"},{property:"og:description",content:"Tutorial using command-line to create a 2 of 3 multi-sig Wallet and Spend"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk-cli_basics_multisig_2of3/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"bdk-cli basics multi-sig 2 of 3 tutorial"},{name:"twitter:description",content:"Tutorial using command-line to create a 2 of 3 multi-sig Wallet and Spend"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk-cli_basics_multisig_2of3/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, bdk-cli, multi-sig"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"multi-sig"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk-cli_basics_multisig_2of3.html",relativePath:"_blog/bdk-cli_basics_multisig_2of3.md",key:"v-8bd632d6",path:"/blog/bdk-cli-basics-multisig-2of3/",headers:[{level:2,title:"2-of-3 Multi-Signature Descriptor Wallet using bdk-cli",slug:"2-of-3-multi-signature-descriptor-wallet-using-bdk-cli"},{level:2,title:"Overview of the tutorial",slug:"overview-of-the-tutorial"},{level:2,title:"Step 1: Generate the XPRVs (Extended-Keys) and Save to environment variables",slug:"step-1-generate-the-xprvs-extended-keys-and-save-to-environment-variables"},{level:3,title:"1a: Verify XPRV environment variables are Active",slug:"1a-verify-xprv-environment-variables-are-active"},{level:2,title:"Step 2: Generate XPUBs (Extended Public Keys) & Save to environment variables",slug:"step-2-generate-xpubs-extended-public-keys-save-to-environment-variables"},{level:3,title:"2a: Verify XPUB environment variables",slug:"2a-verify-xpub-environment-variables"},{level:2,title:"Step 3: Create Single-Wallet Descriptors",slug:"step-3-create-single-wallet-descriptors"},{level:2,title:"Step 4: Create Multi-Sig-Descriptor Wallets",slug:"step-4-create-multi-sig-descriptor-wallets"},{level:3,title:"4a: Verify Multi-Sig-Descriptor environment variables are active",slug:"4a-verify-multi-sig-descriptor-environment-variables-are-active"},{level:2,title:"Step 5: Generate Receive Address by using Multi-Sig-Descriptor Wallets",slug:"step-5-generate-receive-address-by-using-multi-sig-descriptor-wallets"},{level:2,title:"Step 6: Send Testnet Bitcoin to the newly created receive-address",slug:"step-6-send-testnet-bitcoin-to-the-newly-created-receive-address"},{level:2,title:"Step 7: Sync one of the Multi-Sig Wallets",slug:"step-7-sync-one-of-the-multi-sig-wallets"},{level:2,title:"Step 8: Check Balance Multi-Sig Wallets",slug:"step-8-check-balance-multi-sig-wallets"},{level:2,title:"Step 9: Check Multi-Sig Policies on Descriptor Wallet",slug:"step-9-check-multi-sig-policies-on-descriptor-wallet"},{level:3,title:"SpendingPolicyRequired for complex descriptors",slug:"spendingpolicyrequired-for-complex-descriptors"},{level:2,title:"Step 10: Create a Transaction (PSBT)",slug:"step-10-create-a-transaction-psbt"},{level:3,title:"Export UNSIGNED_PSBT to environment variable",slug:"export-unsigned-psbt-to-environment-variable"},{level:3,title:"Verify UNSIGNED_PSBT environment variable",slug:"verify-unsigned-psbt-environment-variable"},{level:2,title:"Step 11: SIGN the Transaction",slug:"step-11-sign-the-transaction"},{level:3,title:"1st Wallet Signs the transaction",slug:"1st-wallet-signs-the-transaction"},{level:3,title:"2nd Wallet Signs the transaction",slug:"2nd-wallet-signs-the-transaction"},{level:2,title:"Step 12: Broadcast Transaction",slug:"step-12-broadcast-transaction"},{level:3,title:"Verify Transaction",slug:"verify-transaction"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"2024 Q3 Update: What Have We Been Up To?",frontmatter:{title:"2024 Q3 Update: What Have We Been Up To?",description:"2024 Q3 Update on the Bitcoin Dev Kit Project",authors:["thunderbiscuit"],date:"2024-11-07",tags:["BDK","project"],draft:!1,meta:[{property:"article:published_time",content:"2024-11-07T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"2024 Q3 Update: What Have We Been Up To?"},{property:"og:description",content:"2024 Q3 Update on the Bitcoin Dev Kit Project"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/2024_q3_update/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"2024 Q3 Update: What Have We Been Up To?"},{name:"twitter:description",content:"2024 Q3 Update on the Bitcoin Dev Kit Project"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/2024_q3_update/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, project"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"project"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/2024_q3_update.html",relativePath:"_blog/2024_q3_update.md",key:"v-62ca00fb",path:"/blog/_2024-q3-update/",headers:[{level:3,title:"Our Grantees in Action",slug:"our-grantees-in-action"},{level:3,title:"BDK in the Wild",slug:"bdk-in-the-wild"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Command Line introduction to Bitcoin Wallet Development using bdk-cli",frontmatter:{title:"Command Line introduction to Bitcoin Wallet Development using bdk-cli",description:"Intro to bdk-cli and wallet dev",authors:["waterst0ne"],date:"2022-09-22",tags:["bdk-cli","basics","novice"],meta:[{property:"article:published_time",content:"2022-09-22T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Command Line introduction to Bitcoin Wallet Development using bdk-cli"},{property:"og:description",content:"Intro to bdk-cli and wallet dev"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_cli_basics/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Command Line introduction to Bitcoin Wallet Development using bdk-cli"},{name:"twitter:description",content:"Intro to bdk-cli and wallet dev"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_cli_basics/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bdk-cli, basics, novice"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"basics"},{property:"article:tag",content:"novice"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_cli_basics.html",relativePath:"_blog/bdk_cli_basics.md",key:"v-0f4d5d15",path:"/blog/bdk-cli-basics/",headers:[{level:2,title:"Tutorial Goals",slug:"tutorial-goals"},{level:2,title:"A few things before you begin:",slug:"a-few-things-before-you-begin"},{level:3,title:"Outline of Tutorial and Installation notes:",slug:"outline-of-tutorial-and-installation-notes"},{level:3,title:"Brief Outline of Tutorial",slug:"brief-outline-of-tutorial"},{level:3,title:"Rust and Cargo installation:",slug:"rust-and-cargo-installation"},{level:3,title:"bdk-cli installation:",slug:"bdk-cli-installation"},{level:3,title:"Emoji Legend:",slug:"emoji-legend"},{level:2,title:"Step 0: Check Version of bdk-cli",slug:"step-0-check-version-of-bdk-cli"},{level:3,title:"Preview of bdk-cli help menu",slug:"preview-of-bdk-cli-help-menu"},{level:2,title:"Step 1: Seed Generate",slug:"step-1-seed-generate"},{level:3,title:"1a: Mnemonic word-list + XPRV (Extended Private Key) :key:",slug:"1a-mnemonic-word-list-xprv-extended-private-key-"},{level:3,title:"1b: Save XPRV (Extended Private Key) into environment variable",slug:"1b-save-xprv-extended-private-key-into-environment-variable"},{level:3,title:"1c: Verify environment variable XPRV_00 is active",slug:"1c-verify-environment-variable-xprv-00-is-active"},{level:3,title:"1d: Create Descriptor and Save into environment variable",slug:"1d-create-descriptor-and-save-into-environment-variable"},{level:3,title:"1e: Verify environment variable my_descriptor is active",slug:"1e-verify-environment-variable-my-descriptor-is-active"},{level:2,title:"Step 2: Generate Receive-Address",slug:"step-2-generate-receive-address"},{level:2,title:"Step 3: Send testnet bitcoin to the newly created receive-address",slug:"step-3-send-testnet-bitcoin-to-the-newly-created-receive-address"},{level:2,title:"Step 4: Sync the wallet",slug:"step-4-sync-the-wallet"},{level:2,title:"Step 5: Check the balance",slug:"step-5-check-the-balance"},{level:2,title:"Step 6: Create Transaction (PSBT)",slug:"step-6-create-transaction-psbt"},{level:3,title:"6a: export PSBT to environment-variable",slug:"6a-export-psbt-to-environment-variable"},{level:2,title:"Step 7: Sign Transaction (PSBT)",slug:"step-7-sign-transaction-psbt"},{level:3,title:"7a: export signed psbt to environment variable",slug:"7a-export-signed-psbt-to-environment-variable"},{level:2,title:"Step 8: Broadcast Transaction",slug:"step-8-broadcast-transaction"},{level:2,title:"Resources",slug:"resources"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"bdk_core: a new architecture for the Bitcoin Dev Kit",frontmatter:{title:"`bdk_core`: a new architecture for the Bitcoin Dev Kit",description:"A new architecture for the Bitcoin Dev Kit",authors:["Lloyd Fournier"],date:"2022-05-09",tags:["architecture"],draft:!1,meta:[{property:"article:published_time",content:"2022-05-09T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"bdk_core: a new architecture for the Bitcoin Dev Kit"},{property:"og:description",content:"A new architecture for the Bitcoin Dev Kit"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_core_pt1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"bdk_core: a new architecture for the Bitcoin Dev Kit"},{name:"twitter:description",content:"A new architecture for the Bitcoin Dev Kit"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_core_pt1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"architecture"},{property:"article:tag",content:"architecture"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_core_pt1.html",relativePath:"_blog/bdk_core_pt1.md",key:"v-2cebe183",path:"/blog/bdk-core-pt1/",headers:[{level:2,title:"The separation of policy and mechanism",slug:"the-separation-of-policy-and-mechanism"},{level:2,title:"A syncing mechansim without the policy",slug:"a-syncing-mechansim-without-the-policy"},{level:3,title:"A general syncing mechanism",slug:"a-general-syncing-mechanism"},{level:3,title:"How to store and index transactions",slug:"how-to-store-and-index-transactions"},{level:3,title:"Rolling back, rolling forward and syncing to disk",slug:"rolling-back-rolling-forward-and-syncing-to-disk"},{level:2,title:"Examples",slug:"examples"},{level:3,title:"Doing an initial sync of a descriptor that may already contain coins",slug:"doing-an-initial-sync-of-a-descriptor-that-may-already-contain-coins"},{level:3,title:"Doing a sync of a wallet after you already have sync'd",slug:"doing-a-sync-of-a-wallet-after-you-already-have-syncd"},{level:3,title:"Updating state when you get the data in real time",slug:"updating-state-when-you-get-the-data-in-real-time"},{level:2,title:"Feedback",slug:"feedback"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"bdk-rn: Behind the scenes",frontmatter:{title:"`bdk-rn`: Behind the scenes",description:"bdk-rn: React Native version of BitcoinDevKit. Insight into how bdk-rn was developed",authors:["Bitcoin Zavior"],date:"2022-07-10",tags:["BDK-RN","Development","Architecture"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-07-10T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"bdk-rn: Behind the scenes"},{property:"og:description",content:"bdk-rn: React Native version of BitcoinDevKit. Insight into how bdk-rn was developed"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_rn_making_of/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"bdk-rn: Behind the scenes"},{name:"twitter:description",content:"bdk-rn: React Native version of BitcoinDevKit. Insight into how bdk-rn was developed"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_rn_making_of/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK-RN, Development, Architecture"},{property:"article:tag",content:"BDK-RN"},{property:"article:tag",content:"Development"},{property:"article:tag",content:"Architecture"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_rn_making_of.html",relativePath:"_blog/bdk_rn_making_of.md",key:"v-3eaa044d",path:"/blog/bdk-rn-making-of/",headers:[{level:2,title:"React Native Architecture",slug:"react-native-architecture"},{level:2,title:"Native Integration",slug:"native-integration"},{level:2,title:"Android Module",slug:"android-module"},{level:2,title:"References",slug:"references"},{level:2,title:"Feedback",slug:"feedback"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Using BDK with Tor",frontmatter:{title:"Using BDK with Tor",description:"How to integrate Tor client to sync BDK wallet with tor enabled blockchain service",authors:["rorp"],date:"2023-01-03",tags:["tutorial","tor","wallet","blockchain"],meta:[{property:"article:published_time",content:"2023-01-03T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Using BDK with Tor"},{property:"og:description",content:"How to integrate Tor client to sync BDK wallet with tor enabled blockchain service"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bdk_with_tor/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Using BDK with Tor"},{name:"twitter:description",content:"How to integrate Tor client to sync BDK wallet with tor enabled blockchain service"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bdk_with_tor/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, tor, wallet, blockchain"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"tor"},{property:"article:tag",content:"wallet"},{property:"article:tag",content:"blockchain"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bdk_with_tor.html",relativePath:"_blog/bdk_with_tor.md",key:"v-353b78e1",path:"/blog/bdk-with-tor/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Prerequisite",slug:"prerequisite"},{level:2,title:"Setting Up",slug:"setting-up"},{level:2,title:"ElectrumBlockchain",slug:"electrumblockchain"},{level:2,title:"Blocking EsploraBlockchain",slug:"blocking-esplorablockchain"},{level:2,title:"Asynchronous EsploraBlockchain",slug:"asynchronous-esplorablockchain"},{level:2,title:"CompactFiltersBlockchain",slug:"compactfiltersblockchain"},{level:2,title:"Integrated Tor daemon",slug:"integrated-tor-daemon"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"BDK's Scope and Approach to Rust Bindings",frontmatter:{title:"BDK's Scope and Approach to Rust Bindings",description:"An outline of BDK's approach to language bindings and how we intend on supporting others build their own.",authors:["thunderbiscuit"],date:"2023-06-02",tags:["BDK","bindings"],meta:[{property:"article:published_time",content:"2023-06-02T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK's Scope and Approach to Rust Bindings"},{property:"og:description",content:"An outline of BDK's approach to language bindings and how we intend on supporting others build their own."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/bindings-scope/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK's Scope and Approach to Rust Bindings"},{name:"twitter:description",content:"An outline of BDK's approach to language bindings and how we intend on supporting others build their own."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/bindings-scope/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, bindings"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"bindings"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/bindings-scope.html",relativePath:"_blog/bindings-scope.md",key:"v-3875825f",path:"/blog/bindings-scope/",headers:[{level:2,title:"Current architecture",slug:"current-architecture"},{level:2,title:"Moving forward: building a family of libraries",slug:"moving-forward-building-a-family-of-libraries"},{level:2,title:"Why can't we just build one big BDK library with everything in it?",slug:"why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"},{level:2,title:"Are you looking to build Rust bindings yourself?",slug:"are-you-looking-to-build-rust-bindings-yourself"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"BDK wallet as a BIP157 SPV light client",frontmatter:{title:"BDK wallet as a BIP157 SPV light client",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"],meta:[{property:"article:published_time",content:"2021-06-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK wallet as a BIP157 SPV light client"},{property:"og:description",content:"Tutorial showing usage of compact filters (BIP157) using bdk-cli command line tools"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/compact_filters_demo/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK wallet as a BIP157 SPV light client"},{name:"twitter:description",content:"Tutorial showing usage of compact filters (BIP157) using bdk-cli command line tools"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/compact_filters_demo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, BDK, bdk-cli, compact_filters, BIP157, Neutrino"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"compact_filters"},{property:"article:tag",content:"BIP157"},{property:"article:tag",content:"Neutrino"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/compact_filters_demo.html",relativePath:"_blog/compact_filters_demo.md",key:"v-07ff1843",path:"/blog/compact-filters-demo/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:3,title:"Compact Filters:",slug:"compact-filters"},{level:3,title:"BDK and Compact filters",slug:"bdk-and-compact-filters"},{level:3,title:"bdk-cli",slug:"bdk-cli"},{level:2,title:"Tutorial Scope",slug:"tutorial-scope"},{level:2,title:"Prerequisites",slug:"prerequisites"},{level:3,title:"Install and run bitcoind",slug:"install-and-run-bitcoind"},{level:3,title:"Install and run bdk-cli",slug:"install-and-run-bdk-cli"},{level:2,title:"Tutorial",slug:"tutorial"},{level:3,title:"Bitcoin Core Wallet Generation",slug:"bitcoin-core-wallet-generation"},{level:3,title:"BDK Wallet Generation",slug:"bdk-wallet-generation"},{level:3,title:"Recieve Coins",slug:"recieve-coins"},{level:3,title:"Creating a transaction.",slug:"creating-a-transaction"},{level:3,title:"Sign and Broadcast the transaction",slug:"sign-and-broadcast-the-transaction"},{level:3,title:"Confirming the Transaction",slug:"confirming-the-transaction"},{level:3,title:"Shutdown Docker",slug:"shutdown-docker"},{level:2,title:"End Words",slug:"end-words"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Making Descriptor-based paper wallets",frontmatter:{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"],meta:[{property:"article:published_time",content:"2021-03-30T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Making Descriptor-based paper wallets"},{property:"og:description",content:"Demonstrate how to create descriptor-based paper wallet and how to spend them with bdk"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/descriptor_based_paper_wallet/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Making Descriptor-based paper wallets"},{name:"twitter:description",content:"Demonstrate how to create descriptor-based paper wallet and how to spend them with bdk"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/descriptor_based_paper_wallet/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"guide, descriptor, paper wallets"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"descriptor"},{property:"article:tag",content:"paper wallets"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/descriptor_based_paper_wallet.html",relativePath:"_blog/descriptor_based_paper_wallet.md",key:"v-9504490e",path:"/blog/descriptor-based-paper-wallet/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"About paper wallets",slug:"about-paper-wallets"},{level:2,title:"Descriptors",slug:"descriptors"},{level:2,title:"Example use case",slug:"example-use-case"},{level:2,title:"Creating the paper wallet",slug:"creating-the-paper-wallet"},{level:2,title:"BDK",slug:"bdk"},{level:2,title:"Funding tx",slug:"funding-tx"},{level:2,title:"Sweep tx",slug:"sweep-tx"},{level:3,title:"Step 1: Alice creates and signs a PSBT",slug:"step-1-alice-creates-and-signs-a-psbt"},{level:3,title:"Step 2: Barbara signs Alice's signed PSBT and broadcasts the tx",slug:"step-2-barbara-signs-alices-signed-psbt-and-broadcasts-the-tx"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"A Multisig between BDK and Core",frontmatter:{title:"A Multisig between BDK and Core",description:"Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK",authors:["Gabriele Domenichini"],date:"2020-11-18",tags:["guide","descriptor"],meta:[{property:"article:published_time",content:"2020-11-18T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"A Multisig between BDK and Core"},{property:"og:description",content:"Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/descriptors_in_the_wild/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"A Multisig between BDK and Core"},{name:"twitter:description",content:"Guide to setup a 2-of-2 multisig using Bitcoin Core and BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/descriptors_in_the_wild/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"guide, descriptor"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"descriptor"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/descriptors_in_the_wild.html",relativePath:"_blog/descriptors_in_the_wild.md",key:"v-c6756cce",path:"/blog/descriptors-in-the-wild/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"The use case",slug:"the-use-case"},{level:2,title:"The role of Descriptors",slug:"the-role-of-descriptors"},{level:2,title:"Our playground",slug:"our-playground"},{level:3,title:"1. Creating the seeds and the derived Extended Public keys",slug:"1-creating-the-seeds-and-the-derived-extended-public-keys"},{level:3,title:"2. Creation of the multi signature descriptor for each wallet",slug:"2-creation-of-the-multi-signature-descriptor-for-each-wallet"},{level:3,title:"3. Use each other's software to receive testnet coins from a faucet",slug:"3-use-each-others-software-to-receive-testnet-coins-from-a-faucet"},{level:3,title:"4. we return part of the satoshis received back to the faucet",slug:"4-we-return-part-of-the-satoshis-received-back-to-the-faucet"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"BDK-RN: Building React Native Apps with BDK",frontmatter:{title:"BDK-RN: Building React Native Apps with BDK",description:"A tutorial and guide to using bdk-rn for building bitcoin apps",authors:["Bitcoin Zavior"],date:"2022-08-05",tags:["bitcoin","React Native","iOS","Android","mobile","bdk-rn","bdk","tutorial","guide","wallet"],meta:[{property:"article:published_time",content:"2022-08-05T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK-RN: Building React Native Apps with BDK"},{property:"og:description",content:"A tutorial and guide to using bdk-rn for building bitcoin apps"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_rn/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK-RN: Building React Native Apps with BDK"},{name:"twitter:description",content:"A tutorial and guide to using bdk-rn for building bitcoin apps"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_rn/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bitcoin, React Native, iOS, Android, mobile, bdk-rn, bdk, tutorial, guide, wallet"},{property:"article:tag",content:"bitcoin"},{property:"article:tag",content:"React Native"},{property:"article:tag",content:"iOS"},{property:"article:tag",content:"Android"},{property:"article:tag",content:"mobile"},{property:"article:tag",content:"bdk-rn"},{property:"article:tag",content:"bdk"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"wallet"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/exploring_bdk_rn.html",relativePath:"_blog/exploring_bdk_rn.md",key:"v-f58ec8f2",path:"/blog/exploring-bdk-rn/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:3,title:"Prerequisites",slug:"prerequisites"},{level:3,title:"Bitcoin Basics",slug:"bitcoin-basics"},{level:2,title:"Bitcoin Dev Kit and bdk-rn",slug:"bitcoin-dev-kit-and-bdk-rn"},{level:2,title:"Getting Started",slug:"getting-started"},{level:2,title:"Setting up styles and RN app structure",slug:"setting-up-styles-and-rn-app-structure"},{level:2,title:"Installing bdk-rn",slug:"installing-bdk-rn"},{level:2,title:"Importing bdk-rn",slug:"importing-bdk-rn"},{level:2,title:"Calling bdk-rn methods",slug:"calling-bdk-rn-methods"},{level:2,title:"Creating a wallet",slug:"creating-a-wallet"},{level:2,title:"UTXOs and balance",slug:"utxos-and-balance"},{level:2,title:"Restoring wallet",slug:"restoring-wallet"},{level:2,title:"Sending bitcoin",slug:"sending-bitcoin"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"BDK-FLUTTER: Building Flutter Apps with BDK",frontmatter:{title:"BDK-FLUTTER: Building Flutter Apps with BDK",description:"A tutorial and guide to using bdk-flutter for building bitcoin apps",authors:["Bitcoin Zavior"],date:"2022-10-05",tags:["bitcoin","React Native","Flutter","iOS","Android","mobile","bdk-rn","bdk","tutorial","guide","wallet"],meta:[{property:"article:published_time",content:"2022-10-05T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK-FLUTTER: Building Flutter Apps with BDK"},{property:"og:description",content:"A tutorial and guide to using bdk-flutter for building bitcoin apps"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_flutter/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK-FLUTTER: Building Flutter Apps with BDK"},{name:"twitter:description",content:"A tutorial and guide to using bdk-flutter for building bitcoin apps"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/exploring_bdk_flutter/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bitcoin, React Native, Flutter, iOS, Android, mobile, bdk-rn, bdk, tutorial, guide, wallet"},{property:"article:tag",content:"bitcoin"},{property:"article:tag",content:"React Native"},{property:"article:tag",content:"Flutter"},{property:"article:tag",content:"iOS"},{property:"article:tag",content:"Android"},{property:"article:tag",content:"mobile"},{property:"article:tag",content:"bdk-rn"},{property:"article:tag",content:"bdk"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"wallet"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/exploring_bdk_flutter.html",relativePath:"_blog/exploring_bdk_flutter.md",key:"v-56536559",path:"/blog/exploring-bdk-flutter/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:3,title:"Prerequisites",slug:"prerequisites"},{level:3,title:"Bitcoin Basics",slug:"bitcoin-basics"},{level:2,title:"Bitcoin Dev Kit and bdk-flutter",slug:"bitcoin-dev-kit-and-bdk-flutter"},{level:2,title:"Getting Started",slug:"getting-started"},{level:2,title:"Setting up Flutter app structure",slug:"setting-up-flutter-app-structure"},{level:2,title:"Installing bdk-flutter",slug:"installing-bdk-flutter"},{level:2,title:"Configuring",slug:"configuring"},{level:2,title:"Importing bdk-flutter",slug:"importing-bdk-flutter"},{level:2,title:"Calling bdk-flutter methods",slug:"calling-bdk-flutter-methods"},{level:2,title:"Creating a wallet",slug:"creating-a-wallet"},{level:2,title:"UTXOs and balance",slug:"utxos-and-balance"},{level:2,title:"Restoring a wallet",slug:"restoring-a-wallet"},{level:2,title:"Sending bitcoin",slug:"sending-bitcoin"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Fee estimation for light-clients (Part 2)",frontmatter:{title:"Fee estimation for light-clients (Part 2)",description:"Applying machine learning to the bitcoin fee estimation problem",authors:["Riccardo Casatta"],date:"2021-01-25",tags:["fee","machine learning"],permalink:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",meta:[{property:"article:published_time",content:"2021-01-25T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Fee estimation for light-clients (Part 2)"},{property:"og:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Fee estimation for light-clients (Part 2)"},{name:"twitter:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"fee, machine learning"},{property:"article:tag",content:"fee"},{property:"article:tag",content:"machine learning"}],layout:"Post"},regularPath:"/_blog/fee_estimation_for_light_clients_part_2.html",relativePath:"_blog/fee_estimation_for_light_clients_part_2.md",key:"v-2c605799",path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",headers:[{level:2,title:"The dataset",slug:"the-dataset"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Fee estimation for light-clients (Part 3)",frontmatter:{title:"Fee estimation for light-clients (Part 3)",description:"Applying machine learning to the bitcoin fee estimation problem",authors:["Riccardo Casatta"],date:"2021-01-25",tags:["fee","machine learning"],permalink:"/blog/2021/01/fee-estimation-for-light-clients-part-3/",meta:[{property:"article:published_time",content:"2021-01-25T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Fee estimation for light-clients (Part 3)"},{property:"og:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Fee estimation for light-clients (Part 3)"},{name:"twitter:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"fee, machine learning"},{property:"article:tag",content:"fee"},{property:"article:tag",content:"machine learning"}],layout:"Post"},regularPath:"/_blog/fee_estimation_for_light_clients_part_3.html",relativePath:"_blog/fee_estimation_for_light_clients_part_3.md",key:"v-57698579",path:"/blog/2021/01/fee-estimation-for-light-clients-part-3/",headers:[{level:2,title:"The model",slug:"the-model"},{level:2,title:"The prediction phase",slug:"the-prediction-phase"},{level:2,title:"Conclusion and future development",slug:"conclusion-and-future-development"},{level:2,title:"Acknowledgements",slug:"acknowledgements"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Fee estimation for light-clients (Part 1)",frontmatter:{title:"Fee estimation for light-clients (Part 1)",description:"Applying machine learning to the bitcoin fee estimation problem",authors:["Riccardo Casatta"],date:"2021-01-25",tags:["fee","machine learning"],permalink:"/blog/2021/01/fee-estimation-for-light-clients-part-1/",meta:[{property:"article:published_time",content:"2021-01-25T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Fee estimation for light-clients (Part 1)"},{property:"og:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Fee estimation for light-clients (Part 1)"},{name:"twitter:description",content:"Applying machine learning to the bitcoin fee estimation problem"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"fee, machine learning"},{property:"article:tag",content:"fee"},{property:"article:tag",content:"machine learning"}],layout:"Post"},regularPath:"/_blog/fee_estimation_for_light_clients_part_1.html",relativePath:"_blog/fee_estimation_for_light_clients_part_1.md",key:"v-015729b9",path:"/blog/2021/01/fee-estimation-for-light-clients-part-1/",headers:[{level:2,title:"Introduction: what is fee estimation?",slug:"introduction-what-is-fee-estimation"},{level:2,title:"The problem",slug:"the-problem"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"The first BDK Taproot TX: a look at the code (Part 1)",frontmatter:{title:"The first BDK Taproot TX: a look at the code (Part 1)",description:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction",authors:["Alekos Filini"],date:"2021-11-15",tags:["BDK","taproot","miniscript"],permalink:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1",meta:[{property:"article:published_time",content:"2021-11-15T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"The first BDK Taproot TX: a look at the code (Part 1)"},{property:"og:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"The first BDK Taproot TX: a look at the code (Part 1)"},{name:"twitter:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, taproot, miniscript"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"taproot"},{property:"article:tag",content:"miniscript"}],layout:"Post"},regularPath:"/_blog/first_bdk_taproot_tx.html",relativePath:"_blog/first_bdk_taproot_tx.md",key:"v-9145467a",path:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/",headers:[{level:2,title:"Backstory",slug:"backstory"},{level:2,title:"rust-bitcoin",slug:"rust-bitcoin"},{level:2,title:"rust-miniscript",slug:"rust-miniscript"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"The first BDK Taproot TX: a look at the code (Part 2)",frontmatter:{title:"The first BDK Taproot TX: a look at the code (Part 2)",description:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction",authors:["Alekos Filini"],date:"2021-12-10",tags:["BDK","taproot","miniscript"],permalink:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2",meta:[{property:"article:published_time",content:"2021-12-10T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"The first BDK Taproot TX: a look at the code (Part 2)"},{property:"og:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"The first BDK Taproot TX: a look at the code (Part 2)"},{name:"twitter:description",content:"A quick overview of the changes made to bdk, rust-miniscript and rust-bitcoin to make a Taproot transaction"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, taproot, miniscript"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"taproot"},{property:"article:tag",content:"miniscript"}],layout:"Post"},regularPath:"/_blog/first_bdk_taproot_tx_part_2.html",relativePath:"_blog/first_bdk_taproot_tx_part_2.md",key:"v-2cf72b39",path:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/",headers:[{level:2,title:"Shortcuts",slug:"shortcuts"},{level:2,title:"Utilities",slug:"utilities"},{level:2,title:"Wrap Fallible Methods",slug:"wrap-fallible-methods"},{level:2,title:"Descriptor Metadata",slug:"descriptor-metadata"},{level:2,title:"Policy",slug:"policy"},{level:2,title:"Signer",slug:"signer"},{level:2,title:"PSBT Metadata",slug:"psbt-metadata"},{level:2,title:"descriptor!() Macro",slug:"descriptor-macro"},{level:3,title:"tr() Descriptors",slug:"tr-descriptors"},{level:3,title:"multi_a() Operator",slug:"multi-a-operator"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Getting Started with rust-hwi",frontmatter:{title:"Getting Started with rust-hwi",description:"This post will help one understand and develop for hardware wallets using BDK",authors:["Wszdexdrf"],date:"2022-08-16",tags:["BDK","Development","Hardware Wallets"],draft:!1,meta:[{property:"article:published_time",content:"2022-08-16T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Getting Started with rust-hwi"},{property:"og:description",content:"This post will help one understand and develop for hardware wallets using BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/getting_started_with_rust_hwi/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Getting Started with rust-hwi"},{name:"twitter:description",content:"This post will help one understand and develop for hardware wallets using BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/getting_started_with_rust_hwi/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, Development, Hardware Wallets"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"Development"},{property:"article:tag",content:"Hardware Wallets"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/getting_started_with_rust_hwi.html",relativePath:"_blog/getting_started_with_rust_hwi.md",key:"v-11d64359",path:"/blog/getting-started-with-rust-hwi/",headers:[{level:2,title:"Fundamentals",slug:"fundamentals"},{level:2,title:"Integration with BDK",slug:"integration-with-bdk"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Hello World!",frontmatter:{title:"Hello World!",description:"Getting started using the BDK library in a very simple Rust project",authors:["Alekos Filini"],date:"2020-12-18",tags:["getting started","rust"],permalink:"/blog/2020/12/hello-world/",meta:[{property:"article:published_time",content:"2020-12-18T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Hello World!"},{property:"og:description",content:"Getting started using the BDK library in a very simple Rust project"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2020/12/hello-world/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Hello World!"},{name:"twitter:description",content:"Getting started using the BDK library in a very simple Rust project"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2020/12/hello-world/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"getting started, rust"},{property:"article:tag",content:"getting started"},{property:"article:tag",content:"rust"}],layout:"Post"},regularPath:"/_blog/hello-world.html",relativePath:"_blog/hello-world.md",key:"v-5d749fce",path:"/blog/2020/12/hello-world/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Design Goals",slug:"design-goals"},{level:2,title:"The Wallet Structure",slug:"the-wallet-structure"},{level:2,title:"Custom Database and Blockchain types",slug:"custom-database-and-blockchain-types"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Hidden Powers of Miniscript Policy & Descriptors",frontmatter:{title:"Hidden Powers of Miniscript Policy & Descriptors",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:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-01-02T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Hidden Powers of Miniscript Policy & Descriptors"},{property:"og:description",content:"Introduction to Descriptor and Miniscript, making a Multisig Wallet and Testing Miniscript Policies"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/hidden-power-of-bitcoin/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Hidden Powers of Miniscript Policy & Descriptors"},{name:"twitter:description",content:"Introduction to Descriptor and Miniscript, making a Multisig Wallet and Testing Miniscript Policies"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/hidden-power-of-bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"tutorial, bdk, bdk-cli, miniscript, descriptor, bitcoin-cli"},{property:"article:tag",content:"tutorial"},{property:"article:tag",content:"bdk"},{property:"article:tag",content:"bdk-cli"},{property:"article:tag",content:"miniscript"},{property:"article:tag",content:"descriptor"},{property:"article:tag",content:"bitcoin-cli"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/hidden-power-of-bitcoin.html",relativePath:"_blog/hidden-power-of-bitcoin.md",key:"v-ab5ba3ce",path:"/blog/hidden-power-of-bitcoin/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Script",slug:"script"},{level:2,title:"Miniscript",slug:"miniscript"},{level:2,title:"Descriptors",slug:"descriptors"},{level:2,title:"Where it all comes together...",slug:"where-it-all-comes-together"},{level:3,title:"Keys and Generating Addresses",slug:"keys-and-generating-addresses"},{level:3,title:"Making a MultiSig Descriptor for Funds",slug:"making-a-multisig-descriptor-for-funds"},{level:2,title:"Retention Bonus - Smart Contract with Bitcoin",slug:"retention-bonus-smart-contract-with-bitcoin"},{level:2,title:"Inspirations",slug:"inspirations"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Improving coin selection in BDK",frontmatter:{title:"Improving coin selection in BDK",description:"A brief description of the work done in the coin selection module in BDK during Summer of Bitcoin 2022",date:"2022-08-17",tags:["coin selection","BDK","development","summer of bitcoin"],authors:["César Alvarez Vallero"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-08-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Improving coin selection in BDK"},{property:"og:description",content:"A brief description of the work done in the coin selection module in BDK during Summer of Bitcoin 2022"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/improving_coin_selection_in_BDK/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Improving coin selection in BDK"},{name:"twitter:description",content:"A brief description of the work done in the coin selection module in BDK during Summer of Bitcoin 2022"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/improving_coin_selection_in_BDK/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"coin selection, BDK, development, summer of bitcoin"},{property:"article:tag",content:"coin selection"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"development"},{property:"article:tag",content:"summer of bitcoin"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/improving_coin_selection_in_BDK.html",relativePath:"_blog/improving_coin_selection_in_BDK.md",key:"v-d0375c8e",path:"/blog/improving-coin-selection-in-bdk/",headers:[{level:2,title:"Waste",slug:"waste"},{level:3,title:"How it works?",slug:"how-it-works"},{level:3,title:"What has been done",slug:"what-has-been-done"},{level:3,title:"Work in progress",slug:"work-in-progress"},{level:2,title:"Further Improvements",slug:"further-improvements"},{level:3,title:"Privacy",slug:"privacy"},{level:3,title:"Flexibility",slug:"flexibility"},{level:2,title:"Conclusion",slug:"conclusion"},{level:2,title:"Acknowledgements",slug:"acknowledgements"},{level:2,title:"References",slug:"references"},{level:3,title:"About coin selection considerations",slug:"about-coin-selection-considerations"},{level:3,title:"About Waste metric",slug:"about-waste-metric"},{level:3,title:"About improving privacy in coin selection",slug:"about-improving-privacy-in-coin-selection"},{level:3,title:"About bdk_core",slug:"about-bdk-core"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Security Advisory: Miniscript MINIMALIF Bug",frontmatter:{title:"Security Advisory: Miniscript MINIMALIF Bug",description:"Security advisory on the recent Miniscript MINIMALIF bug. How to check if you are affected and what to do next.",authors:["Alekos Filini"],date:"2022-04-19",tags:["miniscript","security"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-04-19T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Security Advisory: Miniscript MINIMALIF Bug"},{property:"og:description",content:"Security advisory on the recent Miniscript MINIMALIF bug. How to check if you are affected and what to do next."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/miniscript_vulnerability/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Security Advisory: Miniscript MINIMALIF Bug"},{name:"twitter:description",content:"Security advisory on the recent Miniscript MINIMALIF bug. How to check if you are affected and what to do next."},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/miniscript_vulnerability/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"miniscript, security"},{property:"article:tag",content:"miniscript"},{property:"article:tag",content:"security"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/miniscript_vulnerability.html",relativePath:"_blog/miniscript_vulnerability.md",key:"v-10852eea",path:"/blog/miniscript-vulnerability/",headers:[{level:2,title:"How to check if you are vulnerable",slug:"how-to-check-if-you-are-vulnerable"},{level:2,title:"Next steps",slug:"next-steps"},{level:3,title:"If you are affected",slug:"if-you-are-affected"},{level:3,title:"Everybody",slug:"everybody"},{level:2,title:"Consequences of the update",slug:"consequences-of-the-update"},{level:2,title:"Footnote: How we analyzed the blockchain",slug:"footnote-how-we-analyzed-the-blockchain"},{level:2,title:"Correction (2022-04-25)",slug:"correction-2022-04-25"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.3.0",frontmatter:{title:"Release v0.3.0",description:"Announcing the v0.3.0 release of BDK",authors:["Alekos Filini"],date:"2021-01-20",tags:["rust","release"],permalink:"/blog/2021/01/release-v0.3.0/",meta:[{property:"article:published_time",content:"2021-01-20T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.3.0"},{property:"og:description",content:"Announcing the v0.3.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/01/release-v0.3.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.3.0"},{name:"twitter:description",content:"Announcing the v0.3.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/01/release-v0.3.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.3.0.html",relativePath:"_blog/release-0.3.0.md",key:"v-05df4999",path:"/blog/2021/01/release-v0.3.0/",headers:[{level:2,title:"What's new in v0.3.0",slug:"whats-new-in-v030"},{level:3,title:"Less verbosity when using Wallet::new_offline()",slug:"less-verbosity-when-using-walletnew-offline"},{level:3,title:"No more error conversions in DescriptorTemplate",slug:"no-more-error-conversions-in-descriptortemplate"},{level:3,title:"A new repo for the CLI",slug:"a-new-repo-for-the-cli"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.2.0",frontmatter:{title:"Release v0.2.0",description:"Announcing the v0.2.0 release of BDK",authors:["Alekos Filini"],date:"2020-12-21",tags:["rust","release"],permalink:"/blog/2020/12/release-v0.2.0/",meta:[{property:"article:published_time",content:"2020-12-21T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.2.0"},{property:"og:description",content:"Announcing the v0.2.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2020/12/release-v0.2.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.2.0"},{name:"twitter:description",content:"Announcing the v0.2.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2020/12/release-v0.2.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.2.0.html",relativePath:"_blog/release-0.2.0.md",key:"v-edd5570e",path:"/blog/2020/12/release-v0.2.0/",headers:[{level:2,title:"What's new in v0.2.0",slug:"whats-new-in-v020"},{level:3,title:"A new name",slug:"a-new-name"},{level:3,title:"Branch and Bound coin selection",slug:"branch-and-bound-coin-selection"},{level:3,title:"Key generation",slug:"key-generation"},{level:3,title:"Generic key types",slug:"generic-key-types"},{level:3,title:"Descriptor templates",slug:"descriptor-templates"},{level:3,title:"Easier creation of Blockchain and Database",slug:"easier-creation-of-blockchain-and-database"},{level:3,title:"descriptor!() macro",slug:"descriptor-macro"},{level:3,title:"Support for sortedmulti()",slug:"support-for-sortedmulti"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.5.0",frontmatter:{title:"Release v0.5.0",description:"Announcing the v0.5.0 release of BDK",authors:["Alekos Filini"],date:"2021-03-18",tags:["rust","release"],permalink:"/blog/2021/03/release-v0.5.0/",meta:[{property:"article:published_time",content:"2021-03-18T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.5.0"},{property:"og:description",content:"Announcing the v0.5.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/03/release-v0.5.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.5.0"},{name:"twitter:description",content:"Announcing the v0.5.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/03/release-v0.5.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.5.0.html",relativePath:"_blog/release-0.5.0.md",key:"v-0119984e",path:"/blog/2021/03/release-v0.5.0/",headers:[{level:2,title:"What's new in v0.5.0",slug:"whats-new-in-v050"},{level:3,title:"Dual Licensing",slug:"dual-licensing"},{level:3,title:"Spending foreign UTXOs",slug:"spending-foreign-utxos"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.4.0",frontmatter:{title:"Release v0.4.0",description:"Announcing the v0.4.0 release of BDK",authors:["Alekos Filini"],date:"2021-02-17",tags:["rust","release"],permalink:"/blog/2021/02/release-v0.4.0/",meta:[{property:"article:published_time",content:"2021-02-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.4.0"},{property:"og:description",content:"Announcing the v0.4.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/02/release-v0.4.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.4.0"},{name:"twitter:description",content:"Announcing the v0.4.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/02/release-v0.4.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.4.0.html",relativePath:"_blog/release-0.4.0.md",key:"v-faad828e",path:"/blog/2021/02/release-v0.4.0/",headers:[{level:2,title:"What's new in v0.4.0",slug:"whats-new-in-v040"},{level:3,title:"A new API to build transaction",slug:"a-new-api-to-build-transaction"},{level:3,title:"Upgraded dependencies",slug:"upgraded-dependencies"},{level:3,title:"Compact Filters example",slug:"compact-filters-example"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.6.0",frontmatter:{title:"Release v0.6.0",description:"Announcing the v0.6.0 release of BDK",authors:["Alekos Filini"],date:"2021-04-15",tags:["rust","release"],permalink:"/blog/2021/04/release-v0.6.0/",meta:[{property:"article:published_time",content:"2021-04-15T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.6.0"},{property:"og:description",content:"Announcing the v0.6.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/04/release-v0.6.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.6.0"},{name:"twitter:description",content:"Announcing the v0.6.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/04/release-v0.6.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.6.0.html",relativePath:"_blog/release-0.6.0.md",key:"v-7c3d28f9",path:"/blog/2021/04/release-v0.6.0/",headers:[{level:2,title:"What's new in v0.6.0",slug:"whats-new-in-v060"},{level:3,title:"A new way to generate addresses",slug:"a-new-way-to-generate-addresses"},{level:3,title:"Easier multiparty transaction creation",slug:"easier-multiparty-transaction-creation"},{level:3,title:"Renamed types",slug:"renamed-types"},{level:3,title:"New MSRV",slug:"new-msrv"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.7.0",frontmatter:{title:"Release v0.7.0",description:"Announcing the v0.7.0 release of BDK",authors:["Alekos Filini"],date:"2021-05-17",tags:["rust","release"],permalink:"/blog/2021/05/release-v0.7.0/",meta:[{property:"article:published_time",content:"2021-05-17T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.7.0"},{property:"og:description",content:"Announcing the v0.7.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/05/release-v0.7.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.7.0"},{name:"twitter:description",content:"Announcing the v0.7.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/05/release-v0.7.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.7.0.html",relativePath:"_blog/release-0.7.0.md",key:"v-0df1c3ce",path:"/blog/2021/05/release-v0.7.0/",headers:[{level:2,title:"What's new in v0.7.0",slug:"whats-new-in-v070"},{level:3,title:"New Signing API",slug:"new-signing-api"},{level:3,title:"Support Timelocks in the policy Module",slug:"support-timelocks-in-the-policy-module"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.8.0",frontmatter:{title:"Release v0.8.0",description:"Announcing the v0.8.0 release of BDK",authors:["Alekos Filini"],date:"2021-06-14",tags:["rust","release"],permalink:"/blog/2021/06/release-v0.8.0/",meta:[{property:"article:published_time",content:"2021-06-14T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.8.0"},{property:"og:description",content:"Announcing the v0.8.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/06/release-v0.8.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.8.0"},{name:"twitter:description",content:"Announcing the v0.8.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/06/release-v0.8.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.8.0.html",relativePath:"_blog/release-0.8.0.md",key:"v-75d11339",path:"/blog/2021/06/release-v0.8.0/",headers:[{level:2,title:"What's new in v0.8.0",slug:"whats-new-in-v080"},{level:3,title:"Getting the Derivation Index",slug:"getting-the-derivation-index"},{level:3,title:"Explicitly Enable non-ALL Sighashes",slug:"explicitly-enable-non-all-sighashes"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Release v0.9.0",frontmatter:{title:"Release v0.9.0",description:"Announcing the v0.9.0 release of BDK",authors:["Alekos Filini"],date:"2021-07-11",tags:["rust","release"],permalink:"/blog/2021/07/release-v0.9.0/",meta:[{property:"article:published_time",content:"2021-07-11T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Release v0.9.0"},{property:"og:description",content:"Announcing the v0.9.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/2021/07/release-v0.9.0/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Release v0.9.0"},{name:"twitter:description",content:"Announcing the v0.9.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/2021/07/release-v0.9.0/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"rust, release"},{property:"article:tag",content:"rust"},{property:"article:tag",content:"release"}],layout:"Post"},regularPath:"/_blog/release-0.9.0.html",relativePath:"_blog/release-0.9.0.md",key:"v-1ac9ef4e",path:"/blog/2021/07/release-v0.9.0/",headers:[{level:2,title:"What's new in v0.9.0",slug:"whats-new-in-v090"},{level:2,title:"Bitcoin Core Blockchain Backend",slug:"bitcoin-core-blockchain-backend"},{level:2,title:"Updated TransactionDetails Struct",slug:"updated-transactiondetails-struct"},{level:2,title:"Verify Downloaded TXs",slug:"verify-downloaded-txs"},{level:2,title:"Contributors",slug:"contributors"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"The Road to BDK 1.0",frontmatter:{title:"The Road to BDK 1.0",description:"Outlining the plan for the 1.0 release of BDK",authors:["Alekos Filini"],date:"2022-10-03",tags:["architecture"],draft:!1,meta:[{property:"article:published_time",content:"2022-10-03T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"The Road to BDK 1.0"},{property:"og:description",content:"Outlining the plan for the 1.0 release of BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/road_to_bdk_1/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"The Road to BDK 1.0"},{name:"twitter:description",content:"Outlining the plan for the 1.0 release of BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/road_to_bdk_1/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"architecture"},{property:"article:tag",content:"architecture"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/road_to_bdk_1.html",relativePath:"_blog/road_to_bdk_1.md",key:"v-55969f39",path:"/blog/road-to-bdk-1/",headers:[{level:2,title:"Goals",slug:"goals"},{level:3,title:"Stable API",slug:"stable-api"},{level:3,title:"Upstreaming our code",slug:"upstreaming-our-code"},{level:3,title:"Partially Syncing a Wallet",slug:"partially-syncing-a-wallet"},{level:3,title:"no_std",slug:"no-std"},{level:3,title:"Lower MSRV",slug:"lower-msrv"},{level:2,title:"Architecture",slug:"architecture"},{level:2,title:"Timeline",slug:"timeline"},{level:2,title:"Feature Freezing BDK",slug:"feature-freezing-bdk"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Using BDK with hardware wallets",frontmatter:{title:"Using BDK with hardware wallets",description:"Tutorial showing how to send funds to a HW and then spend from it using BDK",authors:["Daniela Brozzoni"],date:"2022-10-27",tags:["BDK","Development","Hardware Wallets"],hidden:!0,draft:!1,meta:[{property:"article:published_time",content:"2022-10-27T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Using BDK with hardware wallets"},{property:"og:description",content:"Tutorial showing how to send funds to a HW and then spend from it using BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/using_bdk_with_hardware_wallets/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Using BDK with hardware wallets"},{name:"twitter:description",content:"Tutorial showing how to send funds to a HW and then spend from it using BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/using_bdk_with_hardware_wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"BDK, Development, Hardware Wallets"},{property:"article:tag",content:"BDK"},{property:"article:tag",content:"Development"},{property:"article:tag",content:"Hardware Wallets"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/using_bdk_with_hardware_wallets.html",relativePath:"_blog/using_bdk_with_hardware_wallets.md",key:"v-aeb70fce",path:"/blog/using-bdk-with-hardware-wallets/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Prerequisites",slug:"prerequisites"},{level:2,title:"Initial setup",slug:"initial-setup"},{level:2,title:"Finding the hardware wallet",slug:"finding-the-hardware-wallet"},{level:2,title:"Receiving funds",slug:"receiving-funds"},{level:2,title:"Spending funds",slug:"spending-funds"},{level:2,title:"Conclusion",slug:"conclusion"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Why Do We Build Bindings?",frontmatter:{title:"Why Do We Build Bindings?",description:"A post exploring why the Bitcoin Dev Kit Foundation produces language bindings for its libraries",authors:["thunderbiscuit"],date:"2024-05-07",tags:["bindings"],meta:[{property:"article:published_time",content:"2024-05-07T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Why Do We Build Bindings?"},{property:"og:description",content:"A post exploring why the Bitcoin Dev Kit Foundation produces language bindings for its libraries"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/why-bindings/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Why Do We Build Bindings?"},{name:"twitter:description",content:"A post exploring why the Bitcoin Dev Kit Foundation produces language bindings for its libraries"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/why-bindings/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"bindings"},{property:"article:tag",content:"bindings"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/why-bindings.html",relativePath:"_blog/why-bindings.md",key:"v-4dc135e3",path:"/blog/why-bindings/",headers:[{level:2,title:"Awesome! Producing Bindings Must Be Easy Right?",slug:"awesome-producing-bindings-must-be-easy-right"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Spending Policy Decoded",frontmatter:{title:"Spending Policy Decoded",description:"Demonstrate how to use a descriptor wallet with different spending policies",authors:["Steve Myers","thunderbiscuit"],date:"2021-02-23",tags:["guide","descriptor"],meta:[{property:"article:published_time",content:"2021-02-23T00:00:00.000Z"},{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Spending Policy Decoded"},{property:"og:description",content:"Demonstrate how to use a descriptor wallet with different spending policies"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/_blog/spending_policy_demo/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Spending Policy Decoded"},{name:"twitter:description",content:"Demonstrate how to use a descriptor wallet with different spending policies"},{name:"twitter:url",content:"https://bitcoindevkit.org/_blog/spending_policy_demo/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"guide, descriptor"},{property:"article:tag",content:"guide"},{property:"article:tag",content:"descriptor"}],layout:"Post",permalink:"/blog/:slug"},regularPath:"/_blog/spending_policy_demo.html",relativePath:"_blog/spending_policy_demo.md",key:"v-8534b9c2",path:"/blog/spending-policy-demo/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Initial Setup",slug:"initial-setup"},{level:3,title:"Step 0: Install a recent version bdk-cli",slug:"step-0-install-a-recent-version-bdk-cli"},{level:3,title:"Step 1: Generate private extended keys",slug:"step-1-generate-private-extended-keys"},{level:3,title:"Step 2: Extract private extended keys",slug:"step-2-extract-private-extended-keys"},{level:3,title:"Step 3: Derive public extended keys",slug:"step-3-derive-public-extended-keys"},{level:3,title:"Step 4: Create wallet descriptors for each participant",slug:"step-4-create-wallet-descriptors-for-each-participant"},{level:2,title:"Policy A. Three signatures",slug:"policy-a-three-signatures"},{level:3,title:"Step 1a: Create a testnet segwit0 receive address",slug:"step-1a-create-a-testnet-segwit0-receive-address"},{level:3,title:"Step 2a: Send testnet bitcoin from a faucet to receive address",slug:"step-2a-send-testnet-bitcoin-from-a-faucet-to-receive-address"},{level:3,title:"Step 3a: Sync participant wallets and confirm balance",slug:"step-3a-sync-participant-wallets-and-confirm-balance"},{level:3,title:"Step 4a: View wallet spending policies",slug:"step-4a-view-wallet-spending-policies"},{level:3,title:"Step 5a: Create spending transaction",slug:"step-5a-create-spending-transaction"},{level:3,title:"Step 6a: Sign and finalize PSBTs",slug:"step-6a-sign-and-finalize-psbts"},{level:3,title:"Step 7a: Broadcast finalized PSBT",slug:"step-7a-broadcast-finalized-psbt"},{level:3,title:"Step 8a: Confirm transaction included in a testnet block",slug:"step-8a-confirm-transaction-included-in-a-testnet-block"},{level:2,title:"Policy B. Two signatures after a relative time lock",slug:"policy-b-two-signatures-after-a-relative-time-lock"},{level:3,title:"Step 1b: Create a new testnet receive address",slug:"step-1b-create-a-new-testnet-receive-address"},{level:3,title:"Step 2b: Fund new address from testnet faucet",slug:"step-2b-fund-new-address-from-testnet-faucet"},{level:3,title:"Step 3b: Sync wallet and confirm wallet balance",slug:"step-3b-sync-wallet-and-confirm-wallet-balance"},{level:3,title:"Step 4b: Create spending transaction",slug:"step-4b-create-spending-transaction"},{level:3,title:"Step 5b: Sign and finalize PSBTs",slug:"step-5b-sign-and-finalize-psbts"},{level:3,title:"Step 6b: Broadcast finalized PSBT",slug:"step-6b-broadcast-finalized-psbt"},{level:3,title:"Step 7b: View confirmed transaction",slug:"step-7b-view-confirmed-transaction"}],codeSwitcherOptions:{},id:"blog",pid:"blog",lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"All",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/all/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/all/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/all.html",relativePath:"adoption/all.md",key:"v-4d760891",path:"/adoption/all/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Custodial",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/custodial/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/custodial/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/custodial.html",relativePath:"adoption/custodial.md",key:"v-30c0037b",path:"/adoption/custodial/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Desktop",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/desktop/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/desktop/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/desktop.html",relativePath:"adoption/desktop.md",key:"v-4bb7844a",path:"/adoption/desktop/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Exchange",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/exchange/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/exchange/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/exchange.html",relativePath:"adoption/exchange.md",key:"v-b936290e",path:"/adoption/exchange/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Infrastructure",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/infrastructure/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/infrastructure/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/infrastructure.html",relativePath:"adoption/infrastructure.md",key:"v-4e0b610e",path:"/adoption/infrastructure/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Mobile",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/mobile/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/mobile.html",relativePath:"adoption/mobile.md",key:"v-a7c24c4e",path:"/adoption/mobile/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Web",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/web/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/web/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/web.html",relativePath:"adoption/web.md",key:"v-17019aeb",path:"/adoption/web/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Hardware",frontmatter:{sidebar:!0,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/adoption/hardware/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/adoption/hardware/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/adoption/hardware.html",relativePath:"adoption/hardware.md",key:"v-7afdbb4e",path:"/adoption/hardware/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Compiler",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Compiler"},{property:"og:description",content:'If you want to play around with more complicated spending policies, you\'ll start to find it harder and harder to manually create the descriptors. This is where the miniscript compiler comes in! The `bdk` library\nincludes a very simple compiler that can produce a descriptor given a spending policy. The syntax used to encode the spending policy is very well described in this pagehttp://bitcoin.sipa.be/miniscript/,\nspecifically in the "Policy to Miniscript compiler". The compiler included in BDK does basically the same job, but produces descriptors for `rust-miniscript` that have some minor differences from\nthe ones made by the C++ implementation used in that website.'},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/compiler/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Compiler"},{name:"twitter:description",content:'If you want to play around with more complicated spending policies, you\'ll start to find it harder and harder to manually create the descriptors. This is where the miniscript compiler comes in! The `bdk` library\nincludes a very simple compiler that can produce a descriptor given a spending policy. The syntax used to encode the spending policy is very well described in this pagehttp://bitcoin.sipa.be/miniscript/,\nspecifically in the "Policy to Miniscript compiler". The compiler included in BDK does basically the same job, but produces descriptors for `rust-miniscript` that have some minor differences from\nthe ones made by the C++ implementation used in that website.'},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/compiler/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/compiler.html",relativePath:"bdk-cli/compiler.md",key:"v-7a315e41",path:"/bdk-cli/compiler/",headers:[{level:2,title:"Introduction",slug:"introduction"},{level:2,title:"Installation",slug:"installation"},{level:2,title:"Usage",slug:"usage"},{level:2,title:"Example",slug:"example"},{level:2,title:"Troubleshooting",slug:"troubleshooting"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Concept",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Concept"},{property:"og:description",content:"Now, in order to better grasp some of the design choices made by BDK, it's important to understand the main concept driving the development of this project, and the goal that it's trying to\nachieve."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/concept/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Concept"},{name:"twitter:description",content:"Now, in order to better grasp some of the design choices made by BDK, it's important to understand the main concept driving the development of this project, and the goal that it's trying to\nachieve."},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/concept/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/concept.html",relativePath:"bdk-cli/concept.md",key:"v-f611a14e",path:"/bdk-cli/concept/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Installation",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Installation"},{property:"og:description",content:"The only requirement to run the `bdk-cli` tool is a Linux/macOS system with a fairly recent Rust\ntoolchain installed. Since Linux distros tend to lag behind with updates, the quickest way to\ninstall the Rust compiler and Cargo is rustup.rshttps://rustup.rs/. You can head there and\nfollow their instructions, after which you can test if everything went fine by running"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/installation/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Installation"},{name:"twitter:description",content:"The only requirement to run the `bdk-cli` tool is a Linux/macOS system with a fairly recent Rust\ntoolchain installed. Since Linux distros tend to lag behind with updates, the quickest way to\ninstall the Rust compiler and Cargo is rustup.rshttps://rustup.rs/. You can head there and\nfollow their instructions, after which you can test if everything went fine by running"},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/installation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/installation.html",relativePath:"bdk-cli/installation.md",key:"v-3acb6e6a",path:"/bdk-cli/installation/",headers:[{level:2,title:"Requirements",slug:"requirements"},{level:2,title:"Installing the bdk-cli tool",slug:"installing-the-bdk-cli-tool"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Interface",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Interface"},{property:"og:description",content:"Remember the `bdk-cli --help` command you ran before? Let's analyze its output here to figure out the interface:"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/interface/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Interface"},{name:"twitter:description",content:"Remember the `bdk-cli --help` command you ran before? Let's analyze its output here to figure out the interface:"},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/interface/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/interface.html",relativePath:"bdk-cli/interface.md",key:"v-496cb7f9",path:"/bdk-cli/interface/",headers:[{level:2,title:"Flags",slug:"flags"},{level:3,title:"Verbosity",slug:"verbosity"},{level:2,title:"Options",slug:"options"},{level:2,title:"Subcommands",slug:"subcommands"},{level:2,title:"key",slug:"key"},{level:3,title:"generate",slug:"generate"},{level:3,title:"restore",slug:"restore"},{level:3,title:"derive",slug:"derive"},{level:2,title:"wallet",slug:"wallet"},{level:3,title:"Options",slug:"options-2"},{level:2,title:"Subcommands",slug:"subcommands-2"},{level:3,title:"broadcast",slug:"broadcast"},{level:3,title:"bump_fee",slug:"bump-fee"},{level:3,title:"combine_psbt",slug:"combine-psbt"},{level:3,title:"create_tx",slug:"create-tx"},{level:3,title:"extract_psbt",slug:"extract-psbt"},{level:3,title:"finalize_psbt",slug:"finalize-psbt"},{level:3,title:"get_balance",slug:"get-balance"},{level:3,title:"get_new_address",slug:"get-new-address"},{level:3,title:"list_transactions",slug:"list-transactions"},{level:3,title:"list_unspent",slug:"list-unspent"},{level:3,title:"policies",slug:"policies"},{level:3,title:"public_descriptor",slug:"public-descriptor"},{level:3,title:"help",slug:"help"},{level:3,title:"sign",slug:"sign"},{level:3,title:"sync",slug:"sync"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Playground",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Playground"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/playground/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Playground"},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/playground/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/playground.html",relativePath:"bdk-cli/playground.md",key:"v-a76bccee",path:"/bdk-cli/playground/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Introduction",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Introduction"},{property:"og:description",content:"This can also be used as an example application to create your own command line bitcoin wallet tool using bdk."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/introduction/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Introduction"},{name:"twitter:description",content:"This can also be used as an example application to create your own command line bitcoin wallet tool using bdk."},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/introduction/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/introduction.html",relativePath:"bdk-cli/introduction.md",key:"v-0b3b65ea",path:"/bdk-cli/introduction/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Regtest",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Regtest"},{property:"og:description",content:"Running the `bdk-cli` tool in regtest requires having a local Electrum server set-up. There are two main implementations, `electrs`https://github.com/romanz/electrs in Rust and `ElectrumX`https://github.com/spesmilo/electrumx in Python. Since the Rust toolchain is already required to\nuse BDK, this page will focus mostly on the former."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/regtest/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Regtest"},{name:"twitter:description",content:"Running the `bdk-cli` tool in regtest requires having a local Electrum server set-up. There are two main implementations, `electrs`https://github.com/romanz/electrs in Rust and `ElectrumX`https://github.com/spesmilo/electrumx in Python. Since the Rust toolchain is already required to\nuse BDK, this page will focus mostly on the former."},{name:"twitter:url",content:"https://bitcoindevkit.org/bdk-cli/regtest/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/bdk-cli/regtest.html",relativePath:"bdk-cli/regtest.md",key:"v-05d01c19",path:"/bdk-cli/regtest/",headers:[{level:2,title:"Troubleshooting",slug:"troubleshooting"},{level:2,title:"Bonus: Docker",slug:"bonus-docker"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{frontmatter:{cases:!0,sidebar:!1,tagline:"Bitcoin applications building with BDK",description:"A list of bitcoin applications and services building with BDK",actionText:"Add your project",actionLink:"https://github.com/orgs/bitcoindevkit/discussions/64",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin applications building with BDK"},{property:"og:description",content:"A list of bitcoin applications and services building with BDK"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/case-studies/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin applications building with BDK"},{name:"twitter:description",content:"A list of bitcoin applications and services building with BDK"},{name:"twitter:url",content:"https://bitcoindevkit.org/case-studies/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/case-studies.html",relativePath:"case-studies.md",key:"v-11bf335e",path:"/case-studies/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Descriptors",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Descriptors"},{property:"og:description",content:'Descriptors are a compact and semi-standard way to easily encode, or "describe", how scripts and subsequently, addresses of a wallet should be generated. They can be especially helpful when working with multisigs or even\nmore complex scripts, where the structure of the script itself is not trivial. They are a big step forward in making wallets more portable across different tools and apps, because for the first time they create a common\nlanguage to describe a full bitcoin script that developers can use and integrate in their software.'},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/descriptors/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Descriptors"},{name:"twitter:description",content:'Descriptors are a compact and semi-standard way to easily encode, or "describe", how scripts and subsequently, addresses of a wallet should be generated. They can be especially helpful when working with multisigs or even\nmore complex scripts, where the structure of the script itself is not trivial. They are a big step forward in making wallets more portable across different tools and apps, because for the first time they create a common\nlanguage to describe a full bitcoin script that developers can use and integrate in their software.'},{name:"twitter:url",content:"https://bitcoindevkit.org/descriptors/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/descriptors/",relativePath:"descriptors/README.md",key:"v-a9236c10",path:"/descriptors/",headers:[{level:3,title:"Compatibility Matrix",slug:"compatibility-matrix"},{level:3,title:"Examples",slug:"examples"},{level:3,title:"Implementation Details",slug:"implementation-details"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Examples",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Examples"},{property:"og:description",content:"Click the links below and learn from community-built example projects."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/examples/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Examples"},{name:"twitter:description",content:"Click the links below and learn from community-built example projects."},{name:"twitter:url",content:"https://bitcoindevkit.org/examples/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/examples/",relativePath:"examples/README.md",key:"v-29f9f21c",path:"/examples/",headers:[{level:2,title:"BDK-CLI",slug:"bdk-cli"},{level:2,title:"DevkitWallet",slug:"devkitwallet"},{level:2,title:"Padawan Wallet",slug:"padawan-wallet"},{level:2,title:"BDKSwiftExampleWallet",slug:"bdkswiftexamplewallet"},{level:2,title:"Tatooine",slug:"tatooine"},{level:2,title:"SEBA Bank Proof of reserves",slug:"seba-bank-proof-of-reserves"},{level:2,title:"Stackmate",slug:"stackmate"},{level:2,title:"Spotbit",slug:"spotbit"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Bitcoin Dev Kit Foundation",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/about/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/about/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/about.html",relativePath:"foundation/about.md",key:"v-3750297a",path:"/foundation/about/",headers:[{level:2,title:"Board",slug:"board"},{level:2,title:"Operations",slug:"operations"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Become a Member",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information on how to become a member of the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information on how to become a member of the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/become-a-member/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information on how to become a member of the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/become-a-member/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/become-a-member.html",relativePath:"foundation/become-a-member.md",key:"v-71ef7c85",path:"/foundation/become-a-member/",headers:[{level:2,title:"Membership Fee Information",slug:"membership-fee-information"},{level:3,title:"Silver Tier Sliding Scale",slug:"silver-tier-sliding-scale"},{level:3,title:"Ready to apply?",slug:"ready-to-apply"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Current Grantees (Full-Time)",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/grantees/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/grantees/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/grantees.html",relativePath:"foundation/grantees.md",key:"v-105750ce",path:"/foundation/grantees/",headers:[{level:2,title:"thunderbiscuit",slug:"thunderbiscuit"},{level:2,title:"Matthew Ramsden",slug:"matthew-ramsden"},{level:2,title:"ValuedMammal",slug:"valuedmammal"},{level:2,title:"Wei Chen",slug:"wei-chen"},{level:2,title:"Evan Lin",slug:"evan-lin"},{level:2,title:"Nymius",slug:"nymius"},{level:2,title:"Manuel Gatti",slug:"manuel-gatti"},{level:2,title:"Leonardo Souza",slug:"leonardo-souza"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Grants Program",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/grants/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/grants/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/grants.html",relativePath:"foundation/grants.md",key:"v-08589c4e",path:"/foundation/grants/",headers:[{level:2,title:"Grant Requirements",slug:"grant-requirements"},{level:2,title:"Full-time grants",slug:"full-time-grants"},{level:3,title:"Rust",slug:"rust"},{level:3,title:"Mobile / language bindings",slug:"mobile-language-bindings"},{level:2,title:"Project grants",slug:"project-grants"},{level:2,title:"Applying",slug:"applying"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Members",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/members/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/members/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/members.html",relativePath:"foundation/members.md",key:"v-4a4b61eb",path:"/foundation/members/",headers:[{level:2,title:"Platinum",slug:"platinum"},{level:2,title:"Gold",slug:"gold"},{level:2,title:"Silver",slug:"silver"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Bitcoin Dev Kit Foundation",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/",relativePath:"foundation/index.md",key:"v-c152529c",path:"/foundation/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Supporters",frontmatter:{sidebar:!0,tagline:"Foundation",description:"Information about the Bitcoin Dev Kit Foundation",editLink:!1,lastUpdated:!1,meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Foundation"},{property:"og:description",content:"Information about the Bitcoin Dev Kit Foundation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/foundation/supporters/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Foundation"},{name:"twitter:description",content:"Information about the Bitcoin Dev Kit Foundation"},{name:"twitter:url",content:"https://bitcoindevkit.org/foundation/supporters/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/foundation/supporters.html",relativePath:"foundation/supporters.md",key:"v-50aa6d4e",path:"/foundation/supporters/",codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{title:"Bitcoin Dev Kit",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Bitcoin Dev Kit"},{property:"og:description",content:"The Bitcoin Dev Kit BDKhttps://github.com/bitcoindevkit project originally called Magical Bitcoin 🧙 aims to build a collection of tools and libraries that are designed to be a solid foundation for cross platform Bitcoin wallets, along with a fully working reference implementation wallets for various platforms.\nAll BDK components are designed to be lightweight and modular so that they can be adapted for virtually any use-case: from single-sig mobile wallets to multi-billion-dollar cold storage vaults."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/getting-started/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Bitcoin Dev Kit"},{name:"twitter:description",content:"The Bitcoin Dev Kit BDKhttps://github.com/bitcoindevkit project originally called Magical Bitcoin 🧙 aims to build a collection of tools and libraries that are designed to be a solid foundation for cross platform Bitcoin wallets, along with a fully working reference implementation wallets for various platforms.\nAll BDK components are designed to be lightweight and modular so that they can be adapted for virtually any use-case: from single-sig mobile wallets to multi-billion-dollar cold storage vaults."},{name:"twitter:url",content:"https://bitcoindevkit.org/getting-started/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/getting-started.html",relativePath:"getting-started.md",key:"v-4bcdac39",path:"/getting-started/",headers:[{level:2,title:"Initial Configuration",slug:"initial-configuration"},{level:2,title:"Internal Features",slug:"internal-features"},{level:2,title:"Playground",slug:"playground"},{level:2,title:"Descriptors",slug:"descriptors"}],codeSwitcherOptions:{},lastUpdated:"11/18/2024, 8:15:46 PM",lastUpdatedTimestamp:1731960946e3},{frontmatter:{layout:"IndexPost",title:"Blog",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/",key:"v-424df898",path:"/blog/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Tags",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/",key:"v-619df59e",path:"/blog/tags/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterKey",title:"Authors",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/",key:"v-b0968728",path:"/blog/author/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"BDK ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BDK/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BDK/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BDK/",key:"v-5f2600b8",path:"/blog/tags/BDK/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"project ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/project/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/project/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/project/",key:"v-398e8fd4",path:"/blog/tags/project/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"grants ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/grants/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/grants/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/grants/",key:"v-9d39d64c",path:"/blog/tags/grants/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"tutorial ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/tutorial/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/tutorial/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/tutorial/",key:"v-da8c869a",path:"/blog/tags/tutorial/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Bitcoin Core ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Bitcoin Core/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Bitcoin Core/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Bitcoin%20Core/",key:"v-62bbf2ad",path:"/blog/tags/Bitcoin Core/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"RPC ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/RPC/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/RPC/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/RPC/",key:"v-5f171cb0",path:"/blog/tags/RPC/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Wallet ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Wallet/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Wallet/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Wallet/",key:"v-4696dfd8",path:"/blog/tags/Wallet/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bdk-cli ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bdk-cli/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bdk-cli/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bdk-cli/",key:"v-c711ccde",path:"/blog/tags/bdk-cli/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"multi-sig ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/multi-sig/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/multi-sig/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/multi-sig/",key:"v-655ee4a0",path:"/blog/tags/multi-sig/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"basics ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/basics/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/basics/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/basics/",key:"v-e646a928",path:"/blog/tags/basics/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"novice ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/novice/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/novice/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/novice/",key:"v-1fb58ffb",path:"/blog/tags/novice/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"architecture ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/architecture/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/architecture/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/architecture/",key:"v-c4494744",path:"/blog/tags/architecture/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"BDK-RN ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BDK-RN/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BDK-RN/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BDK-RN/",key:"v-876cfade",path:"/blog/tags/BDK-RN/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Development ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Development/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Development/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Development/",key:"v-3acc51dc",path:"/blog/tags/Development/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Architecture ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Architecture/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Architecture/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Architecture/",key:"v-650ae784",path:"/blog/tags/Architecture/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"tor ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/tor/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/tor/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/tor/",key:"v-5ef73f54",path:"/blog/tags/tor/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"wallet ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/wallet/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/wallet/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/wallet/",key:"v-39437010",path:"/blog/tags/wallet/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"blockchain ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/blockchain/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/blockchain/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/blockchain/",key:"v-7c8563fd",path:"/blog/tags/blockchain/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bindings ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bindings/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bindings/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bindings/",key:"v-1296a8fa",path:"/blog/tags/bindings/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"compact_filters ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/compact_filters/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/compact_filters/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/compact_filters/",key:"v-baacba64",path:"/blog/tags/compact_filters/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"BIP157 ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BIP157/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BIP157/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BIP157/",key:"v-75ccd5f2",path:"/blog/tags/BIP157/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Neutrino ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Neutrino/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Neutrino/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Neutrino/",key:"v-4fed1c23",path:"/blog/tags/Neutrino/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"guide ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/guide/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/guide/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/guide/",key:"v-a9e0285e",path:"/blog/tags/guide/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"descriptor ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/descriptor/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/descriptor/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/descriptor/",key:"v-733ed37c",path:"/blog/tags/descriptor/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"paper wallets ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/paper wallets/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/paper wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/paper%20wallets/",key:"v-1144be8a",path:"/blog/tags/paper wallets/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bitcoin ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bitcoin/",key:"v-915f8322",path:"/blog/tags/bitcoin/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"React Native ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/React Native/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/React Native/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/React%20Native/",key:"v-bf53d4d4",path:"/blog/tags/React Native/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"iOS ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/iOS/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/iOS/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/iOS/",key:"v-5f023740",path:"/blog/tags/iOS/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Android ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Android/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Android/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Android/",key:"v-414e735e",path:"/blog/tags/Android/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"mobile ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/mobile/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/mobile/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/mobile/",key:"v-2c94bf22",path:"/blog/tags/mobile/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bdk-rn ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bdk-rn/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bdk-rn/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bdk-rn/",key:"v-dd212a9e",path:"/blog/tags/bdk-rn/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bdk ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bdk/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bdk/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bdk/",key:"v-5f07f0f8",path:"/blog/tags/bdk/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Flutter ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Flutter/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Flutter/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Flutter/",key:"v-07eeb15e",path:"/blog/tags/Flutter/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"fee ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/fee/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/fee/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/fee/",key:"v-5f0447f2",path:"/blog/tags/fee/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"machine learning ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/machine learning/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/machine learning/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/machine%20learning/",key:"v-e2317b12",path:"/blog/tags/machine learning/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"taproot ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/taproot/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/taproot/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/taproot/",key:"v-57f3a168",path:"/blog/tags/taproot/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"miniscript ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/miniscript/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/miniscript/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/miniscript/",key:"v-ef7c3fa2",path:"/blog/tags/miniscript/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Hardware Wallets ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/Hardware Wallets/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/Hardware Wallets/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/Hardware%20Wallets/",key:"v-640144b2",path:"/blog/tags/Hardware Wallets/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"getting started ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/getting started/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/getting started/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/getting%20started/",key:"v-79c3de4b",path:"/blog/tags/getting started/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"rust ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/rust/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/rust/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/rust/",key:"v-3fee41ed",path:"/blog/tags/rust/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"bitcoin-cli ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin-cli/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/bitcoin-cli/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/bitcoin-cli/",key:"v-01a03a08",path:"/blog/tags/bitcoin-cli/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"coin selection ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/coin selection/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/coin selection/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/coin%20selection/",key:"v-74edfe92",path:"/blog/tags/coin selection/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"development ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/development/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/development/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/development/",key:"v-4e62fa1c",path:"/blog/tags/development/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"summer of bitcoin ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/summer of bitcoin/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/summer of bitcoin/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/summer%20of%20bitcoin/",key:"v-0159a747",path:"/blog/tags/summer of bitcoin/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"security ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/security/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/security/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/security/",key:"v-0755ed11",path:"/blog/tags/security/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"release ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/release/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/release/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/release/",key:"v-543950a6",path:"/blog/tags/release/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Steve Myers ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Steve Myers/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Steve Myers/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Steve%20Myers/",key:"v-a354115e",path:"/blog/author/Steve Myers/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Daniela Brozzoni ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Daniela Brozzoni/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Daniela Brozzoni/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Daniela%20Brozzoni/",key:"v-22d0e252",path:"/blog/author/Daniela Brozzoni/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"thunderbiscuit ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/thunderbiscuit/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/thunderbiscuit/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/thunderbiscuit/",key:"v-5d54001e",path:"/blog/author/thunderbiscuit/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Rajarshi Maitra ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Rajarshi Maitra/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Rajarshi Maitra/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Rajarshi%20Maitra/",key:"v-82e16b5c",path:"/blog/author/Rajarshi Maitra/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"waterst0ne ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/waterst0ne/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/waterst0ne/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/waterst0ne/",key:"v-3e6950f4",path:"/blog/author/waterst0ne/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Lloyd Fournier ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Lloyd Fournier/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Lloyd Fournier/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Lloyd%20Fournier/",key:"v-600b5b28",path:"/blog/author/Lloyd Fournier/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Bitcoin Zavior ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Bitcoin Zavior/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Bitcoin Zavior/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Bitcoin%20Zavior/",key:"v-37829241",path:"/blog/author/Bitcoin Zavior/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"rorp ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/rorp/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/rorp/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/rorp/",key:"v-d2b26530",path:"/blog/author/rorp/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Riccardo Casatta ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Riccardo Casatta/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Riccardo Casatta/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Riccardo%20Casatta/",key:"v-624fd61e",path:"/blog/author/Riccardo Casatta/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Gabriele Domenichini ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Gabriele Domenichini/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Gabriele Domenichini/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Gabriele%20Domenichini/",key:"v-6b564fb4",path:"/blog/author/Gabriele Domenichini/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Alekos Filini ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Alekos%20Filini/",key:"v-ad00c09c",path:"/blog/author/Alekos Filini/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Wszdexdrf ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Wszdexdrf/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Wszdexdrf/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Wszdexdrf/",key:"v-4eeab648",path:"/blog/author/Wszdexdrf/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"Sandipan Dey ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Sandipan Dey/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Sandipan Dey/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Sandipan%20Dey/",key:"v-91c10894",path:"/blog/author/Sandipan Dey/",codeSwitcherOptions:{}},{frontmatter:{layout:"FrontmatterPagination",title:"César Alvarez Vallero ",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/César Alvarez Vallero/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/César Alvarez Vallero/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/C%C3%A9sar%20Alvarez%20Vallero/",key:"v-a0d840b0",path:"/blog/author/César Alvarez Vallero/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 2",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/page/2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/page/2/",key:"v-c3507bb6",path:"/blog/page/2/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 3",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/page/3/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/page/3/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/page/3/",key:"v-c3507b78",path:"/blog/page/3/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Page 4",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/page/4/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/page/4/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/page/4/",key:"v-c3507b3a",path:"/blog/page/4/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"BDK - Page 2",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/tags/BDK/page/2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/tags/BDK/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/tags/BDK/page/2/",key:"v-73be14ce",path:"/blog/tags/BDK/page/2/",codeSwitcherOptions:{}},{frontmatter:{layout:"DirectoryPagination",title:"Alekos Filini - Page 2",meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/page/2/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:url",content:"https://bitcoindevkit.org/blog/author/Alekos Filini/page/2/"},{name:"twitter:card",content:"summary"},{name:"twitter:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:label2",content:"Filed under"},{name:"twitter:data2",content:"Bitcoin, Bitcoin Dev Kit, BDK"},{property:"article:tag",content:"Bitcoin"},{property:"article:tag",content:"Bitcoin Dev Kit"},{property:"article:tag",content:"BDK"}]},regularPath:"/blog/author/Alekos%20Filini/page/2/",key:"v-5f2ac9cb",path:"/blog/author/Alekos Filini/page/2/",codeSwitcherOptions:{}}],themeConfig:{domain:"https://bitcoindevkit.org",logo:"/img/logo.svg",displayAllHeaders:!1,repo:"bitcoindevkit/bitcoindevkit.org",docsDir:"docs",editLinks:!0,sidebarDepth:0,nav:[{text:"Docs",link:"/getting-started/"},{text:"Adoption",link:"/adoption/all.md"},{text:"Foundation",link:"/foundation/"},{text:"Blog",link:"/blog/"}],sidebar:{"/adoption/":[{title:"Built With BDK",collapsable:!1,children:[["/adoption/all.md","All"],["/adoption/mobile.md","Mobile"],["/adoption/desktop.md","Desktop"],["/adoption/hardware.md","Hardware"],["/adoption/web.md","Web"],["/adoption/custodial.md","Custodial"],["/adoption/exchange.md","Exchange"],["/adoption/infrastructure.md","Infrastructure"]]}],"/_blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/blog/":[{title:"Blog",collapsable:!1,children:[["/blog/","Articles"],["/blog/tags/","Tags"],["/blog/author/","Authors"]]}],"/foundation/":[{title:"Foundation",collapsable:!1,children:[["/foundation/about.md","About Us"],["/foundation/supporters.md","Supporters"],["/foundation/grantees.md","Grantees"],["/foundation/grants.md","Grants"],["/foundation/members.md","Members"]]}],"/":[{title:"Documentation",collapsable:!1,children:[["/getting-started","Getting Started"],{title:"BDK-CLI",collapsable:!0,children:["/bdk-cli/introduction","/bdk-cli/installation","/bdk-cli/concept","/bdk-cli/interface","/bdk-cli/regtest","/bdk-cli/compiler","/bdk-cli/playground"]},"/descriptors/","/examples/"]},{title:"API Reference",collapsable:!1,children:[["https://docs.rs/bdk_wallet/","Rust Stable Docs"],["https://bitcoindevkit.org/docs-rs/bdk/nightly/latest/bdk_wallet/","Rust Nightly Docs"],["https://bitcoindevkit.org/android/","Android Docs"],["https://bitcoindevkit.org/jvm/","Kotlin/JVM Docs"],["https://bitcoindevkit.org/java/","Java Docs"]]}]},footer:{links:[{title:"Docs",children:[{text:"Getting Started",link:"/getting-started/"},{text:"BDK-CLI",link:"/bdk-cli/installation/"},{text:"Descriptors",link:"/descriptors/"}]},{title:"Community",children:[{text:"GitHub",link:"https://github.com/bitcoindevkit",rel:"noopener noreferrer"},{text:"Nostr",link:"nostr:npub13dk3dke4zm9vdkucm7f6vv7vhqgkevgg3gju9kr2wzumz7nrykdq0dgnvc",rel:"noopener noreferrer"},{text:"Twitter",link:"https://twitter.com/intent/follow?screen_name=bitcoindevkit",rel:"noopener noreferrer"},{text:"Chat on Discord",link:"https://discord.gg/dstn4dQ",rel:"noopener noreferrer"}]},{title:"More",children:[{text:"Blog",link:"/blog/"},{text:"Supporters",link:"/foundation/supporters/"},{text:"BDK Foundation",link:"/foundation/"}]}],copyright:"Copyright © 2024 BDK Developers"}}},{COLOR_MODES:$c,STORE_ATTR:jc,setColorMode:Mc}=n(111),Rc=t=>"Enter"===t.code||13===(t.keyCode||t.which),Ic=t=>{const e=t.target.matches("#algolia-search-input")&&Rc(t);(t.target.matches(".ds-dropdown-menu *")||e)&&document.getElementById("algolia-search-input").blur(),t.target.matches(".ytEmbed")&&(t.preventDefault(),(t=>{const e=t.querySelector("iframe[data-src]");if(e){const t=e.getAttribute("data-src");e.setAttribute("src",t)}})(t.target))};if("undefined"==typeof process||"server"!==process.env.VUE_ENV){const t=window.matchMedia("(prefers-color-scheme: dark)").matches?$c[1]:$c[0],e=window.localStorage.getItem(jc);Mc($c.includes(e)?e:t)}n(242);Vn.component("Badge",()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,397))),Vn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,387))),Vn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,388)));n(243);var Uc={props:{color:{required:!1,default:"rgb(66, 185, 131)"}}},Nc=(n(244),Object(Sc.a)(Uc,(function(){return(0,this._self._c)("div",{staticClass:"spinner",style:{background:this.color}})}),[],!1,null,"1bbcb91a",null).exports);const Lc={name:"Mermaid",props:{id:{type:String,required:!0},graph:{type:String,required:!0}},data:()=>({svg:void 0}),render(t){return void 0===this.svg?t("Loading"):t("div",{domProps:{innerHTML:this.svg,style:"width: 100%"}})},mounted(){n.e(99).then(n.t.bind(null,383,7)).then(t=>{t.initialize({startOnLoad:!0});let e=document.createElement("div");document.body.appendChild(e),t.render(this.id,this.graph,t=>{this.svg=t,document.body.removeChild(e)},e)})},components:{Loading:Nc}};var Wc=n(94),zc=n.n(Wc);n(245);Vn.component("CodeSwitcher",()=>n.e(44).then(n.bind(null,396)));var qc={tags:{BDK:{key:"BDK",scope:"tags",path:"/blog/tags/BDK/",pageKeys:["v-2c450c3f","v-5e744cf7","v-bac76d8e","v-609f26f9","v-7c0c45f9","v-62ca00fb","v-3875825f","v-07ff1843","v-9145467a","v-2cf72b39","v-11d64359","v-d0375c8e","v-aeb70fce"]},project:{key:"project",scope:"tags",path:"/blog/tags/project/",pageKeys:["v-2c450c3f","v-5e744cf7","v-609f26f9","v-62ca00fb"]},grants:{key:"grants",scope:"tags",path:"/blog/tags/grants/",pageKeys:["v-bac76d8e"]},tutorial:{key:"tutorial",scope:"tags",path:"/blog/tags/tutorial/",pageKeys:["v-7c0c45f9","v-8bd632d6","v-353b78e1","v-07ff1843","v-f58ec8f2","v-56536559","v-ab5ba3ce"]},"Bitcoin Core":{key:"Bitcoin Core",scope:"tags",path:"/blog/tags/Bitcoin Core/",pageKeys:["v-7c0c45f9"]},RPC:{key:"RPC",scope:"tags",path:"/blog/tags/RPC/",pageKeys:["v-7c0c45f9"]},Wallet:{key:"Wallet",scope:"tags",path:"/blog/tags/Wallet/",pageKeys:["v-7c0c45f9"]},"bdk-cli":{key:"bdk-cli",scope:"tags",path:"/blog/tags/bdk-cli/",pageKeys:["v-8bd632d6","v-0f4d5d15","v-07ff1843","v-ab5ba3ce"]},"multi-sig":{key:"multi-sig",scope:"tags",path:"/blog/tags/multi-sig/",pageKeys:["v-8bd632d6"]},basics:{key:"basics",scope:"tags",path:"/blog/tags/basics/",pageKeys:["v-0f4d5d15"]},novice:{key:"novice",scope:"tags",path:"/blog/tags/novice/",pageKeys:["v-0f4d5d15"]},architecture:{key:"architecture",scope:"tags",path:"/blog/tags/architecture/",pageKeys:["v-2cebe183","v-55969f39"]},"BDK-RN":{key:"BDK-RN",scope:"tags",path:"/blog/tags/BDK-RN/",pageKeys:["v-3eaa044d"]},Development:{key:"Development",scope:"tags",path:"/blog/tags/Development/",pageKeys:["v-3eaa044d","v-11d64359","v-aeb70fce"]},Architecture:{key:"Architecture",scope:"tags",path:"/blog/tags/Architecture/",pageKeys:["v-3eaa044d"]},tor:{key:"tor",scope:"tags",path:"/blog/tags/tor/",pageKeys:["v-353b78e1"]},wallet:{key:"wallet",scope:"tags",path:"/blog/tags/wallet/",pageKeys:["v-353b78e1","v-f58ec8f2","v-56536559"]},blockchain:{key:"blockchain",scope:"tags",path:"/blog/tags/blockchain/",pageKeys:["v-353b78e1"]},bindings:{key:"bindings",scope:"tags",path:"/blog/tags/bindings/",pageKeys:["v-3875825f","v-4dc135e3"]},compact_filters:{key:"compact_filters",scope:"tags",path:"/blog/tags/compact_filters/",pageKeys:["v-07ff1843"]},BIP157:{key:"BIP157",scope:"tags",path:"/blog/tags/BIP157/",pageKeys:["v-07ff1843"]},Neutrino:{key:"Neutrino",scope:"tags",path:"/blog/tags/Neutrino/",pageKeys:["v-07ff1843"]},guide:{key:"guide",scope:"tags",path:"/blog/tags/guide/",pageKeys:["v-9504490e","v-c6756cce","v-f58ec8f2","v-56536559","v-8534b9c2"]},descriptor:{key:"descriptor",scope:"tags",path:"/blog/tags/descriptor/",pageKeys:["v-9504490e","v-c6756cce","v-ab5ba3ce","v-8534b9c2"]},"paper wallets":{key:"paper wallets",scope:"tags",path:"/blog/tags/paper wallets/",pageKeys:["v-9504490e"]},bitcoin:{key:"bitcoin",scope:"tags",path:"/blog/tags/bitcoin/",pageKeys:["v-f58ec8f2","v-56536559"]},"React Native":{key:"React Native",scope:"tags",path:"/blog/tags/React Native/",pageKeys:["v-f58ec8f2","v-56536559"]},iOS:{key:"iOS",scope:"tags",path:"/blog/tags/iOS/",pageKeys:["v-f58ec8f2","v-56536559"]},Android:{key:"Android",scope:"tags",path:"/blog/tags/Android/",pageKeys:["v-f58ec8f2","v-56536559"]},mobile:{key:"mobile",scope:"tags",path:"/blog/tags/mobile/",pageKeys:["v-f58ec8f2","v-56536559"]},"bdk-rn":{key:"bdk-rn",scope:"tags",path:"/blog/tags/bdk-rn/",pageKeys:["v-f58ec8f2","v-56536559"]},bdk:{key:"bdk",scope:"tags",path:"/blog/tags/bdk/",pageKeys:["v-f58ec8f2","v-56536559","v-ab5ba3ce"]},Flutter:{key:"Flutter",scope:"tags",path:"/blog/tags/Flutter/",pageKeys:["v-56536559"]},fee:{key:"fee",scope:"tags",path:"/blog/tags/fee/",pageKeys:["v-2c605799","v-57698579","v-015729b9"]},"machine learning":{key:"machine learning",scope:"tags",path:"/blog/tags/machine learning/",pageKeys:["v-2c605799","v-57698579","v-015729b9"]},taproot:{key:"taproot",scope:"tags",path:"/blog/tags/taproot/",pageKeys:["v-9145467a","v-2cf72b39"]},miniscript:{key:"miniscript",scope:"tags",path:"/blog/tags/miniscript/",pageKeys:["v-9145467a","v-2cf72b39","v-ab5ba3ce","v-10852eea"]},"Hardware Wallets":{key:"Hardware Wallets",scope:"tags",path:"/blog/tags/Hardware Wallets/",pageKeys:["v-11d64359","v-aeb70fce"]},"getting started":{key:"getting started",scope:"tags",path:"/blog/tags/getting started/",pageKeys:["v-5d749fce"]},rust:{key:"rust",scope:"tags",path:"/blog/tags/rust/",pageKeys:["v-5d749fce","v-05df4999","v-edd5570e","v-0119984e","v-faad828e","v-7c3d28f9","v-0df1c3ce","v-75d11339","v-1ac9ef4e"]},"bitcoin-cli":{key:"bitcoin-cli",scope:"tags",path:"/blog/tags/bitcoin-cli/",pageKeys:["v-ab5ba3ce"]},"coin selection":{key:"coin selection",scope:"tags",path:"/blog/tags/coin selection/",pageKeys:["v-d0375c8e"]},development:{key:"development",scope:"tags",path:"/blog/tags/development/",pageKeys:["v-d0375c8e"]},"summer of bitcoin":{key:"summer of bitcoin",scope:"tags",path:"/blog/tags/summer of bitcoin/",pageKeys:["v-d0375c8e"]},security:{key:"security",scope:"tags",path:"/blog/tags/security/",pageKeys:["v-10852eea"]},release:{key:"release",scope:"tags",path:"/blog/tags/release/",pageKeys:["v-05df4999","v-edd5570e","v-0119984e","v-faad828e","v-7c3d28f9","v-0df1c3ce","v-75d11339","v-1ac9ef4e"]}},author:{"Steve Myers":{key:"Steve Myers",scope:"author",path:"/blog/author/Steve Myers/",pageKeys:["v-2c450c3f","v-5e744cf7","v-bac76d8e","v-9504490e","v-8534b9c2"]},"Daniela Brozzoni":{key:"Daniela Brozzoni",scope:"author",path:"/blog/author/Daniela Brozzoni/",pageKeys:["v-2c450c3f","v-aeb70fce"]},thunderbiscuit:{key:"thunderbiscuit",scope:"author",path:"/blog/author/thunderbiscuit/",pageKeys:["v-609f26f9","v-62ca00fb","v-3875825f","v-4dc135e3","v-8534b9c2"]},"Rajarshi Maitra":{key:"Rajarshi Maitra",scope:"author",path:"/blog/author/Rajarshi Maitra/",pageKeys:["v-7c0c45f9","v-07ff1843","v-ab5ba3ce"]},waterst0ne:{key:"waterst0ne",scope:"author",path:"/blog/author/waterst0ne/",pageKeys:["v-8bd632d6","v-0f4d5d15"]},"Lloyd Fournier":{key:"Lloyd Fournier",scope:"author",path:"/blog/author/Lloyd Fournier/",pageKeys:["v-2cebe183"]},"Bitcoin Zavior":{key:"Bitcoin Zavior",scope:"author",path:"/blog/author/Bitcoin Zavior/",pageKeys:["v-3eaa044d","v-f58ec8f2","v-56536559"]},rorp:{key:"rorp",scope:"author",path:"/blog/author/rorp/",pageKeys:["v-353b78e1"]},"Riccardo Casatta":{key:"Riccardo Casatta",scope:"author",path:"/blog/author/Riccardo Casatta/",pageKeys:["v-9504490e","v-2c605799","v-57698579","v-015729b9"]},"Gabriele Domenichini":{key:"Gabriele Domenichini",scope:"author",path:"/blog/author/Gabriele Domenichini/",pageKeys:["v-c6756cce"]},"Alekos Filini":{key:"Alekos Filini",scope:"author",path:"/blog/author/Alekos Filini/",pageKeys:["v-9145467a","v-2cf72b39","v-5d749fce","v-10852eea","v-05df4999","v-edd5570e","v-0119984e","v-faad828e","v-7c3d28f9","v-0df1c3ce","v-75d11339","v-1ac9ef4e","v-55969f39"]},Wszdexdrf:{key:"Wszdexdrf",scope:"author",path:"/blog/author/Wszdexdrf/",pageKeys:["v-11d64359"]},"Sandipan Dey":{key:"Sandipan Dey",scope:"author",path:"/blog/author/Sandipan Dey/",pageKeys:["v-ab5ba3ce"]},"César Alvarez Vallero":{key:"César Alvarez Vallero",scope:"author",path:"/blog/author/César Alvarez Vallero/",pageKeys:["v-d0375c8e"]}}};class Hc{constructor(t,e){this._metaMap=Object.assign({},t),Object.keys(this._metaMap).forEach(t=>{const{pageKeys:n}=this._metaMap[t];this._metaMap[t].pages=n.map(t=>function(t,e){for(let n=0;n{const{pages:n,path:i}=this._metaMap[e];t.push({name:e,pages:n,path:i})}),t}getItemByName(t){return this._metaMap[t]}}var Vc={blog:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},tags:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1},author:(t,e)=>{const i=n(45);return i(t.frontmatter.date)-i(e.frontmatter.date)>0?-1:1}},Gc={blog:function(t,e,n){return t.pid===n&&t.id===e},tags:function(t,e,n){const i=e;return["tags"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})},author:function(t,e,n){const i=e;return["author","authors"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==i):n==i})}},Zc=[{pid:"blog",id:"blog",filter:Gc.blog,sorter:Vc.blog,pages:[{path:"/blog/",interval:[0,9]},{path:"/blog/page/2/",interval:[10,19]},{path:"/blog/page/3/",interval:[20,29]},{path:"/blog/page/4/",interval:[30,39]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/BDK/",interval:[0,9]},{path:"/blog/tags/BDK/page/2/",interval:[10,13]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"project",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/project/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"grants",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/grants/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tutorial",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/tutorial/",interval:[0,7]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Bitcoin Core",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Bitcoin Core/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"RPC",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/RPC/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Wallet",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Wallet/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-cli",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bdk-cli/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"multi-sig",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/multi-sig/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"basics",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/basics/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"novice",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/novice/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"architecture",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/architecture/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK-RN",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/BDK-RN/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Development",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Development/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Architecture",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Architecture/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tor",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/tor/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"wallet",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/wallet/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"blockchain",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/blockchain/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bindings",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bindings/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"compact_filters",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/compact_filters/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BIP157",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/BIP157/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Neutrino",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Neutrino/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"guide",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/guide/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"descriptor",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/descriptor/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"paper wallets",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/paper wallets/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bitcoin/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"React Native",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/React Native/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"iOS",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/iOS/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Android",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Android/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"mobile",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/mobile/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-rn",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bdk-rn/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bdk/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Flutter",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Flutter/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"fee",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/fee/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"machine learning",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/machine learning/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"taproot",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/taproot/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"miniscript",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/miniscript/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Hardware Wallets",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/Hardware Wallets/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"getting started",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/getting started/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"rust",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/rust/",interval:[0,9]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin-cli",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/bitcoin-cli/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"coin selection",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/coin selection/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"development",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/development/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"summer of bitcoin",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/summer of bitcoin/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"security",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/security/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"release",filter:Gc.tags,sorter:Vc.tags,pages:[{path:"/blog/tags/release/",interval:[0,8]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Steve Myers",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Steve Myers/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Daniela Brozzoni",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Daniela Brozzoni/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"thunderbiscuit",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/thunderbiscuit/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Rajarshi Maitra",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Rajarshi Maitra/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"waterst0ne",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/waterst0ne/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Lloyd Fournier",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Lloyd Fournier/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Bitcoin Zavior",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Bitcoin Zavior/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"rorp",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/rorp/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Riccardo Casatta",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Riccardo Casatta/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Gabriele Domenichini",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Gabriele Domenichini/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Alekos Filini",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Alekos Filini/",interval:[0,9]},{path:"/blog/author/Alekos Filini/page/2/",interval:[10,13]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Wszdexdrf",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Wszdexdrf/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Sandipan Dey",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/Sandipan Dey/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"César Alvarez Vallero",filter:Gc.author,sorter:Vc.author,pages:[{path:"/blog/author/César Alvarez Vallero/",interval:[0,1]}],prevText:"Prev",nextText:"Next"}],Qc=n(95);const Xc=n.n(Qc)()("plugin-blog:pagination");class Jc{constructor(t,e,n){Xc("pagination",t);const{pages:i,prevText:o,nextText:r}=t,{path:a}=n;this._prevText=o,this._nextText=r;for(let t=0,e=i.length;tt.filter(e,t.id,t.pid)).sort(t.sorter)}setIndexPage(t){this._indexPage=t}get length(){return this._paginationPages.length}get pages(){const[t,e]=this._currentPage.interval;return this._matchedPages.slice(t,e+1)}get hasPrev(){return 0!==this.paginationIndex}get prevLink(){return this.hasPrev?this.paginationIndex-1==0&&this._indexPage?this._indexPage:this._paginationPages[this.paginationIndex-1].path:null}get hasNext(){return this.paginationIndex!==this.length-1}get nextLink(){return this.hasNext?this._paginationPages[this.paginationIndex+1].path:null}get prevText(){return this._prevText}get nextText(){return this._nextText}getSpecificPageLink(t){return this._paginationPages[t].path}}const Yc=new class{constructor(t){this.paginations=t}get pages(){return Vn.$vuepress.$get("siteData").pages}getPagination(t,e,n){Xc("id",e),Xc("pid",t);const i=this.paginations.filter(n=>n.id===e&&n.pid===t)[0];return new Jc(i,this.pages,n)}}(Zc);var tl={comment:{enabled:!1,service:""},email:{enabled:!1},feed:{rss:!1,atom:!1,json:!1}},el=[({router:t})=>{"undefined"!=typeof process&&"server"===process.env.VUE_ENV||t.onReady(()=>{const{app:e}=t;e.$once("hook:mounted",()=>{setTimeout(()=>{const{hash:t}=document.location;if(t.length>1){const e=t.substring(1),n=document.getElementById(e);n&&n.scrollIntoView()}},500)}),document.addEventListener("click",Ic),document.addEventListener("keyup",t=>{Rc(t)&&Ic(t)})})},{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({Vue:t})=>{t.component("CodeCopy",Tc)},({Vue:t})=>{t.component("Mermaid",Lc)},({Vue:t})=>t.use(zc.a),{},{},({Vue:t})=>{const e=Object.keys(qc).map(t=>{const e=qc[t],n="$"+t;return{[n](){const{pages:t}=this.$site;return new Hc(e,t)},["$current"+(t.charAt(0).toUpperCase()+t.slice(1))](){const t=this.$route.meta.id;return this[n].getItemByName(t)}}}).reduce((t,e)=>(Object.assign(t,e),t),{});e.$frontmatterKey=function(){const t=this["$"+this.$route.meta.id];return t||null},t.mixin({computed:e})},({Vue:t})=>{t.mixin({computed:{$pagination(){return this.$route.meta.pid&&this.$route.meta.id?this.$getPagination(this.$route.meta.pid,this.$route.meta.id):null}},methods:{$getPagination(t,e){return e=e||t,Yc.getPagination(t,e,this.$route)}}})},({Vue:t})=>{const e={$service:()=>tl};t.mixin({computed:e})}],nl=[];class il extends class{constructor(){this.store=new Vn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Vn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(il.prototype,{getPageAsyncComponent:cc,getLayoutAsyncComponent:lc,getAsyncComponent:sc,getVueComponent:pc});var ol={install(t){const e=new il;t.$vuepress=e,t.prototype.$vuepress=e}};function rl(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var al={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return uc("pageKey",e),Vn.component(e)||Vn.component(e,cc(e)),Vn.component(e)?t(e):t("")}},cl={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},ll={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},sl=(n(248),n(249),Object(Sc.a)(ll,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),pl={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Vn.config.productionTip=!1,Vn.use(qa),Vn.use(ol),Vn.mixin(function(t,e,n=Vn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const i=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(i)),r={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),r),{computed:r}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const i in t)"/"===i?n=t[i]:0===this.$page.path.indexOf(i)&&(e=t[i]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,i=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?i?i+" | "+n:n:i||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Vn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,i)=>{if(rl(t,e.path))i();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";rl(t,n)?i(n):i()}else i();else{const n=e.path+"/",o=e.path+".html";rl(t,o)?i(o):rl(t,n)?i(n):i()}})}(n);const i={};try{await Promise.all(el.filter(t=>"function"==typeof t).map(e=>e({Vue:Vn,options:i,router:n,siteData:Ec,isServer:t})))}catch(t){console.error(t)}return{app:new Vn(Object.assign(i,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},nl.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file diff --git a/bdk-cli/compiler/index.html b/bdk-cli/compiler/index.html index dac364f4de..7df592f486 100644 --- a/bdk-cli/compiler/index.html +++ b/bdk-cli/compiler/index.html @@ -35,7 +35,7 @@ - + @@ -155,7 +155,7 @@ } }

# Troubleshooting

# Nothing is printed

This might mean that you have a RUST_LOG variable set to a value that suppresses the compiler's log. You can try adding miniscriptc=info to your RUST_LOG value and see if that works, or open a new clean -shell.

Last Updated: 11/21/2024, 4:44:27 PM
Last Updated: 11/18/2024, 8:15:46 PM
- + diff --git a/bdk-cli/concept/index.html b/bdk-cli/concept/index.html index 7231ba0c38..6134f36fc5 100644 --- a/bdk-cli/concept/index.html +++ b/bdk-cli/concept/index.html @@ -31,7 +31,7 @@ - + @@ -62,7 +62,7 @@ will never contain any data that can't be recreated purely by looking at the blockchain. Keys, descriptors, Electrum endpoints are not stored in the database. This explains why you'll have to specify them every time in the command line. It can be seen more like a cache and can be safely deleted without risking funds.
  • BDK doesn't automatically "monitor" the blockchain, instead there's a sync command that has to be called by the user.
  • When you create a transaction and then sign it, it's not automatically broadcast to the network. There's a broadcast command that does this. Moreover, the command doesn't accept a normal Bitcoin raw transaction, but instead a PSBT. That's because internally transactions are always moved as PSBTs, and again, the broadcast command is just a very thin wrapper over the raw library call.
  • There are probably more of these examples, but hopefully by this point you'll have more or less understood the gist of it. If you are not a developer, some parts of this will feel weird, inefficient, hard -to understand, and that's absolutely normal. Just try to survive through the pain and you'll be rewarded!

    Last Updated: 11/21/2024, 4:44:27 PM
    Last Updated: 11/18/2024, 8:15:46 PM
    - + diff --git a/bdk-cli/installation/index.html b/bdk-cli/installation/index.html index 42f2110b61..1d855419cd 100644 --- a/bdk-cli/installation/index.html +++ b/bdk-cli/installation/index.html @@ -35,7 +35,7 @@ - + @@ -106,7 +106,7 @@ wallet Wallet Operations

    An example command to sync a testnet wallet to a default electrum server looks like this:

    bdk-cli wallet -w example --descriptor "wpkh(tprv8ZgxMBicQKsPexGYyaFwnAsCXCjmz2FaTm6LtesyyihjbQE3gRMfXqQBXKM43DvC1UgRVv1qom1qFxNMSqVAs88qx9PhgFnfGVUdiiDf6j4/0/*)" sync
    -
    Last Updated: 11/21/2024, 4:44:27 PM
    Last Updated: 11/18/2024, 8:15:46 PM
    - + diff --git a/bdk-cli/interface/index.html b/bdk-cli/interface/index.html index 17985d9da1..5617002c61 100644 --- a/bdk-cli/interface/index.html +++ b/bdk-cli/interface/index.html @@ -29,7 +29,7 @@ - + @@ -364,7 +364,7 @@ --psbt <BASE64_PSBT> Sets the PSBT to sign --assume_height <HEIGHT> Assume the blockchain has reached a specific height. This affects the transaction finalization, if there are timelocks in the descriptor --trust_witness_utxo <WITNESS> Whether the signer should trust the witness_utxo, if the non_witness_utxo hasn’t been provided -

    Adds to the PSBT all the signatures it can produce with the secrets embedded in the descriptor (xprv or WIF keys). Returns the signed PSBT and, if there are enough item to satisfy the script, also the extracted raw Bitcoin transaction.

    Optionally, the --assume_height option can be specified to let the wallet assume the blockchain has reached a specific height. This affects the finalization of the PSBT which is done right at the end of the signing process: the wallet tries to satisfy the spending condition of each input using the partial signatures collected. In case timelocks are present the wallet needs to know whether or not they have expired. This flag is particularly useful for offline wallets.

    # sync

    This subcommand has no extra flags. It connects to the chosen Electrum server and synchronizes the list of transactions received and available UTXOs.

    Last Updated: 11/21/2024, 4:44:27 PM

    Adds to the PSBT all the signatures it can produce with the secrets embedded in the descriptor (xprv or WIF keys). Returns the signed PSBT and, if there are enough item to satisfy the script, also the extracted raw Bitcoin transaction.

    Optionally, the --assume_height option can be specified to let the wallet assume the blockchain has reached a specific height. This affects the finalization of the PSBT which is done right at the end of the signing process: the wallet tries to satisfy the spending condition of each input using the partial signatures collected. In case timelocks are present the wallet needs to know whether or not they have expired. This flag is particularly useful for offline wallets.

    # sync

    This subcommand has no extra flags. It connects to the chosen Electrum server and synchronizes the list of transactions received and available UTXOs.

    Last Updated: 11/18/2024, 8:15:46 PM
    - + diff --git a/bdk-cli/introduction/index.html b/bdk-cli/introduction/index.html index 0ed59863a0..bcd11f0254 100644 --- a/bdk-cli/introduction/index.html +++ b/bdk-cli/introduction/index.html @@ -29,7 +29,7 @@ - + @@ -53,7 +53,7 @@ Blog GitHub - (opens new window)

    # Introduction

    bdk-cli (opens new window) is a lightweight repl (opens new window) wrapper over bdk that comes as a command line application. It is useful for quick testing and prototyping of bdk functionalities.

    This can also be used as an example application to create your own command line bitcoin wallet tool using bdk.

    bdk-cli can interface with all the blockchain backends currently supported by bdk, like rpc, electrum, esplora and compact_filters.

    Check out project documentation (opens new window) for more details.

    The following sections goes into more details on the installation and usage of bdk-cli.

    Last Updated: 11/21/2024, 4:44:27 PM
    - + diff --git a/bdk-cli/playground/index.html b/bdk-cli/playground/index.html index 68dc87b90b..33ffd4f40c 100644 --- a/bdk-cli/playground/index.html +++ b/bdk-cli/playground/index.html @@ -27,7 +27,7 @@ - + @@ -51,7 +51,7 @@ Blog GitHub - (opens new window)

    # Playground

    Last Updated: 11/21/2024, 4:44:27 PM
    - + diff --git a/bdk-cli/regtest/index.html b/bdk-cli/regtest/index.html index 07a9257de1..351ab084ee 100644 --- a/bdk-cli/regtest/index.html +++ b/bdk-cli/regtest/index.html @@ -31,7 +31,7 @@ - + @@ -60,7 +60,7 @@

    Just like before, this command will probably take a while to finish.

    Once it's done, assuming you have a regtest bitcoind running in background, you can launch a new terminal and run the following command to actually start electrs:

    electrs --log-filters INFO --timestamp --db-dir /tmp/electrs-db --electrum-rpc-addr="127.0.0.1:50001" --network=regtest --cookie-file=$HOME/.bitcoin/regtest/.cookie
     

    on macOS you should change the cookie-file to $HOME/Library/Application Support/Bitcoin/regtest/.cookie.

    This will start the Electrum server on port 50001. You can then add the -n regtest -s 127.0.0.1:50001 to the bdk-cli commands to switch to the local regtest.

    # Troubleshooting

    # Stuck with "wait until bitcoind is synced (i.e. initialblockdownload = false)"

    Just generate a few blocks with bitcoin-cli generatetoaddress 1 <address>

    # Bonus: Docker

    If you have already installed Docker on your machine, you can also use 🍣 Nigiri CLI (opens new window) to spin-up a complete development environment in regtest that includes a bitcoin node, an electrs explorer and the esplora (opens new window) web-app to visualize blocks and transactions in the browser.

    Install 🍣 Nigiri

    $ curl https://getnigiri.vulpem.com | bash
     

    Start Docker daemon and run Nigiri box

    $ nigiri start
    -

    This will start electrum RPC interface on port 51401, the REST interface on 3000 and the esplora UI on 5000 (You can visit with the browser and look for blocks, addresses and transactions)

    You can then add the -n regtest -s 127.0.0.1:51401 to the bdk-cli commands to switch to the local regtest.

    Last Updated: 11/21/2024, 4:44:27 PM

    This will start electrum RPC interface on port 51401, the REST interface on 3000 and the esplora UI on 5000 (You can visit with the browser and look for blocks, addresses and transactions)

    You can then add the -n regtest -s 127.0.0.1:51401 to the bdk-cli commands to switch to the local regtest.

    Last Updated: 11/18/2024, 8:15:46 PM
    - + diff --git a/blog/2020/12/hello-world/index.html b/blog/2020/12/hello-world/index.html index 01e4ac422b..6c4db9e2b8 100644 --- a/blog/2020/12/hello-world/index.html +++ b/blog/2020/12/hello-world/index.html @@ -30,7 +30,7 @@ - + @@ -147,7 +147,7 @@ txid = txid );

    # Custom Database and Blockchain types

    We briefly mentioned before that for our example we used the MemoryDatabase, but that it could also be swapped for a different one: this is one example of the modularity of BDK. By default, some database types are already implemented in the library, namely the MemoryDatabase (opens new window) which only keeps data in RAM, the Sled (opens new window) database that can store data on a filesystem, and the SqliteDatabase (opens new window) that can store data into a SQLite database. But since the Database trait is public, users of the library can also implement different database types more suitable for their use-case.

    The same is true for the Blockchain types: the library provides (through the use of opt-in features) implementations for the Electrum, Esplora, CompactFilters (Neutrino) and Bitcoin Core rpc backends. Those again can also be -swapped with custom types if the user desires to do so.

    # Conclusion

    Hopefully, this article will help you get started with BDK! This is just a very quick and gentle introduction to the library, and only barely scratches the surface of what's inside: we will keep publishing more articles in the future to explain some of the more advanced features of BDK, like key generation, using complex descriptors with multiple keys and/or timelocks, using external signers, etc.

    If you'd like to learn more about the library feel free to ask any questions in the comment section down below, or join our Discord Community (opens new window) to chat with us directly!

    Last Updated: 11/21/2024, 4:44:27 PM
    - + diff --git a/blog/2020/12/release-v0.2.0/index.html b/blog/2020/12/release-v0.2.0/index.html index d36923613b..66877ead3d 100644 --- a/blog/2020/12/release-v0.2.0/index.html +++ b/blog/2020/12/release-v0.2.0/index.html @@ -30,7 +30,7 @@ - + @@ -128,7 +128,7 @@ .map_err(|e| KeyError::Message(e.to_string()))?) } } -

    # Support for sortedmulti()

    Thanks to the addition of sortedmulti() in rust-miniscript, we can now also support them in BDK, which means we are getting more and more compatible with other descriptor-based wallets out there like Bitcoin Core.

    # Contributors

    A huge thanks to everybody who contributed to this new release with suggestions, pull requests and bug reports.

    Since the 0.1.0-beta.1 release over three months ago, we've had 213 new commits made by 10 different contributors for a total of 9990 additions and 2993 deletions. Here's the full diff (opens new window).

    A special thanks to the 7 new contributors:

    Last Updated: 11/21/2024, 4:44:27 PM
    - + diff --git a/blog/tags/bdk/index.html b/blog/tags/bdk/index.html index ba4be37d5c..c2305b6c3b 100644 --- a/blog/tags/bdk/index.html +++ b/blog/tags/bdk/index.html @@ -25,7 +25,7 @@ - + @@ -180,6 +180,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bindings/index.html b/blog/tags/bindings/index.html index e50f90aefc..38f20b43ab 100644 --- a/blog/tags/bindings/index.html +++ b/blog/tags/bindings/index.html @@ -25,7 +25,7 @@ - + @@ -92,6 +92,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bitcoin-cli/index.html b/blog/tags/bitcoin-cli/index.html index 67bc02e437..8f9715e3d4 100644 --- a/blog/tags/bitcoin-cli/index.html +++ b/blog/tags/bitcoin-cli/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bitcoin/index.html b/blog/tags/bitcoin/index.html index fdc524cd2c..8e07c15cdc 100644 --- a/blog/tags/bitcoin/index.html +++ b/blog/tags/bitcoin/index.html @@ -25,7 +25,7 @@ - + @@ -92,6 +92,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/blockchain/index.html b/blog/tags/blockchain/index.html index bc7ba77f78..a7ddaa4536 100644 --- a/blog/tags/blockchain/index.html +++ b/blog/tags/blockchain/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/coin selection/index.html b/blog/tags/coin selection/index.html index 4d124cb7b6..2b6d418fd8 100644 --- a/blog/tags/coin selection/index.html +++ b/blog/tags/coin selection/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/compact_filters/index.html b/blog/tags/compact_filters/index.html index 1268f14cc8..5a62509f0f 100644 --- a/blog/tags/compact_filters/index.html +++ b/blog/tags/compact_filters/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/descriptor/index.html b/blog/tags/descriptor/index.html index ffa9db7b09..7f6195e8cd 100644 --- a/blog/tags/descriptor/index.html +++ b/blog/tags/descriptor/index.html @@ -25,7 +25,7 @@ - + @@ -114,6 +114,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/development/index.html b/blog/tags/development/index.html index 7b3fe24acc..4cde891065 100644 --- a/blog/tags/development/index.html +++ b/blog/tags/development/index.html @@ -25,7 +25,7 @@ - + @@ -103,6 +103,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/fee/index.html b/blog/tags/fee/index.html index f65986e202..b200977bce 100644 --- a/blog/tags/fee/index.html +++ b/blog/tags/fee/index.html @@ -25,7 +25,7 @@ - + @@ -49,7 +49,7 @@ Blog GitHub - (opens new window)
    - + diff --git a/blog/tags/getting started/index.html b/blog/tags/getting started/index.html index 6ae63a2de5..370c0106c1 100644 --- a/blog/tags/getting started/index.html +++ b/blog/tags/getting started/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/grants/index.html b/blog/tags/grants/index.html index 10637caa3d..941e3f43cf 100644 --- a/blog/tags/grants/index.html +++ b/blog/tags/grants/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/guide/index.html b/blog/tags/guide/index.html index 6dae6ff0a7..9dc17a5767 100644 --- a/blog/tags/guide/index.html +++ b/blog/tags/guide/index.html @@ -25,7 +25,7 @@ - + @@ -125,6 +125,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/iOS/index.html b/blog/tags/iOS/index.html index 05c3041310..8e88802c89 100644 --- a/blog/tags/iOS/index.html +++ b/blog/tags/iOS/index.html @@ -25,7 +25,7 @@ - + @@ -92,6 +92,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/index.html b/blog/tags/index.html index c83eade296..af09eb2c25 100644 --- a/blog/tags/index.html +++ b/blog/tags/index.html @@ -25,7 +25,7 @@ - + @@ -49,7 +49,7 @@ Blog GitHub - (opens new window)
    - + diff --git a/blog/tags/miniscript/index.html b/blog/tags/miniscript/index.html index b96c4e4123..1e152eb6f7 100644 --- a/blog/tags/miniscript/index.html +++ b/blog/tags/miniscript/index.html @@ -25,7 +25,7 @@ - + @@ -114,6 +114,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/mobile/index.html b/blog/tags/mobile/index.html index 4cd0be3761..c23f9efba3 100644 --- a/blog/tags/mobile/index.html +++ b/blog/tags/mobile/index.html @@ -25,7 +25,7 @@ - + @@ -92,6 +92,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/multi-sig/index.html b/blog/tags/multi-sig/index.html index 8709593885..701f06e128 100644 --- a/blog/tags/multi-sig/index.html +++ b/blog/tags/multi-sig/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/novice/index.html b/blog/tags/novice/index.html index 15546e1223..ea5d57cff9 100644 --- a/blog/tags/novice/index.html +++ b/blog/tags/novice/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/paper wallets/index.html b/blog/tags/paper wallets/index.html index c23a3a7977..fd7f270540 100644 --- a/blog/tags/paper wallets/index.html +++ b/blog/tags/paper wallets/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/project/index.html b/blog/tags/project/index.html index a875df9520..315879297a 100644 --- a/blog/tags/project/index.html +++ b/blog/tags/project/index.html @@ -25,7 +25,7 @@ - + @@ -114,6 +114,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/release/index.html b/blog/tags/release/index.html index 4cb3a74be9..38c467c3c0 100644 --- a/blog/tags/release/index.html +++ b/blog/tags/release/index.html @@ -25,7 +25,7 @@ - + @@ -158,6 +158,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/rust/index.html b/blog/tags/rust/index.html index 9a16e80001..96a9d26f81 100644 --- a/blog/tags/rust/index.html +++ b/blog/tags/rust/index.html @@ -25,7 +25,7 @@ - + @@ -169,6 +169,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/security/index.html b/blog/tags/security/index.html index cbaa7c85c6..27bd344ce4 100644 --- a/blog/tags/security/index.html +++ b/blog/tags/security/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/summer of bitcoin/index.html b/blog/tags/summer of bitcoin/index.html index 02466264bc..d88ad1f506 100644 --- a/blog/tags/summer of bitcoin/index.html +++ b/blog/tags/summer of bitcoin/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/taproot/index.html b/blog/tags/taproot/index.html index aa7e47fc9e..1f4265a094 100644 --- a/blog/tags/taproot/index.html +++ b/blog/tags/taproot/index.html @@ -25,7 +25,7 @@ - + @@ -92,6 +92,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/tor/index.html b/blog/tags/tor/index.html index 24b0b91c62..28573e989e 100644 --- a/blog/tags/tor/index.html +++ b/blog/tags/tor/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/tutorial/index.html b/blog/tags/tutorial/index.html index a445992145..7078592d9e 100644 --- a/blog/tags/tutorial/index.html +++ b/blog/tags/tutorial/index.html @@ -25,7 +25,7 @@ - + @@ -147,6 +147,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/wallet/index.html b/blog/tags/wallet/index.html index 12442be077..2d0192dac9 100644 --- a/blog/tags/wallet/index.html +++ b/blog/tags/wallet/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/using-bdk-with-hardware-wallets/index.html b/blog/using-bdk-with-hardware-wallets/index.html index ff69b28ba2..9b985ac482 100644 --- a/blog/using-bdk-with-hardware-wallets/index.html +++ b/blog/using-bdk-with-hardware-wallets/index.html @@ -30,7 +30,7 @@ - + @@ -181,7 +181,7 @@ blockchain.broadcast(&raw_transaction)?; println!("Transaction broadcasted! TXID: {txid}.\nExplorer URL: https://mempool.space/testnet/tx/{txid}", txid = txid); -

    # Conclusion

    We just received coins on a hardware wallet and spent from it - how cool is that?!

    See the hardware signer example (opens new window) for the full code, and, if you have any questions or suggestions, head to our Discord (opens new window). See you there!

    Last Updated: 11/21/2024, 4:44:27 PM
    - + diff --git a/examples/index.html b/examples/index.html index 8ad3752952..8a0027d725 100644 --- a/examples/index.html +++ b/examples/index.html @@ -29,7 +29,7 @@ - + @@ -53,7 +53,7 @@ Blog GitHub - (opens new window)

    # Examples

    Click the links below and learn from community-built example projects.

    # BDK-CLI (opens new window)

    A command line interface to experiment with the bitcoindevkit.

    # DevkitWallet (opens new window)

    A demo app for the bitcoindevkit on Android using bdk-kotlin.

    # Padawan Wallet (opens new window)

    A testnet-only bitcoin wallet full of tutorials on how to use bitcoin wallets.

    # BDKSwiftExampleWallet (opens new window)

    An example iOS app using bdk-swift.

    # Tatooine (opens new window)

    Tatooine is a small bitcoin testnet faucet built with Ktor, a Kotlin asynchronous framework for creating microservices and web applications.

    # SEBA Bank Proof of reserves (opens new window)

    The bdk library aims to be the core building block for Bitcoin wallets of any kind. The bdk-reserves library provides an implementation of proof-of-reserves for bdk.

    # Stackmate (opens new window)

    A multi-purpose Bitcoin Wallet.

    # Spotbit (opens new window)

    Spotbit's purpose is to allow users to access price feeds in a customisable way that preserves privacy and mitigate the reliance on a single source of data.

    Last Updated: 11/21/2024, 4:44:27 PM
    - + diff --git a/foundation/about/index.html b/foundation/about/index.html index 7c1981ca71..7bb1759247 100644 --- a/foundation/about/index.html +++ b/foundation/about/index.html @@ -29,7 +29,7 @@ - + @@ -78,6 +78,6 @@
    BDK Foundation
    - + diff --git a/foundation/become-a-member/index.html b/foundation/become-a-member/index.html index f12d170105..914b9a1d54 100644 --- a/foundation/become-a-member/index.html +++ b/foundation/become-a-member/index.html @@ -29,7 +29,7 @@ - + @@ -74,6 +74,6 @@
    BDK Foundation
    - + diff --git a/foundation/grantees/index.html b/foundation/grantees/index.html index e978430b9b..3212a24bdb 100644 --- a/foundation/grantees/index.html +++ b/foundation/grantees/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
    BDK Foundation
    - + diff --git a/foundation/grants/index.html b/foundation/grants/index.html index 34bd942d0a..5393762e4b 100644 --- a/foundation/grants/index.html +++ b/foundation/grants/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
    BDK Foundation
    - + diff --git a/foundation/index.html b/foundation/index.html index 2b001cb72f..10df13ea67 100644 --- a/foundation/index.html +++ b/foundation/index.html @@ -29,7 +29,7 @@ - + @@ -74,6 +74,6 @@
    BDK Foundation
    - + diff --git a/foundation/members/index.html b/foundation/members/index.html index 1fda49bd76..eedc3e0db3 100644 --- a/foundation/members/index.html +++ b/foundation/members/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
    BDK Foundation
    - + diff --git a/foundation/supporters/index.html b/foundation/supporters/index.html index 5cd4a44e1c..9c8433a5f5 100644 --- a/foundation/supporters/index.html +++ b/foundation/supporters/index.html @@ -29,7 +29,7 @@ - + @@ -113,6 +113,6 @@
    BDK Foundation
    - + diff --git a/getting-started/index.html b/getting-started/index.html index 65cf3ebec7..3d40a54170 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -31,7 +31,7 @@ - + @@ -105,7 +105,7 @@ wallet.get_descriptor_for_keychain(KeychainKind::External).to_string(), wallet.get_descriptor_for_keychain(KeychainKind::Internal).to_string()); } -

    More information about each component used in the code can be found in BDK Documentation (opens new window).

    Last Updated: 11/21/2024, 4:44:27 PM

    More information about each component used in the code can be found in BDK Documentation (opens new window).

    Last Updated: 11/18/2024, 8:15:46 PM
    BDK Foundation
    - + diff --git a/index.html b/index.html index 9fa515ee39..2e1654ba34 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,7 @@ - + @@ -80,6 +80,6 @@
    BDK Foundation
    - + diff --git a/sitemap.xml b/sitemap.xml index c63b665669..3ace1ecf6b 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://bitcoindevkit.org/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q1-update/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/_2023-q4-update/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q2-update/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q3-rfp-rust-maintainer/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q3-update/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics-multisig-2of3/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/bitcoin-core-rpc-demo/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/bdk-core-pt1/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/bdk-rn-making-of/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/bindings-scope/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/bdk-with-tor/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/compact-filters-demo/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/descriptor-based-paper-wallet/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-flutter/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-rn/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/descriptors-in-the-wild/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/getting-started-with-rust-hwi/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/hidden-power-of-bitcoin/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/hello-world/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/improving-coin-selection-in-bdk/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/miniscript-vulnerability/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/release-v0.2.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/release-v0.3.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/02/release-v0.4.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/04/release-v0.6.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/03/release-v0.5.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/05/release-v0.7.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/06/release-v0.8.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/2021/07/release-v0.9.0/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/road-to-bdk-1/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/spending-policy-demo/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/using-bdk-with-hardware-wallets/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/why-bindings/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/all/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/custodial/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/desktop/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/exchange/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/hardware/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/infrastructure/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/mobile/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/adoption/web/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/bdk-cli/compiler/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/bdk-cli/concept/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/bdk-cli/installation/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/bdk-cli/interface/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/bdk-cli/introduction/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/bdk-cli/playground/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/bdk-cli/regtest/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/case-studies/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/descriptors/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/examples/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/foundation/about/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/foundation/become-a-member/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/foundation/grantees/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/foundation/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/foundation/grants/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/foundation/members/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/foundation/supporters/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/getting-started/2024-11-21T16:44:27.000Zdailyhttps://bitcoindevkit.org/blog/dailyhttps://bitcoindevkit.org/blog/tags/dailyhttps://bitcoindevkit.org/blog/author/dailyhttps://bitcoindevkit.org/blog/tags/BDK/dailyhttps://bitcoindevkit.org/blog/tags/project/dailyhttps://bitcoindevkit.org/blog/tags/grants/dailyhttps://bitcoindevkit.org/blog/tags/tutorial/dailyhttps://bitcoindevkit.org/blog/tags/bdk-cli/dailyhttps://bitcoindevkit.org/blog/tags/multi-sig/dailyhttps://bitcoindevkit.org/blog/tags/Bitcoin%20Core/dailyhttps://bitcoindevkit.org/blog/tags/RPC/dailyhttps://bitcoindevkit.org/blog/tags/Wallet/dailyhttps://bitcoindevkit.org/blog/tags/architecture/dailyhttps://bitcoindevkit.org/blog/tags/BDK-RN/dailyhttps://bitcoindevkit.org/blog/tags/Development/dailyhttps://bitcoindevkit.org/blog/tags/Architecture/dailyhttps://bitcoindevkit.org/blog/tags/basics/dailyhttps://bitcoindevkit.org/blog/tags/novice/dailyhttps://bitcoindevkit.org/blog/tags/bindings/dailyhttps://bitcoindevkit.org/blog/tags/tor/dailyhttps://bitcoindevkit.org/blog/tags/wallet/dailyhttps://bitcoindevkit.org/blog/tags/blockchain/dailyhttps://bitcoindevkit.org/blog/tags/compact_filters/dailyhttps://bitcoindevkit.org/blog/tags/BIP157/dailyhttps://bitcoindevkit.org/blog/tags/Neutrino/dailyhttps://bitcoindevkit.org/blog/tags/guide/dailyhttps://bitcoindevkit.org/blog/tags/descriptor/dailyhttps://bitcoindevkit.org/blog/tags/paper%20wallets/dailyhttps://bitcoindevkit.org/blog/tags/bitcoin/dailyhttps://bitcoindevkit.org/blog/tags/React%20Native/dailyhttps://bitcoindevkit.org/blog/tags/Flutter/dailyhttps://bitcoindevkit.org/blog/tags/iOS/dailyhttps://bitcoindevkit.org/blog/tags/Android/dailyhttps://bitcoindevkit.org/blog/tags/mobile/dailyhttps://bitcoindevkit.org/blog/tags/bdk-rn/dailyhttps://bitcoindevkit.org/blog/tags/bdk/dailyhttps://bitcoindevkit.org/blog/tags/fee/dailyhttps://bitcoindevkit.org/blog/tags/machine%20learning/dailyhttps://bitcoindevkit.org/blog/tags/taproot/dailyhttps://bitcoindevkit.org/blog/tags/miniscript/dailyhttps://bitcoindevkit.org/blog/tags/Hardware%20Wallets/dailyhttps://bitcoindevkit.org/blog/tags/bitcoin-cli/dailyhttps://bitcoindevkit.org/blog/tags/getting%20started/dailyhttps://bitcoindevkit.org/blog/tags/rust/dailyhttps://bitcoindevkit.org/blog/tags/coin%20selection/dailyhttps://bitcoindevkit.org/blog/tags/development/dailyhttps://bitcoindevkit.org/blog/tags/summer%20of%20bitcoin/dailyhttps://bitcoindevkit.org/blog/tags/security/dailyhttps://bitcoindevkit.org/blog/tags/release/dailyhttps://bitcoindevkit.org/blog/author/Steve%20Myers/dailyhttps://bitcoindevkit.org/blog/author/Daniela%20Brozzoni/dailyhttps://bitcoindevkit.org/blog/author/thunderbiscuit/dailyhttps://bitcoindevkit.org/blog/author/waterst0ne/dailyhttps://bitcoindevkit.org/blog/author/Rajarshi%20Maitra/dailyhttps://bitcoindevkit.org/blog/author/Lloyd%20Fournier/dailyhttps://bitcoindevkit.org/blog/author/Bitcoin%20Zavior/dailyhttps://bitcoindevkit.org/blog/author/rorp/dailyhttps://bitcoindevkit.org/blog/author/Riccardo%20Casatta/dailyhttps://bitcoindevkit.org/blog/author/Gabriele%20Domenichini/dailyhttps://bitcoindevkit.org/blog/author/Alekos%20Filini/dailyhttps://bitcoindevkit.org/blog/author/Wszdexdrf/dailyhttps://bitcoindevkit.org/blog/author/Sandipan%20Dey/dailyhttps://bitcoindevkit.org/blog/author/C%C3%A9sar%20Alvarez%20Vallero/dailyhttps://bitcoindevkit.org/blog/page/2/dailyhttps://bitcoindevkit.org/blog/page/3/dailyhttps://bitcoindevkit.org/blog/page/4/dailyhttps://bitcoindevkit.org/blog/tags/BDK/page/2/dailyhttps://bitcoindevkit.org/blog/author/Alekos%20Filini/page/2/daily \ No newline at end of file +https://bitcoindevkit.org/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/_2023-q4-update/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q1-update/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q3-rfp-rust-maintainer/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q2-update/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/bitcoin-core-rpc-demo/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics-multisig-2of3/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q3-update/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/bdk-core-pt1/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/bdk-rn-making-of/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/bdk-with-tor/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/bindings-scope/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/compact-filters-demo/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/descriptor-based-paper-wallet/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/descriptors-in-the-wild/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-rn/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-flutter/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/getting-started-with-rust-hwi/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/hello-world/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/hidden-power-of-bitcoin/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/improving-coin-selection-in-bdk/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/miniscript-vulnerability/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/release-v0.3.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/release-v0.2.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/03/release-v0.5.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/02/release-v0.4.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/04/release-v0.6.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/05/release-v0.7.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/06/release-v0.8.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/2021/07/release-v0.9.0/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/road-to-bdk-1/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/using-bdk-with-hardware-wallets/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/why-bindings/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/spending-policy-demo/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/all/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/custodial/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/desktop/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/exchange/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/infrastructure/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/mobile/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/web/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/adoption/hardware/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/bdk-cli/compiler/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/bdk-cli/concept/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/bdk-cli/installation/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/bdk-cli/interface/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/bdk-cli/playground/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/bdk-cli/introduction/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/bdk-cli/regtest/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/case-studies/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/descriptors/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/examples/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/foundation/about/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/foundation/become-a-member/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/foundation/grantees/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/foundation/grants/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/foundation/members/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/foundation/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/foundation/supporters/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/getting-started/2024-11-18T20:15:46.000Zdailyhttps://bitcoindevkit.org/blog/dailyhttps://bitcoindevkit.org/blog/tags/dailyhttps://bitcoindevkit.org/blog/author/dailyhttps://bitcoindevkit.org/blog/tags/BDK/dailyhttps://bitcoindevkit.org/blog/tags/project/dailyhttps://bitcoindevkit.org/blog/tags/grants/dailyhttps://bitcoindevkit.org/blog/tags/tutorial/dailyhttps://bitcoindevkit.org/blog/tags/Bitcoin%20Core/dailyhttps://bitcoindevkit.org/blog/tags/RPC/dailyhttps://bitcoindevkit.org/blog/tags/Wallet/dailyhttps://bitcoindevkit.org/blog/tags/bdk-cli/dailyhttps://bitcoindevkit.org/blog/tags/multi-sig/dailyhttps://bitcoindevkit.org/blog/tags/basics/dailyhttps://bitcoindevkit.org/blog/tags/novice/dailyhttps://bitcoindevkit.org/blog/tags/architecture/dailyhttps://bitcoindevkit.org/blog/tags/BDK-RN/dailyhttps://bitcoindevkit.org/blog/tags/Development/dailyhttps://bitcoindevkit.org/blog/tags/Architecture/dailyhttps://bitcoindevkit.org/blog/tags/tor/dailyhttps://bitcoindevkit.org/blog/tags/wallet/dailyhttps://bitcoindevkit.org/blog/tags/blockchain/dailyhttps://bitcoindevkit.org/blog/tags/bindings/dailyhttps://bitcoindevkit.org/blog/tags/compact_filters/dailyhttps://bitcoindevkit.org/blog/tags/BIP157/dailyhttps://bitcoindevkit.org/blog/tags/Neutrino/dailyhttps://bitcoindevkit.org/blog/tags/guide/dailyhttps://bitcoindevkit.org/blog/tags/descriptor/dailyhttps://bitcoindevkit.org/blog/tags/paper%20wallets/dailyhttps://bitcoindevkit.org/blog/tags/bitcoin/dailyhttps://bitcoindevkit.org/blog/tags/React%20Native/dailyhttps://bitcoindevkit.org/blog/tags/iOS/dailyhttps://bitcoindevkit.org/blog/tags/Android/dailyhttps://bitcoindevkit.org/blog/tags/mobile/dailyhttps://bitcoindevkit.org/blog/tags/bdk-rn/dailyhttps://bitcoindevkit.org/blog/tags/bdk/dailyhttps://bitcoindevkit.org/blog/tags/Flutter/dailyhttps://bitcoindevkit.org/blog/tags/fee/dailyhttps://bitcoindevkit.org/blog/tags/machine%20learning/dailyhttps://bitcoindevkit.org/blog/tags/taproot/dailyhttps://bitcoindevkit.org/blog/tags/miniscript/dailyhttps://bitcoindevkit.org/blog/tags/Hardware%20Wallets/dailyhttps://bitcoindevkit.org/blog/tags/getting%20started/dailyhttps://bitcoindevkit.org/blog/tags/rust/dailyhttps://bitcoindevkit.org/blog/tags/bitcoin-cli/dailyhttps://bitcoindevkit.org/blog/tags/coin%20selection/dailyhttps://bitcoindevkit.org/blog/tags/development/dailyhttps://bitcoindevkit.org/blog/tags/summer%20of%20bitcoin/dailyhttps://bitcoindevkit.org/blog/tags/security/dailyhttps://bitcoindevkit.org/blog/tags/release/dailyhttps://bitcoindevkit.org/blog/author/Steve%20Myers/dailyhttps://bitcoindevkit.org/blog/author/Daniela%20Brozzoni/dailyhttps://bitcoindevkit.org/blog/author/thunderbiscuit/dailyhttps://bitcoindevkit.org/blog/author/Rajarshi%20Maitra/dailyhttps://bitcoindevkit.org/blog/author/waterst0ne/dailyhttps://bitcoindevkit.org/blog/author/Lloyd%20Fournier/dailyhttps://bitcoindevkit.org/blog/author/Bitcoin%20Zavior/dailyhttps://bitcoindevkit.org/blog/author/rorp/dailyhttps://bitcoindevkit.org/blog/author/Riccardo%20Casatta/dailyhttps://bitcoindevkit.org/blog/author/Gabriele%20Domenichini/dailyhttps://bitcoindevkit.org/blog/author/Alekos%20Filini/dailyhttps://bitcoindevkit.org/blog/author/Wszdexdrf/dailyhttps://bitcoindevkit.org/blog/author/Sandipan%20Dey/dailyhttps://bitcoindevkit.org/blog/author/C%C3%A9sar%20Alvarez%20Vallero/dailyhttps://bitcoindevkit.org/blog/page/2/dailyhttps://bitcoindevkit.org/blog/page/3/dailyhttps://bitcoindevkit.org/blog/page/4/dailyhttps://bitcoindevkit.org/blog/tags/BDK/page/2/dailyhttps://bitcoindevkit.org/blog/author/Alekos%20Filini/page/2/daily \ No newline at end of file