From 0425efe4d86537127e4e2848ce36d5d8f8d889e5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 18 Apr 2024 07:45:21 +0000 Subject: [PATCH] deploy: 6adcbde9f3d5b960a91ae7c97bae77e91cdcb7b0 --- 404.html | 6 +- assets/js/{34.2e8ace62.js => 34.1951be7d.js} | 2 +- assets/js/{39.089a397e.js => 39.b76a2ad0.js} | 2 +- assets/js/{40.40d30668.js => 40.d6250f8b.js} | 2 +- assets/js/{44.1195b75f.js => 44.5391eb7f.js} | 2 +- assets/js/{45.41387e37.js => 45.dbedb51c.js} | 2 +- assets/js/{46.883464d4.js => 46.5deb1292.js} | 2 +- assets/js/{48.9a448976.js => 48.f74437f6.js} | 2 +- assets/js/{49.17ce6e83.js => 49.b70acbda.js} | 2 +- assets/js/{53.fb891878.js => 53.08d5fa33.js} | 2 +- assets/js/{54.d9630932.js => 54.4ffb88f8.js} | 2 +- assets/js/{60.08677303.js => 60.e9dd6778.js} | 2 +- assets/js/{61.63feb9f0.js => 61.1cf26963.js} | 2 +- assets/js/{62.b483815a.js => 62.43618b30.js} | 2 +- assets/js/{63.2a61731d.js => 63.2518a4ae.js} | 2 +- assets/js/{64.1a1630c4.js => 64.c74d4d9a.js} | 2 +- assets/js/{65.5db91110.js => 65.084b8455.js} | 2 +- assets/js/{69.34e6059d.js => 69.c4fd27b4.js} | 2 +- assets/js/{70.42bd691e.js => 70.c2fb4c8e.js} | 2 +- assets/js/{71.2b84faa7.js => 71.12dfcc1e.js} | 2 +- assets/js/{76.2c842c7e.js => 76.f9c90561.js} | 2 +- assets/js/{77.1bd88a81.js => 77.1cad2d43.js} | 2 +- assets/js/{79.bf24138b.js => 79.210c655a.js} | 2 +- assets/js/{80.9c59a7bc.js => 80.79a4d68e.js} | 2 +- .../js/{app.2350a6e1.js => app.76456079.js} | 4 +- bdk-cli/compiler/index.html | 6 +- bdk-cli/concept/index.html | 6 +- bdk-cli/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 +- .../index.html | 6 +- .../index.html | 6 +- .../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/_2024-q4-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 +- .../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 | 8 +- 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 +- .../index.html | 6 +- blog/index.html | 4 +- blog/miniscript-vulnerability/index.html | 6 +- blog/page/2/index.html | 4 +- blog/page/3/index.html | 8 +- blog/page/4/index.html | 4 +- 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/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 | 8 +- blog/tags/getting started/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 | 8 +- 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 +- .../index.html | 6 +- case-studies/index.html | 4 +- descriptors/index.html | 6 +- .../bdk/descriptor/enum.Descriptor.html | 8 +- .../descriptor/enum.DescriptorPublicKey.html | 6 +- .../bdk/descriptor/policy/enum.PkOrF.html | 2 +- .../descriptor/policy/enum.Satisfaction.html | 2 +- .../policy/enum.SatisfiableItem.html | 2 +- .../descriptor/policy/struct.Condition.html | 2 +- .../bdk/descriptor/policy/struct.Policy.html | 2 +- .../bdk/descriptor/struct.Miniscript.html | 6 +- .../nightly/latest/bdk/enum.KeychainKind.html | 6 +- .../bdk/keys/enum.DescriptorPublicKey.html | 6 +- .../latest/bdk/struct.LocalOutput.html | 6 +- .../export/struct.FullyNodedExport.html | 4 +- .../latest/bdk/wallet/struct.Balance.html | 6 +- .../latest/bdk/wallet/struct.ChangeSet.html | 6 +- .../bdk_chain/enum.ConfirmationTime.html | 6 +- .../bdk/nightly/latest/bdk_chain/index.html | 2 +- .../indexed_tx_graph/struct.ChangeSet.html | 6 +- .../bdk_chain/keychain/struct.Balance.html | 6 +- .../bdk_chain/keychain/struct.ChangeSet.html | 6 +- .../keychain/struct.KeychainTxOutIndex.html | 62 +++++---- .../latest/bdk_chain/struct.BlockId.html | 6 +- .../struct.ConfirmationHeightAnchor.html | 6 +- .../struct.ConfirmationTimeHeightAnchor.html | 6 +- .../bdk_chain/struct.SpkTxOutIndex.html | 19 ++- .../bdk_chain/tx_graph/struct.ChangeSet.html | 6 +- .../tx_graph/struct.TxAncestors.html | 4 +- .../tx_graph/struct.TxDescendants.html | 4 +- .../bdk_file_store/struct.EntryIter.html | 2 +- .../latest/bdk_file_store/struct.Store.html | 6 +- docs-rs/bdk/nightly/latest/bdk_hwi/index.html | 2 +- .../latest/bdk_hwi/struct.HWISigner.html | 2 +- .../latest/example_cli/enum.Keychain.html | 6 +- .../example_cli/fn.handle_commands.html | 2 +- .../nightly/latest/example_cli/fn.init.html | 2 +- .../bdk/wallet/signer/trait.SignerCommon.js | 2 +- .../wallet/signer/trait.TransactionSigner.js | 2 +- .../bdk_chain/persist/trait.PersistBackend.js | 2 +- .../iter/traits/iterator/trait.Iterator.js | 2 +- .../serde/de/trait.Deserialize.js | 6 +- .../implementors/serde/ser/trait.Serialize.js | 6 +- docs-rs/bdk/nightly/latest/search-index.js | 4 +- .../nightly/latest/src/bdk/wallet/mod.rs.html | 2 +- .../bdk_chain/keychain/txout_index.rs.html | 118 ++++++++++-------- .../src/bdk_chain/spk_txout_index.rs.html | 36 +++--- .../latest/src/example_electrum/main.rs.html | 4 +- .../latest/src/example_esplora/main.rs.html | 4 +- examples/index.html | 6 +- foundation/index.html | 4 +- getting-started/index.html | 6 +- index.html | 4 +- sitemap.xml | 2 +- supporters/index.html | 6 +- 187 files changed, 531 insertions(+), 512 deletions(-) rename assets/js/{34.2e8ace62.js => 34.1951be7d.js} (99%) rename assets/js/{39.089a397e.js => 39.b76a2ad0.js} (99%) rename assets/js/{40.40d30668.js => 40.d6250f8b.js} (99%) rename assets/js/{44.1195b75f.js => 44.5391eb7f.js} (99%) rename assets/js/{45.41387e37.js => 45.dbedb51c.js} (99%) rename assets/js/{46.883464d4.js => 46.5deb1292.js} (99%) rename assets/js/{48.9a448976.js => 48.f74437f6.js} (99%) rename assets/js/{49.17ce6e83.js => 49.b70acbda.js} (99%) rename assets/js/{53.fb891878.js => 53.08d5fa33.js} (99%) rename assets/js/{54.d9630932.js => 54.4ffb88f8.js} (99%) rename assets/js/{60.08677303.js => 60.e9dd6778.js} (98%) rename assets/js/{61.63feb9f0.js => 61.1cf26963.js} (99%) rename assets/js/{62.b483815a.js => 62.43618b30.js} (99%) rename assets/js/{63.2a61731d.js => 63.2518a4ae.js} (99%) rename assets/js/{64.1a1630c4.js => 64.c74d4d9a.js} (99%) rename assets/js/{65.5db91110.js => 65.084b8455.js} (99%) rename assets/js/{69.34e6059d.js => 69.c4fd27b4.js} (99%) rename assets/js/{70.42bd691e.js => 70.c2fb4c8e.js} (98%) rename assets/js/{71.2b84faa7.js => 71.12dfcc1e.js} (99%) rename assets/js/{76.2c842c7e.js => 76.f9c90561.js} (99%) rename assets/js/{77.1bd88a81.js => 77.1cad2d43.js} (99%) rename assets/js/{79.bf24138b.js => 79.210c655a.js} (97%) rename assets/js/{80.9c59a7bc.js => 80.79a4d68e.js} (99%) rename assets/js/{app.2350a6e1.js => app.76456079.js} (77%) diff --git a/404.html b/404.html index 895ee6fc84..d0ab66d024 100644 --- a/404.html +++ b/404.html @@ -15,7 +15,7 @@ - + @@ -39,7 +39,7 @@ Blog GitHub - (opens new window)

404 - Not Found

That's a Four-Oh-Four.
+ (opens new window)

404 - Not Found

There's nothing here.
Take me home.
- + diff --git a/assets/js/34.2e8ace62.js b/assets/js/34.1951be7d.js similarity index 99% rename from assets/js/34.2e8ace62.js rename to assets/js/34.1951be7d.js index 641e4dfc68..47f2cd89d8 100644 --- a/assets/js/34.2e8ace62.js +++ b/assets/js/34.1951be7d.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{342:function(t,e,a){t.exports=a.p+"assets/img/descriptor-tracker.5942c853.jpg"},343:function(t,e,a){t.exports=a.p+"assets/img/checkpoints.a4179787.jpg"},387: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(342),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(343),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],{342:function(t,e,a){t.exports=a.p+"assets/img/descriptor-tracker.5942c853.jpg"},343:function(t,e,a){t.exports=a.p+"assets/img/checkpoints.a4179787.jpg"},388: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(342),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(343),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.089a397e.js b/assets/js/39.b76a2ad0.js similarity index 99% rename from assets/js/39.089a397e.js rename to assets/js/39.b76a2ad0.js index 4612598e26..64bd78a0b4 100644 --- a/assets/js/39.089a397e.js +++ b/assets/js/39.b76a2ad0.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{388: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([[39],{385: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/40.40d30668.js b/assets/js/40.d6250f8b.js similarity index 99% rename from assets/js/40.40d30668.js rename to assets/js/40.d6250f8b.js index 9e2c066643..85ab325e44 100644 --- a/assets/js/40.40d30668.js +++ b/assets/js/40.d6250f8b.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{385:function(t,e,s){"use strict";s.r(e);var a=s(7),r=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"2-of-3-multi-signature-descriptor-wallet-using-bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#2-of-3-multi-signature-descriptor-wallet-using-bdk-cli"}},[t._v("#")]),t._v(" 2-of-3 Multi-Signature Descriptor Wallet using bdk-cli")]),t._v(" "),e("h2",{attrs:{id:"overview-of-the-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#overview-of-the-tutorial"}},[t._v("#")]),t._v(" Overview of the tutorial")]),t._v(" "),e("ul",[e("li",[t._v("The purpose of this tutorial is to continue learning "),e("code",[t._v("bdk-cli")]),t._v(" as our tool to manage a 2 of 3 multi-signature wallet.")]),t._v(" "),e("li",[t._v("Generate a receive address with a spending Policy of 2 out of 3 escrow aka multi-signature.")]),t._v(" "),e("li",[t._v("Intro to more complex but standard policies to create custom encumberances aka custom spending conditions for transactions.")])]),t._v(" "),e("p",[t._v("Note that to complete this tutorial, you'll need to enable the "),e("code",[t._v("compiler")]),t._v(" and "),e("code",[t._v("electrum")]),t._v(" flags when installing or building bdk-cli, for example by installing using:")]),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 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("compiler,electrum\n")])])]),e("h2",{attrs:{id:"step-1-generate-the-xprvs-extended-keys-and-save-to-environment-variables"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-1-generate-the-xprvs-extended-keys-and-save-to-environment-variables"}},[t._v("#")]),t._v(" Step 1: Generate the XPRVs (Extended-Keys) and Save to environment variables")]),t._v(" "),e("blockquote",[e("p",[t._v("Create three private keys and each in their own environment variable")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export XPRV_00=$(bdk-cli key generate | jq -r '.xprv')")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export XPRV_01=$(bdk-cli key generate | jq -r '.xprv')")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export XPRV_02=$(bdk-cli key generate | jq -r '.xprv')")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/FwgUdwK.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"1a-verify-xprv-environment-variables-are-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1a-verify-xprv-environment-variables-are-active"}},[t._v("#")]),t._v(" 1a: Verify XPRV environment variables are Active")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep XPRV")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/ZerGPbO.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-2-generate-xpubs-extended-public-keys-save-to-environment-variables"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-2-generate-xpubs-extended-public-keys-save-to-environment-variables"}},[t._v("#")]),t._v(" Step 2: Generate XPUBs (Extended Public Keys) & Save to environment variables")]),t._v(" "),e("blockquote",[e("p",[t._v("Generate the three individual Public Keys aka XPUBs using our Private key and descriptor path.")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export XPUB_00=$(bdk-cli key derive --xprv $XPRV_00 --path "m/84\'/1\'/0\'/0" | jq -r ".xpub")')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export XPUB_01=$(bdk-cli key derive --xprv $XPRV_01 --path "m/84\'/1\'/0\'/0" | jq -r ".xpub")')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export XPUB_02=$(bdk-cli key derive --xprv $XPRV_02 --path "m/84\'/1\'/0\'/0" | jq -r ".xpub")')])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/xT3KRh4.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"2a-verify-xpub-environment-variables"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#2a-verify-xpub-environment-variables"}},[t._v("#")]),t._v(" 2a: Verify XPUB environment variables")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep XPUB")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/SzAip9E.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-3-create-single-wallet-descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-3-create-single-wallet-descriptors"}},[t._v("#")]),t._v(" Step 3: Create Single-Wallet Descriptors")]),t._v(" "),e("blockquote",[e("p",[t._v("Create the wallet Descriptor for each wallet")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export DESCRIPTOR_00="$XPRV_00/84h/1h/0h/0/*"')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export DESCRIPTOR_01="$XPRV_01/84h/1h/0h/0/*"')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export DESCRIPTOR_02="$XPRV_02/84h/1h/0h/0/*"')])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/mFrWt6b.png",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-4-create-multi-sig-descriptor-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-4-create-multi-sig-descriptor-wallets"}},[t._v("#")]),t._v(" Step 4: Create Multi-Sig-Descriptor Wallets")]),t._v(" "),e("blockquote",[e("p",[t._v("This is how you create the 2-of-3 multi-sig output descriptor. You will need (one PrivateKey and two Xpubs) It consists of using the "),e("code",[t._v("compiler")]),t._v(" function to parse "),e("code",[t._v("policy")]),t._v(" to "),e("code",[t._v("mini-script")]),t._v(" .")])]),t._v(" "),e("ul",[e("li",[t._v("When creating the descriptor the order matters so be aware of that when following tutorial if you are for any reason changing the order of the policy.")])]),t._v(" "),e("h4",{attrs:{id:"multi-sig-wallet-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-wallet-0"}},[t._v("#")]),t._v(" Multi-Sig-Wallet 0")]),t._v(" "),e("ul",[e("li",[t._v("[ ] ▶️ "),e("code",[t._v("export MULTI_DESCRIPTOR_00=$(bdk-cli compile \"thresh(2,pk($DESCRIPTOR_00),pk($XPUB_01),pk($XPUB_02))\" | jq -r '.descriptor')")])])]),t._v(" "),e("h4",{attrs:{id:"multi-sig-wallet-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-wallet-1"}},[t._v("#")]),t._v(" Multi-Sig-Wallet 1")]),t._v(" "),e("ul",[e("li",[t._v("[ ] ▶️ "),e("code",[t._v("export MULTI_DESCRIPTOR_01=$(bdk-cli compile \"thresh(2,pk($XPUB_00),pk($DESCRIPTOR_01),pk($XPUB_02))\" | jq -r '.descriptor')")])])]),t._v(" "),e("h4",{attrs:{id:"multi-sig-wallet-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-wallet-2"}},[t._v("#")]),t._v(" Multi-Sig-Wallet 2")]),t._v(" "),e("ul",[e("li",[t._v("[ ] ▶️ "),e("code",[t._v("export MULTI_DESCRIPTOR_02=$(bdk-cli compile \"thresh(2,pk($XPUB_00),pk($XPUB_01),pk($DESCRIPTOR_02))\" | jq -r '.descriptor')")])])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/Yb8RmFS.gif",alt:""}})]),t._v(" "),e("h4",{attrs:{id:"multi-sig-2-of-3-policy-gets-compiled-to-miniscript"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-2-of-3-policy-gets-compiled-to-miniscript"}},[t._v("#")]),t._v(" multi-sig 2 of 3 policy gets compiled to miniscript")]),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 comment"}},[t._v("# policy")]),t._v("\nthresh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("XPRV_A"),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("XPUB_B"),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("XPUB_C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v(" \n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# miniscript")]),t._v("\nwsh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("multi"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",XPRV_KEY,PUBKEY_B,XPUB_C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h3",{attrs:{id:"4a-verify-multi-sig-descriptor-environment-variables-are-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#4a-verify-multi-sig-descriptor-environment-variables-are-active"}},[t._v("#")]),t._v(" 4a: Verify Multi-Sig-Descriptor environment variables are active")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep MULTI")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/aAgtlsi.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-5-generate-receive-address-by-using-multi-sig-descriptor-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-5-generate-receive-address-by-using-multi-sig-descriptor-wallets"}},[t._v("#")]),t._v(" Step 5: Generate Receive Address by using Multi-Sig-Descriptor Wallets")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 get_new_address")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 get_new_address")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd02 --descriptor $MULTI_DESCRIPTOR_02 get_new_address")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/w1fxPSn.gif",alt:""}})]),t._v(" "),e("p",[t._v("🔴 Did you generate the same address for all three? Good! Else, something might be incorrect.")]),t._v(" "),e("h2",{attrs:{id:"step-6-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-6-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[t._v("#")]),t._v(" Step 6: Send Testnet Bitcoin to the newly created receive-address")]),t._v(" "),e("p",[e("a",{attrs:{href:"https://testnet-faucet.mempool.co",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Testnet Faucet link:1"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Testnet Faucet link:2"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"step-7-sync-one-of-the-multi-sig-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-7-sync-one-of-the-multi-sig-wallets"}},[t._v("#")]),t._v(" Step 7: Sync one of the Multi-Sig Wallets")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 sync")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/GuefgeI.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-8-check-balance-multi-sig-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-8-check-balance-multi-sig-wallets"}},[t._v("#")]),t._v(" Step 8: Check Balance Multi-Sig Wallets")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 get_balance")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/zNciCqF.gif",alt:""}})]),t._v(" "),e("ul",[e("li",[t._v("Every wallet has access to sync and view balance.")])]),t._v(" "),e("h2",{attrs:{id:"step-9-check-multi-sig-policies-on-descriptor-wallet"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-9-check-multi-sig-policies-on-descriptor-wallet"}},[t._v("#")]),t._v(" Step 9: Check Multi-Sig Policies on Descriptor Wallet")]),t._v(" "),e("p",[t._v("▶️"),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 policies")])]),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('"external"')]),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('"contribution"')]),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('"conditions"')]),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('"0"')]),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 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 "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"items"')]),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 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 string"}},[t._v('"m"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"n"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sorted"')]),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('"type"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIAL"')]),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('"id"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"seaxtqqn"')]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"keys"')]),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 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('"7cdf2d46"')]),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 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('"fc7870cd"')]),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 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('"26b03333"')]),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 string"}},[t._v('"satisfaction"')]),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('"items"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[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 string"}},[t._v('"m"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"n"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sorted"')]),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('"type"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIAL"')]),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('"threshold"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"type"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"MULTISIG"')]),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('"internal"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" null\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n\n")])])]),e("h3",{attrs:{id:"spendingpolicyrequired-for-complex-descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#spendingpolicyrequired-for-complex-descriptors"}},[t._v("#")]),t._v(" SpendingPolicyRequired for complex descriptors")]),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 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('\\"')]),t._v("seaxtqqn"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(': [0,1]}"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-rootnode-"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("children "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#0 and #1 of root node>")]),t._v("\n")])])]),e("blockquote",[e("p",[t._v("Save the \"id\": We will need to use this ''id'' later.")])]),t._v(" "),e("p",[t._v("More info on "),e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-cli/interface/",target:"_blank",rel:"noopener noreferrer"}},[t._v("external policies here"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"step-10-create-a-transaction-psbt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-10-create-a-transaction-psbt"}},[t._v("#")]),t._v(" Step 10: Create a Transaction (PSBT)")]),t._v(" "),e("ul",[e("li",[t._v("1st Create a PSBT using the first wallet")]),t._v(" "),e("li",[t._v("2nd Sign the PSBT with the first wallet")]),t._v(" "),e("li",[t._v("3rd Sign PSBT with the second wallet")]),t._v(" "),e("li",[t._v("Broadcast PSBT")])]),t._v(" "),e("h3",{attrs:{id:"export-unsigned-psbt-to-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#export-unsigned-psbt-to-environment-variable"}},[t._v("#")]),t._v(" Export UNSIGNED_PSBT to environment variable")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export UNSIGNED_PSBT=$(bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 create_tx --send_all --to mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt:0 --external_policy "{\\"CHANGE_ID_HERE\\": [0,1]}" | jq -r \'.psbt\')')])]),t._v(" "),e("h3",{attrs:{id:"verify-unsigned-psbt-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#verify-unsigned-psbt-environment-variable"}},[t._v("#")]),t._v(" Verify UNSIGNED_PSBT environment variable")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep UNSIGNED")]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/djHaRDq.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-11-sign-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-11-sign-the-transaction"}},[t._v("#")]),t._v(" Step 11: SIGN the Transaction")]),t._v(" "),e("h3",{attrs:{id:"1st-wallet-signs-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1st-wallet-signs-the-transaction"}},[t._v("#")]),t._v(" 1st Wallet Signs the transaction")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 sign --psbt $UNSIGNED_PSBT")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export ONESIG_PSBT=$(bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 sign --psbt $UNSIGNED_PSBT | jq -r '.psbt')")])]),t._v(" "),e("p",[t._v("▶️"),e("code",[t._v("env | grep ONESIG")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('{\n "is_finalized": false,\n "psbt": "cHNidP8BAFUBAAAAAdYCtva/7Rkt+fgFu3mxAdaPh4uTbgBL3HmYZgcEKWygAAAAAAD/////AQqGAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA6gIAAAAAAQFLyGFJFK884DGBM1WgskRZ6gKp/7oZ+Z30u0+wF3pZYAEAAAAA/v///wKghgEAAAAAACIAINHcOQLE6GpJ3J+FOzn/be+HApxW8sZtGqfA3TBW+NYX91hoOAAAAAAWABTPQDZx2wYYIn+ug2pZBmWBn0Tu/gJHMEQCIHu6GmRMDgPZyTx+klFMA9VujR3qDA/Y08kSkRvOaChjAiBAtExtGAYLuQ/DDJzCqLlNZ1bMB3MV+nxsLfTdI9YcYwEhA0b8lz+kt0xHfR/tjUKOc2Nt2L61pDd5vJ/lsKi8pw9MmFUjAAEBK6CGAQAAAAAAIgAg0dw5AsToakncn4U7Of9t74cCnFbyxm0ap8DdMFb41hciAgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDUgwRQIhAJdILr7G3UzYylyr2fA13MFsz/jG4+iZlKeEkX79d082AiA99UF0/uFyXBVNUmuGaxdHL7wlhzqfbgGLMREN0z/O6QEBBWlSIQIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDSEDzsDXexRPSxeXiLJoS0i2fQlOoOGHmo+Dhaeaq3oHV6YhAjGKA2Dqg+QeMICBAifYslQF2WrehLEQ0iEOpp/+eQ0NU64iBgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDRh83y1GVAAAgAEAAIAAAACAAAAAAAAAAAAiBgIxigNg6oPkHjCAgQIn2LJUBdlq3oSxENIhDqaf/nkNDRgmsDMzVAAAgAEAAIAAAACAAAAAAAAAAAAiBgPOwNd7FE9LF5eIsmhLSLZ9CU6g4Yeaj4OFp5qregdXphj8eHDNVAAAgAEAAIAAAACAAAAAAAAAAAAAAA=="\n}\n')])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/0w4sK5y.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"2nd-wallet-signs-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#2nd-wallet-signs-the-transaction"}},[t._v("#")]),t._v(" 2nd Wallet Signs the transaction")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 sign --psbt $ONESIG_PSBT")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export SECONDSIG_PSBT=$(bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 sign --psbt $ONESIG_PSBT | jq -r '.psbt')")])]),t._v(" "),e("p",[t._v("▶️"),e("code",[t._v("env | grep SECONDSIG")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('{\n "is_finalized": true,\n "psbt": "cHNidP8BAFUBAAAAAdYCtva/7Rkt+fgFu3mxAdaPh4uTbgBL3HmYZgcEKWygAAAAAAD/////AQqGAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA6gIAAAAAAQFLyGFJFK884DGBM1WgskRZ6gKp/7oZ+Z30u0+wF3pZYAEAAAAA/v///wKghgEAAAAAACIAINHcOQLE6GpJ3J+FOzn/be+HApxW8sZtGqfA3TBW+NYX91hoOAAAAAAWABTPQDZx2wYYIn+ug2pZBmWBn0Tu/gJHMEQCIHu6GmRMDgPZyTx+klFMA9VujR3qDA/Y08kSkRvOaChjAiBAtExtGAYLuQ/DDJzCqLlNZ1bMB3MV+nxsLfTdI9YcYwEhA0b8lz+kt0xHfR/tjUKOc2Nt2L61pDd5vJ/lsKi8pw9MmFUjAAEBK6CGAQAAAAAAIgAg0dw5AsToakncn4U7Of9t74cCnFbyxm0ap8DdMFb41hciAgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDUgwRQIhAJdILr7G3UzYylyr2fA13MFsz/jG4+iZlKeEkX79d082AiA99UF0/uFyXBVNUmuGaxdHL7wlhzqfbgGLMREN0z/O6QEiAgPOwNd7FE9LF5eIsmhLSLZ9CU6g4Yeaj4OFp5qregdXpkgwRQIhAO2aRERcublhAzToshkZRMg2I8GaE7mM2ECr0vYyuscmAiB5KK4ETlvrLqL0QbcRbGqrSwIa9lVuOqP3f5qCnGRMaQEBBWlSIQIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDSEDzsDXexRPSxeXiLJoS0i2fQlOoOGHmo+Dhaeaq3oHV6YhAjGKA2Dqg+QeMICBAifYslQF2WrehLEQ0iEOpp/+eQ0NU64iBgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDRh83y1GVAAAgAEAAIAAAACAAAAAAAAAAAAiBgIxigNg6oPkHjCAgQIn2LJUBdlq3oSxENIhDqaf/nkNDRgmsDMzVAAAgAEAAIAAAACAAAAAAAAAAAAiBgPOwNd7FE9LF5eIsmhLSLZ9CU6g4Yeaj4OFp5qregdXphj8eHDNVAAAgAEAAIAAAACAAAAAAAAAAAABBwABCP3+AAQASDBFAiEAl0guvsbdTNjKXKvZ8DXcwWzP+Mbj6JmUp4SRfv13TzYCID31QXT+4XJcFU1Sa4ZrF0cvvCWHOp9uAYsxEQ3TP87pAUgwRQIhAO2aRERcublhAzToshkZRMg2I8GaE7mM2ECr0vYyuscmAiB5KK4ETlvrLqL0QbcRbGqrSwIa9lVuOqP3f5qCnGRMaQFpUiECI1AiHZ8q+qw7bjYVTbeGQQ3L2C2sH6CW82z8sXP1jQ0hA87A13sUT0sXl4iyaEtItn0JTqDhh5qPg4Wnmqt6B1emIQIxigNg6oPkHjCAgQIn2LJUBdlq3oSxENIhDqaf/nkNDVOuAAA="\n}\n')])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/OdLHnJ3.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-12-broadcast-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-12-broadcast-transaction"}},[t._v("#")]),t._v(" Step 12: Broadcast Transaction")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 broadcast --psbt $SECONDSIG_PSBT")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('{\n "txid": "61da2451874a483aa8d1d0787c7680d157639f284840de8885098cac43f6cc2f"\n}\n')])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/M7s0Fd6.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"verify-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#verify-transaction"}},[t._v("#")]),t._v(" Verify Transaction")]),t._v(" "),e("p",[t._v("Verify transcation 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)])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{387:function(t,e,s){"use strict";s.r(e);var a=s(7),r=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"2-of-3-multi-signature-descriptor-wallet-using-bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#2-of-3-multi-signature-descriptor-wallet-using-bdk-cli"}},[t._v("#")]),t._v(" 2-of-3 Multi-Signature Descriptor Wallet using bdk-cli")]),t._v(" "),e("h2",{attrs:{id:"overview-of-the-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#overview-of-the-tutorial"}},[t._v("#")]),t._v(" Overview of the tutorial")]),t._v(" "),e("ul",[e("li",[t._v("The purpose of this tutorial is to continue learning "),e("code",[t._v("bdk-cli")]),t._v(" as our tool to manage a 2 of 3 multi-signature wallet.")]),t._v(" "),e("li",[t._v("Generate a receive address with a spending Policy of 2 out of 3 escrow aka multi-signature.")]),t._v(" "),e("li",[t._v("Intro to more complex but standard policies to create custom encumberances aka custom spending conditions for transactions.")])]),t._v(" "),e("p",[t._v("Note that to complete this tutorial, you'll need to enable the "),e("code",[t._v("compiler")]),t._v(" and "),e("code",[t._v("electrum")]),t._v(" flags when installing or building bdk-cli, for example by installing using:")]),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 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("compiler,electrum\n")])])]),e("h2",{attrs:{id:"step-1-generate-the-xprvs-extended-keys-and-save-to-environment-variables"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-1-generate-the-xprvs-extended-keys-and-save-to-environment-variables"}},[t._v("#")]),t._v(" Step 1: Generate the XPRVs (Extended-Keys) and Save to environment variables")]),t._v(" "),e("blockquote",[e("p",[t._v("Create three private keys and each in their own environment variable")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export XPRV_00=$(bdk-cli key generate | jq -r '.xprv')")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export XPRV_01=$(bdk-cli key generate | jq -r '.xprv')")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export XPRV_02=$(bdk-cli key generate | jq -r '.xprv')")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/FwgUdwK.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"1a-verify-xprv-environment-variables-are-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1a-verify-xprv-environment-variables-are-active"}},[t._v("#")]),t._v(" 1a: Verify XPRV environment variables are Active")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep XPRV")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/ZerGPbO.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-2-generate-xpubs-extended-public-keys-save-to-environment-variables"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-2-generate-xpubs-extended-public-keys-save-to-environment-variables"}},[t._v("#")]),t._v(" Step 2: Generate XPUBs (Extended Public Keys) & Save to environment variables")]),t._v(" "),e("blockquote",[e("p",[t._v("Generate the three individual Public Keys aka XPUBs using our Private key and descriptor path.")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export XPUB_00=$(bdk-cli key derive --xprv $XPRV_00 --path "m/84\'/1\'/0\'/0" | jq -r ".xpub")')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export XPUB_01=$(bdk-cli key derive --xprv $XPRV_01 --path "m/84\'/1\'/0\'/0" | jq -r ".xpub")')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export XPUB_02=$(bdk-cli key derive --xprv $XPRV_02 --path "m/84\'/1\'/0\'/0" | jq -r ".xpub")')])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/xT3KRh4.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"2a-verify-xpub-environment-variables"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#2a-verify-xpub-environment-variables"}},[t._v("#")]),t._v(" 2a: Verify XPUB environment variables")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep XPUB")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/SzAip9E.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-3-create-single-wallet-descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-3-create-single-wallet-descriptors"}},[t._v("#")]),t._v(" Step 3: Create Single-Wallet Descriptors")]),t._v(" "),e("blockquote",[e("p",[t._v("Create the wallet Descriptor for each wallet")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export DESCRIPTOR_00="$XPRV_00/84h/1h/0h/0/*"')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export DESCRIPTOR_01="$XPRV_01/84h/1h/0h/0/*"')])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export DESCRIPTOR_02="$XPRV_02/84h/1h/0h/0/*"')])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/mFrWt6b.png",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-4-create-multi-sig-descriptor-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-4-create-multi-sig-descriptor-wallets"}},[t._v("#")]),t._v(" Step 4: Create Multi-Sig-Descriptor Wallets")]),t._v(" "),e("blockquote",[e("p",[t._v("This is how you create the 2-of-3 multi-sig output descriptor. You will need (one PrivateKey and two Xpubs) It consists of using the "),e("code",[t._v("compiler")]),t._v(" function to parse "),e("code",[t._v("policy")]),t._v(" to "),e("code",[t._v("mini-script")]),t._v(" .")])]),t._v(" "),e("ul",[e("li",[t._v("When creating the descriptor the order matters so be aware of that when following tutorial if you are for any reason changing the order of the policy.")])]),t._v(" "),e("h4",{attrs:{id:"multi-sig-wallet-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-wallet-0"}},[t._v("#")]),t._v(" Multi-Sig-Wallet 0")]),t._v(" "),e("ul",[e("li",[t._v("[ ] ▶️ "),e("code",[t._v("export MULTI_DESCRIPTOR_00=$(bdk-cli compile \"thresh(2,pk($DESCRIPTOR_00),pk($XPUB_01),pk($XPUB_02))\" | jq -r '.descriptor')")])])]),t._v(" "),e("h4",{attrs:{id:"multi-sig-wallet-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-wallet-1"}},[t._v("#")]),t._v(" Multi-Sig-Wallet 1")]),t._v(" "),e("ul",[e("li",[t._v("[ ] ▶️ "),e("code",[t._v("export MULTI_DESCRIPTOR_01=$(bdk-cli compile \"thresh(2,pk($XPUB_00),pk($DESCRIPTOR_01),pk($XPUB_02))\" | jq -r '.descriptor')")])])]),t._v(" "),e("h4",{attrs:{id:"multi-sig-wallet-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-wallet-2"}},[t._v("#")]),t._v(" Multi-Sig-Wallet 2")]),t._v(" "),e("ul",[e("li",[t._v("[ ] ▶️ "),e("code",[t._v("export MULTI_DESCRIPTOR_02=$(bdk-cli compile \"thresh(2,pk($XPUB_00),pk($XPUB_01),pk($DESCRIPTOR_02))\" | jq -r '.descriptor')")])])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/Yb8RmFS.gif",alt:""}})]),t._v(" "),e("h4",{attrs:{id:"multi-sig-2-of-3-policy-gets-compiled-to-miniscript"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multi-sig-2-of-3-policy-gets-compiled-to-miniscript"}},[t._v("#")]),t._v(" multi-sig 2 of 3 policy gets compiled to miniscript")]),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 comment"}},[t._v("# policy")]),t._v("\nthresh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",pk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("XPRV_A"),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("XPUB_B"),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("XPUB_C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v(" \n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# miniscript")]),t._v("\nwsh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("multi"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",XPRV_KEY,PUBKEY_B,XPUB_C"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("))")]),t._v("\n")])])]),e("hr"),t._v(" "),e("h3",{attrs:{id:"4a-verify-multi-sig-descriptor-environment-variables-are-active"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#4a-verify-multi-sig-descriptor-environment-variables-are-active"}},[t._v("#")]),t._v(" 4a: Verify Multi-Sig-Descriptor environment variables are active")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep MULTI")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/aAgtlsi.gif",alt:""}})]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"step-5-generate-receive-address-by-using-multi-sig-descriptor-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-5-generate-receive-address-by-using-multi-sig-descriptor-wallets"}},[t._v("#")]),t._v(" Step 5: Generate Receive Address by using Multi-Sig-Descriptor Wallets")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 get_new_address")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 get_new_address")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd02 --descriptor $MULTI_DESCRIPTOR_02 get_new_address")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/w1fxPSn.gif",alt:""}})]),t._v(" "),e("p",[t._v("🔴 Did you generate the same address for all three? Good! Else, something might be incorrect.")]),t._v(" "),e("h2",{attrs:{id:"step-6-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-6-send-testnet-bitcoin-to-the-newly-created-receive-address"}},[t._v("#")]),t._v(" Step 6: Send Testnet Bitcoin to the newly created receive-address")]),t._v(" "),e("p",[e("a",{attrs:{href:"https://testnet-faucet.mempool.co",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Testnet Faucet link:1"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Testnet Faucet link:2"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"step-7-sync-one-of-the-multi-sig-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-7-sync-one-of-the-multi-sig-wallets"}},[t._v("#")]),t._v(" Step 7: Sync one of the Multi-Sig Wallets")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 sync")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/GuefgeI.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-8-check-balance-multi-sig-wallets"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-8-check-balance-multi-sig-wallets"}},[t._v("#")]),t._v(" Step 8: Check Balance Multi-Sig Wallets")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 get_balance")])]),t._v(" "),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/zNciCqF.gif",alt:""}})]),t._v(" "),e("ul",[e("li",[t._v("Every wallet has access to sync and view balance.")])]),t._v(" "),e("h2",{attrs:{id:"step-9-check-multi-sig-policies-on-descriptor-wallet"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-9-check-multi-sig-policies-on-descriptor-wallet"}},[t._v("#")]),t._v(" Step 9: Check Multi-Sig Policies on Descriptor Wallet")]),t._v(" "),e("p",[t._v("▶️"),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 policies")])]),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('"external"')]),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('"contribution"')]),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('"conditions"')]),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('"0"')]),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 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 "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"items"')]),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 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 string"}},[t._v('"m"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"n"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sorted"')]),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('"type"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIAL"')]),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('"id"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"seaxtqqn"')]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"keys"')]),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 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('"7cdf2d46"')]),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 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('"fc7870cd"')]),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 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('"26b03333"')]),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 string"}},[t._v('"satisfaction"')]),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('"items"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[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 string"}},[t._v('"m"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"n"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sorted"')]),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('"type"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIAL"')]),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('"threshold"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"type"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"MULTISIG"')]),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('"internal"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),t._v(" null\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n\n")])])]),e("h3",{attrs:{id:"spendingpolicyrequired-for-complex-descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#spendingpolicyrequired-for-complex-descriptors"}},[t._v("#")]),t._v(" SpendingPolicyRequired for complex descriptors")]),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 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('\\"')]),t._v("seaxtqqn"),e("span",{pre:!0,attrs:{class:"token entity",title:'\\"'}},[t._v('\\"')]),t._v(': [0,1]}"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-rootnode-"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("children "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#0 and #1 of root node>")]),t._v("\n")])])]),e("blockquote",[e("p",[t._v("Save the \"id\": We will need to use this ''id'' later.")])]),t._v(" "),e("p",[t._v("More info on "),e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-cli/interface/",target:"_blank",rel:"noopener noreferrer"}},[t._v("external policies here"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"step-10-create-a-transaction-psbt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-10-create-a-transaction-psbt"}},[t._v("#")]),t._v(" Step 10: Create a Transaction (PSBT)")]),t._v(" "),e("ul",[e("li",[t._v("1st Create a PSBT using the first wallet")]),t._v(" "),e("li",[t._v("2nd Sign the PSBT with the first wallet")]),t._v(" "),e("li",[t._v("3rd Sign PSBT with the second wallet")]),t._v(" "),e("li",[t._v("Broadcast PSBT")])]),t._v(" "),e("h3",{attrs:{id:"export-unsigned-psbt-to-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#export-unsigned-psbt-to-environment-variable"}},[t._v("#")]),t._v(" Export UNSIGNED_PSBT to environment variable")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v('export UNSIGNED_PSBT=$(bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 create_tx --send_all --to mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt:0 --external_policy "{\\"CHANGE_ID_HERE\\": [0,1]}" | jq -r \'.psbt\')')])]),t._v(" "),e("h3",{attrs:{id:"verify-unsigned-psbt-environment-variable"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#verify-unsigned-psbt-environment-variable"}},[t._v("#")]),t._v(" Verify UNSIGNED_PSBT environment variable")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("env | grep UNSIGNED")]),t._v(" "),e("img",{attrs:{src:"https://i.imgur.com/djHaRDq.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-11-sign-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-11-sign-the-transaction"}},[t._v("#")]),t._v(" Step 11: SIGN the Transaction")]),t._v(" "),e("h3",{attrs:{id:"1st-wallet-signs-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#1st-wallet-signs-the-transaction"}},[t._v("#")]),t._v(" 1st Wallet Signs the transaction")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 sign --psbt $UNSIGNED_PSBT")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export ONESIG_PSBT=$(bdk-cli wallet --wallet wallet_name_msd00 --descriptor $MULTI_DESCRIPTOR_00 sign --psbt $UNSIGNED_PSBT | jq -r '.psbt')")])]),t._v(" "),e("p",[t._v("▶️"),e("code",[t._v("env | grep ONESIG")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('{\n "is_finalized": false,\n "psbt": "cHNidP8BAFUBAAAAAdYCtva/7Rkt+fgFu3mxAdaPh4uTbgBL3HmYZgcEKWygAAAAAAD/////AQqGAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA6gIAAAAAAQFLyGFJFK884DGBM1WgskRZ6gKp/7oZ+Z30u0+wF3pZYAEAAAAA/v///wKghgEAAAAAACIAINHcOQLE6GpJ3J+FOzn/be+HApxW8sZtGqfA3TBW+NYX91hoOAAAAAAWABTPQDZx2wYYIn+ug2pZBmWBn0Tu/gJHMEQCIHu6GmRMDgPZyTx+klFMA9VujR3qDA/Y08kSkRvOaChjAiBAtExtGAYLuQ/DDJzCqLlNZ1bMB3MV+nxsLfTdI9YcYwEhA0b8lz+kt0xHfR/tjUKOc2Nt2L61pDd5vJ/lsKi8pw9MmFUjAAEBK6CGAQAAAAAAIgAg0dw5AsToakncn4U7Of9t74cCnFbyxm0ap8DdMFb41hciAgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDUgwRQIhAJdILr7G3UzYylyr2fA13MFsz/jG4+iZlKeEkX79d082AiA99UF0/uFyXBVNUmuGaxdHL7wlhzqfbgGLMREN0z/O6QEBBWlSIQIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDSEDzsDXexRPSxeXiLJoS0i2fQlOoOGHmo+Dhaeaq3oHV6YhAjGKA2Dqg+QeMICBAifYslQF2WrehLEQ0iEOpp/+eQ0NU64iBgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDRh83y1GVAAAgAEAAIAAAACAAAAAAAAAAAAiBgIxigNg6oPkHjCAgQIn2LJUBdlq3oSxENIhDqaf/nkNDRgmsDMzVAAAgAEAAIAAAACAAAAAAAAAAAAiBgPOwNd7FE9LF5eIsmhLSLZ9CU6g4Yeaj4OFp5qregdXphj8eHDNVAAAgAEAAIAAAACAAAAAAAAAAAAAAA=="\n}\n')])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/0w4sK5y.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"2nd-wallet-signs-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#2nd-wallet-signs-the-transaction"}},[t._v("#")]),t._v(" 2nd Wallet Signs the transaction")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 sign --psbt $ONESIG_PSBT")])]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("export SECONDSIG_PSBT=$(bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 sign --psbt $ONESIG_PSBT | jq -r '.psbt')")])]),t._v(" "),e("p",[t._v("▶️"),e("code",[t._v("env | grep SECONDSIG")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('{\n "is_finalized": true,\n "psbt": "cHNidP8BAFUBAAAAAdYCtva/7Rkt+fgFu3mxAdaPh4uTbgBL3HmYZgcEKWygAAAAAAD/////AQqGAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA6gIAAAAAAQFLyGFJFK884DGBM1WgskRZ6gKp/7oZ+Z30u0+wF3pZYAEAAAAA/v///wKghgEAAAAAACIAINHcOQLE6GpJ3J+FOzn/be+HApxW8sZtGqfA3TBW+NYX91hoOAAAAAAWABTPQDZx2wYYIn+ug2pZBmWBn0Tu/gJHMEQCIHu6GmRMDgPZyTx+klFMA9VujR3qDA/Y08kSkRvOaChjAiBAtExtGAYLuQ/DDJzCqLlNZ1bMB3MV+nxsLfTdI9YcYwEhA0b8lz+kt0xHfR/tjUKOc2Nt2L61pDd5vJ/lsKi8pw9MmFUjAAEBK6CGAQAAAAAAIgAg0dw5AsToakncn4U7Of9t74cCnFbyxm0ap8DdMFb41hciAgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDUgwRQIhAJdILr7G3UzYylyr2fA13MFsz/jG4+iZlKeEkX79d082AiA99UF0/uFyXBVNUmuGaxdHL7wlhzqfbgGLMREN0z/O6QEiAgPOwNd7FE9LF5eIsmhLSLZ9CU6g4Yeaj4OFp5qregdXpkgwRQIhAO2aRERcublhAzToshkZRMg2I8GaE7mM2ECr0vYyuscmAiB5KK4ETlvrLqL0QbcRbGqrSwIa9lVuOqP3f5qCnGRMaQEBBWlSIQIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDSEDzsDXexRPSxeXiLJoS0i2fQlOoOGHmo+Dhaeaq3oHV6YhAjGKA2Dqg+QeMICBAifYslQF2WrehLEQ0iEOpp/+eQ0NU64iBgIjUCIdnyr6rDtuNhVNt4ZBDcvYLawfoJbzbPyxc/WNDRh83y1GVAAAgAEAAIAAAACAAAAAAAAAAAAiBgIxigNg6oPkHjCAgQIn2LJUBdlq3oSxENIhDqaf/nkNDRgmsDMzVAAAgAEAAIAAAACAAAAAAAAAAAAiBgPOwNd7FE9LF5eIsmhLSLZ9CU6g4Yeaj4OFp5qregdXphj8eHDNVAAAgAEAAIAAAACAAAAAAAAAAAABBwABCP3+AAQASDBFAiEAl0guvsbdTNjKXKvZ8DXcwWzP+Mbj6JmUp4SRfv13TzYCID31QXT+4XJcFU1Sa4ZrF0cvvCWHOp9uAYsxEQ3TP87pAUgwRQIhAO2aRERcublhAzToshkZRMg2I8GaE7mM2ECr0vYyuscmAiB5KK4ETlvrLqL0QbcRbGqrSwIa9lVuOqP3f5qCnGRMaQFpUiECI1AiHZ8q+qw7bjYVTbeGQQ3L2C2sH6CW82z8sXP1jQ0hA87A13sUT0sXl4iyaEtItn0JTqDhh5qPg4Wnmqt6B1emIQIxigNg6oPkHjCAgQIn2LJUBdlq3oSxENIhDqaf/nkNDVOuAAA="\n}\n')])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/OdLHnJ3.gif",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"step-12-broadcast-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#step-12-broadcast-transaction"}},[t._v("#")]),t._v(" Step 12: Broadcast Transaction")]),t._v(" "),e("p",[t._v("▶️ "),e("code",[t._v("bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 broadcast --psbt $SECONDSIG_PSBT")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('{\n "txid": "61da2451874a483aa8d1d0787c7680d157639f284840de8885098cac43f6cc2f"\n}\n')])])]),e("figure",[e("img",{attrs:{src:"https://i.imgur.com/M7s0Fd6.gif",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"verify-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#verify-transaction"}},[t._v("#")]),t._v(" Verify Transaction")]),t._v(" "),e("p",[t._v("Verify transcation 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)])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/44.1195b75f.js b/assets/js/44.5391eb7f.js similarity index 99% rename from assets/js/44.1195b75f.js rename to assets/js/44.5391eb7f.js index 86cb616f3e..8c7a8ae730 100644 --- a/assets/js/44.1195b75f.js +++ b/assets/js/44.5391eb7f.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{392:function(a,e,t){"use strict";t.r(e);var s=t(7),r=Object(s.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h2",{attrs:{id:"introduction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[a._v("#")]),a._v(" Introduction")]),a._v(" "),e("h3",{attrs:{id:"compact-filters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#compact-filters"}},[a._v("#")]),a._v(" Compact Filters:")]),a._v(" "),e("p",[a._v("Compact filters are the latest specification of Bitcoin SPV node implementation as per "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP157"),e("OutboundLink")],1),a._v(" and "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP158"),e("OutboundLink")],1),a._v(". Such light clients were envisioned by Satoshi himself in his original white paper, but due to lack of robust privacy and trust guarantees using conventional "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("bloomfilters"),e("OutboundLink")],1),a._v(", these type of nodes never got popular.")]),a._v(" "),e("p",[a._v("Enters "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP157"),e("OutboundLink")],1),a._v(", which described a new type of filters for Bitcoin Blockchain data, known as "),e("code",[a._v("compact_filters")]),a._v(". The "),e("a",{attrs:{href:"https://github.com/lightninglabs/neutrino",target:"_blank",rel:"noopener noreferrer"}},[a._v("Neutrino"),e("OutboundLink")],1),a._v(' project pioneered the use of compact filter based light client nodes for using with Lightning Network wallets. Using compact filters, a light-node can talk to one or more full nodes, and fetch relevant information from the blockchain, with much more robust privacy and security guarantees than previously possible. Compact filter based nodes are best suitable to be used with mobile wallets, to create more trustless mobile applications on Bitcoin. Any wallet application that needs to have an "eye on the blockchain" has an use for such light clients.')]),a._v(" "),e("p",[e("code",[a._v("BIP157")]),a._v(" type filters allows to create tiny sized SPV nodes, that can fetch blockchain data and can identify inconsistency, so it can actively defend itself, while also preserving its privacy. Such nodes are most useful for Lightning Network mobile applications.")]),a._v(" "),e("p",[a._v("Example of such "),e("code",[a._v("compact_filters")]),a._v(" wallets in wild is "),e("a",{attrs:{href:"https://github.com/breez/breezmobile",target:"_blank",rel:"noopener noreferrer"}},[a._v("Breeze"),e("OutboundLink")],1),a._v(" Lightning mobile wallet.")]),a._v(" "),e("p",[a._v("Bitcoin core supports serving "),e("code",[a._v("BIP157")]),a._v(" type filters from "),e("code",[a._v("v0.21.0")]),a._v(".")]),a._v(" "),e("h3",{attrs:{id:"bdk-and-compact-filters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-and-compact-filters"}},[a._v("#")]),a._v(" BDK and Compact filters")]),a._v(" "),e("p",[a._v("BDK is a bitcoin wallet development library that can be used to create bitcoin wallets with custom "),e("code",[a._v("Database")]),a._v(" and "),e("code",[a._v("Blockchain")]),a._v(" backends. BDK is a "),e("a",{attrs:{href:"https://bitcoindevkit.org/descriptors/",target:"_blank",rel:"noopener noreferrer"}},[a._v("descriptor"),e("OutboundLink")],1),a._v(" based wallet, i.e. the wallet keychain is described by a set of descriptors.")]),a._v(" "),e("p",[a._v("Using BDK one can instantiate wallets of various kinds as per requirement. BDK abstracts away all the heavy lifting works, and allow wallet devs to concentrate on logic that they care about, i.e. writing wallet codes. For more detailed documentation on BDK capabilities check these "),e("a",{attrs:{href:"https://bitcoindevkit.org/blog/2020/12/hello-world/",target:"_blank",rel:"noopener noreferrer"}},[a._v("blog"),e("OutboundLink")],1),a._v(", "),e("a",{attrs:{href:"https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/",target:"_blank",rel:"noopener noreferrer"}},[a._v("bog"),e("OutboundLink")],1),a._v(" and "),e("a",{attrs:{href:"https://docs.rs/bdk/",target:"_blank",rel:"noopener noreferrer"}},[a._v("docs"),e("OutboundLink")],1),a._v(".")]),a._v(" "),e("p",[a._v("The main three components of abstraction in BDK are")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("Database")])]),a._v(" "),e("li",[e("code",[a._v("Descriptors")])]),a._v(" "),e("li",[e("code",[a._v("Blockchain")])])]),a._v(" "),e("p",[a._v("BDK comes with default implementations of all them that developers can start with out of the box. Developers can also create their own custom implementations and plug it into BDK (thanks to rust magic of "),e("code",[a._v("Traits")]),a._v(").")]),a._v(" "),e("p",[a._v("BDK also supports "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP158"),e("OutboundLink")],1),a._v(" communication protocol, which allows creation of "),e("code",[a._v("BIP157")]),a._v(" type compact filter SPV nodes. This capability is extended to wallet with BDK's "),e("code",[a._v("Blockchain")]),a._v(" data structure. The "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("API"),e("OutboundLink")],1),a._v(" for "),e("code",[a._v("compact_filters")]),a._v(" backend is similar to any other kind of backends, so wallet devs don't need to worry about all the details. Its ok if the dev haven't even heard of "),e("code",[a._v("BIP157")]),a._v(", BDK takes care of that in background.")]),a._v(" "),e("p",[a._v("This capability can be unlocked by compiling BDK with the "),e("code",[a._v("compact_filters")]),a._v(" feature. Once enabled, BDK will be able to create wallets with the "),e("code",[a._v("compact_filters")]),a._v(" type "),e("code",[a._v("Blockchain")]),a._v(" backend. (The default backend is electrum server)")]),a._v(" "),e("h3",{attrs:{id:"bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-cli"}},[a._v("#")]),a._v(" bdk-cli")]),a._v(" "),e("p",[e("code",[a._v("bdk-cli")]),a._v(" is a lightweight "),e("a",{attrs:{href:"https://codewith.mu/en/tutorials/1.0/repl",target:"_blank",rel:"noopener noreferrer"}},[a._v("REPL"),e("OutboundLink")],1),a._v(" wrapper over the BDK library to facilitate quick and easy demonstration of BDK capabilities in command-line. Wallet devs can use this tool to quickly try out different possibilities with BDK.")]),a._v(" "),e("p",[a._v("In this tutorial, We will use "),e("code",[a._v("bdk-cli")]),a._v(" to demonstrate some basic wallet functionalities using "),e("code",[a._v("compact_filters")]),a._v(" backend.")]),a._v(" "),e("h2",{attrs:{id:"tutorial-scope"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tutorial-scope"}},[a._v("#")]),a._v(" Tutorial Scope")]),a._v(" "),e("p",[a._v("Basic wallet workflow we will cover:")]),a._v(" "),e("ul",[e("li",[a._v("create and sync a wallet,")]),a._v(" "),e("li",[a._v("receive a transaction,")]),a._v(" "),e("li",[a._v("create a transaction,")]),a._v(" "),e("li",[a._v("sign and broadcast the transaction,")]),a._v(" "),e("li",[a._v("fetch updated balance,")])]),a._v(" "),e("p",[a._v("The BDK wallet will have a "),e("code",[a._v("BIP157")]),a._v(" SPV backend (aka "),e("code",[a._v("compact_filters")]),a._v(" backend) that will connect with a Bitcoin core node serving filter data.")]),a._v(" "),e("p",[a._v("It will publish and extract transaction data through that node.")]),a._v(" "),e("p",[a._v("We will have a Bitcoin Core wallet and a BDK wallet, sending and receiving transactions between each other, in regtest.")]),a._v(" "),e("h2",{attrs:{id:"prerequisites"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[a._v("#")]),a._v(" Prerequisites")]),a._v(" "),e("p",[a._v("Following things are required to start with the tutorial.")]),a._v(" "),e("ol",[e("li",[a._v("A Bitcoin Core regtest node listening at "),e("code",[a._v("localhost:18444")]),a._v(" signalling for compact filter support.")]),a._v(" "),e("li",[e("code",[a._v("bdk-cli")]),a._v(" compiled with "),e("code",[a._v("compact_filter")]),a._v(" features.")])]),a._v(" "),e("p",[a._v("If you already have these two setup and working, you can skip this and jump to the "),e("a",{attrs:{href:"#tutorial"}},[a._v("Tutorial")]),a._v(" section.")]),a._v(" "),e("h3",{attrs:{id:"install-and-run-bitcoind"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#install-and-run-bitcoind"}},[a._v("#")]),a._v(" Install and run "),e("code",[a._v("bitcoind")])]),a._v(" "),e("p",[a._v("You can definitely do it with your own "),e("code",[a._v("bitcoind")]),a._v(" installation. "),e("code",[a._v("BIP157")]),a._v(" support has been included in Bitcoin Core "),e("code",[a._v("v0.21.0")]),a._v(". So anything above that will work.")]),a._v(" "),e("p",[a._v("You also need to ensure proper configuration settings for signalling "),e("code",[a._v("compact_filters")]),a._v(" support.")]),a._v(" "),e("p",[a._v("For ease of testing, the BDK project hosts docker images that can be used to spawn Bitcoin Core with all the relevant configurations.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("spawn a regtest node using "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoin-regtest-box",target:"_blank",rel:"noopener noreferrer"}},[a._v("bitcoin-regtest-box"),e("OutboundLink")],1),a._v(" docker file.")]),a._v(" "),e("p",[a._v("Start the regtest box docker container.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" run "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--detach")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--rm")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-p")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("127.0")]),a._v(".0.1:18443-18444:18443-18444/tcp "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--name")]),a._v(" bdk-box bitcoindevkit/bitcoind\n")])])]),e("p",[a._v("This will spin up a docker container running "),e("code",[a._v("bicoind")]),a._v(" and listening to port "),e("code",[a._v("18444")]),a._v(" and "),e("code",[a._v("18333")]),a._v(". You can keep this terminal alive to see communication events with BDK and the node.")])]),a._v(" "),e("li",[e("p",[a._v("Check node is reachable")]),a._v(" "),e("p",[a._v("In another terminal try connecting to the node with "),e("code",[a._v("bitcoin-cli")])]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getnetworkinfo\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"version"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("210000")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"subversion"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"/Satoshi:0.21.1/"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"protocolversion"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("70016")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"localservices"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"0000000000000449"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"localservicesnames"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NETWORK"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"WITNESS"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"COMPACT_FILTERS"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NETWORK_LIMITED"')]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(".\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n")])])]),e("p",[a._v("In the output, the "),e("code",[a._v("version")]),a._v(" should show "),e("code",[a._v("210000")]),a._v(". "),e("code",[a._v("localservicesnames")]),a._v(" should contain "),e("code",[a._v('"COMPACT_FILTERS"')]),a._v(". If you see this, then Bitcoin Core is correctly configured.")])])]),a._v(" "),e("h3",{attrs:{id:"install-and-run-bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#install-and-run-bdk-cli"}},[a._v("#")]),a._v(" Install and run bdk-cli")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Install "),e("code",[a._v("bdk-cli")]),a._v(" with "),e("code",[a._v("compact_filters")]),a._v(" feature")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("cargo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--git")]),a._v(" https://github.com/bitcoindevkit/bdk-cli.git bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--features")]),a._v(" compact_filters\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Check installation")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--help")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(".\nUSAGE:\n bdk-cli "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("OPTIONS"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("SUBCOMMAND"),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("\nFLAGS:\n -h, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--help")]),a._v(" Prints "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v(" information\n -V, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--version")]),a._v(" Prints version information\nOPTIONS:\n -n, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("NETWORK"),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v(" Sets the network "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("default: testnet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n\nSUBCOMMANDS:\n "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v(" Prints this message or the "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v(" of the given subcommand"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("s"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n key Key management sub-commands\n repl Enter REPL "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("command")]),a._v(" loop mode\n wallet Wallet options and sub-commands\n")])])])])]),a._v(" "),e("p",[a._v("Once these are setup correctly, you can start with the tutorial next.")]),a._v(" "),e("h2",{attrs:{id:"tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tutorial"}},[a._v("#")]),a._v(" Tutorial")]),a._v(" "),e("p",[a._v("[Note: For brevity "),e("code",[a._v("bdk-cli")]),a._v(" results are stored in command line variables using "),e("code",[a._v("jq")]),a._v(" tool. It is recommended to check the full results to see different information returned by "),e("code",[a._v("bdk-cli")]),a._v(" commands.]")]),a._v(" "),e("h3",{attrs:{id:"bitcoin-core-wallet-generation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-core-wallet-generation"}},[a._v("#")]),a._v(" Bitcoin Core Wallet Generation")]),a._v(" "),e("p",[a._v("This is standard procedure with "),e("code",[a._v("bitcoin-cli")]),a._v(".")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Create a wallet and generate 101 blocks.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" createwallet "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("test")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"test"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"warning"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('""')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getnewaddress\nbcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("101")]),a._v(" bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3813ed6eb716f4743b9657d918799acf743add985a8ded28d8aa3629dd4496b6"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"70da855913bdf791b6e458c611cebdef79b7a9840eb103ce58c71c1c7e3c49bc"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"682ca732ef72719cd6f82c5047c7690fb1cd2df2543d035ac4ea99e974b8d172"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"78799e4771017d4f46aa3c240054e2d61f54cea07ec44cb18ae712761e0aaa1e"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(".\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getbalance\n"),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("50.00000000")]),a._v("\n")])])]),e("p",[a._v("Now the core wallet has generated new blocks and is funded with test bitcoin.")])])]),a._v(" "),e("h3",{attrs:{id:"bdk-wallet-generation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-wallet-generation"}},[a._v("#")]),a._v(" BDK Wallet Generation")]),a._v(" "),e("p",[a._v("BDK is a descriptor based wallet library. So in order to use it we will need some descriptors to work with.")]),a._v(" "),e("p",[a._v("BDK wallet will ask for two descriptors as input, corresponding to "),e("code",[a._v("receive")]),a._v(" and "),e("code",[a._v("change")]),a._v(" addresses. Its recommended to have these two descriptors separate as BDK will handle them separately and ensure "),e("code",[a._v("change")]),a._v(" addresses are never used for receiving funds.")]),a._v(" "),e("p",[a._v("Or developers can decide to use a single descriptor too, in that case BDK will use that descriptor for deriving both "),e("code",[a._v("receive")]),a._v(" and "),e("code",[a._v("change")]),a._v(" addresses.")]),a._v(" "),e("p",[a._v("We will use "),e("code",[a._v("bdk-cli")]),a._v(" itself to generate such descriptors.")]),a._v(" "),e("ul",[e("li",[e("h4",{attrs:{id:"generate-a-privatekey"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#generate-a-privatekey"}},[a._v("#")]),a._v(" Generate a privatekey")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BDK_xprv")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n$ "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_xprv")]),a._v("\ntprv8ZgxMBicQKsPefY7tdq7EKny81n9tfSvUYfSHAZByXdjPAZVysvaB6sFd2YavqfqMBgbHaXUG5oWM6sYvdJn6vnUizzQKTYAJ36bQsfPv4N\n")])])]),e("p",[e("code",[a._v("bdk-cli key generate")]),a._v(" will generate a fresh master key with "),e("code",[a._v("mnemonic")]),a._v(" and "),e("code",[a._v("xprv")]),a._v(". We have extracted the value of extended private key and stored it in "),e("code",[a._v("BDK_xprv")]),a._v(" variable.")]),a._v(" "),e("p",[a._v("The returned "),e("code",[a._v("mnemonic")]),a._v(" can be used to restore back the wallet if wallet data directory is lost.")])]),a._v(" "),e("li",[e("h4",{attrs:{id:"generate-descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#generate-descriptors"}},[a._v("#")]),a._v(" Generate Descriptors")]),a._v(" "),e("p",[e("code",[a._v("bdk-cli key derive")]),a._v(" can derive an "),e("code",[a._v("xpub")]),a._v("s given a "),e("code",[a._v("master key")]),a._v(" and "),e("code",[a._v("derivation_path")]),a._v(".")]),a._v(" "),e("p",[a._v("We will use the following paths for our "),e("code",[a._v("receive")]),a._v(" and "),e("code",[a._v("change")]),a._v(" descriptors")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("receive")]),a._v(" path: "),e("code",[a._v("m/84h/1h/0h/0")])]),a._v(" "),e("li",[e("code",[a._v("change")]),a._v(" path: "),e("code",[a._v("m/84h/1h/0h/1")]),a._v(",")])]),a._v(" "),e("p",[a._v("We can then simply wrap them in a "),e("code",[a._v('"wpkh()"')]),a._v(" to create our descriptors string and store them.")]),a._v(" "),e("p",[a._v("When asked for a new address, BDK will derive one from the "),e("code",[a._v("receive")]),a._v(" descriptor.")]),a._v(" "),e("p",[a._v("And while constructing transaction, BDK will use the "),e("code",[a._v("change")]),a._v(" descriptor to derive change address.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BDK_recv_desc")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wpkh('),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" m/84h/1h/0h/0 "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $BDK_xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v(')"')]),a._v("\n$ "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v("\nwpkh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("ff09c7c9/84"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'/1'")]),a._v("/0'/0"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("tprv8hkdEGgwLLnqsdfkJFidpTj5d6z5qFdP6Qwzsviea3HrS9C2mXXaDivPKCCgcaWvnGNX9eciLUQs91PWYXJqrChfnAagViCgG6L5phaNyWr/*"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BDK_chng_desc")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wpkh('),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" m/84h/1h/0h/1 "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $BDK_xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v(')"')]),a._v("\n$ "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v("\nwpkh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("ff09c7c9/84"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'/1'")]),a._v("/0'/1"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("tprv8hkdEGgwLLnqtbYkGG7fSy7v43RF2SQGGjNuZtmBzEHh7H8xgpXBETQAbVPqi8rkvLNFKLYY4rDzXA4fn5Ha1yuazZqhQPe3uNKmFS7648s/*"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n")])])]),e("p",[a._v("Note: "),e("code",[a._v("BDK_xprv")]),a._v(" has been used as the "),e("code",[a._v("master key")]),a._v(", this will allow BDK to have signing capabilities.\nWe could have used an "),e("code",[a._v("xpub")]),a._v(" master key here instead, that would create an "),e("code",[a._v("watch-only")]),a._v(" wallet.")])]),a._v(" "),e("li",[e("h4",{attrs:{id:"create-and-sync-a-wallet"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#create-and-sync-a-wallet"}},[a._v("#")]),a._v(" Create and Sync a wallet")]),a._v(" "),e("p",[a._v("We will now instruct BDK to create a new wallet with following instructions")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("ul",[e("li",[a._v("name ("),e("code",[a._v("--wallet")]),a._v(") "),e("code",[a._v("bdk-test")]),a._v(",")]),a._v(" "),e("li",[e("code",[a._v("receive")]),a._v(" descriptor ("),e("code",[a._v("-d")]),a._v(") as "),e("code",[a._v("$BDK_recv_desc")]),a._v(" and change descriptor ("),e("code",[a._v("-c")]),a._v(") as "),e("code",[a._v("$BDK_chng_desc")]),a._v(",")]),a._v(" "),e("li",[a._v("connected to a full node ("),e("code",[a._v("--node")]),a._v(") listening at "),e("code",[a._v("127.0.0.1:18444")]),a._v(",")]),a._v(" "),e("li",[a._v("and finally create and sync the wallet with the "),e("code",[a._v("sync")]),a._v(" command.")])]),a._v(" "),e("p",[a._v("If you are using a "),e("code",[a._v("regtest")]),a._v(" node, also add "),e("code",[a._v("--network regtest")]),a._v(", the default is "),e("code",[a._v("testnet")]),a._v(".")]),a._v(" "),e("p",[e("code",[a._v("bdk-cli")]),a._v(" makes multiple parallel connections that can be configured with the "),e("code",[a._v("--conn-count")]),a._v(" parameter (default is 4). This makes syncing parallel and fast. Use "),e("code",[a._v("bdk-cli --help")]),a._v(" to see all other options.")]),a._v(" "),e("p",[a._v("Getting an empty return means wallet creation succeeded.")]),a._v(" "),e("p",[a._v("BDK has created a wallet named "),e("code",[a._v("bdk-test")]),a._v(" in its data directory. Which is by default stored at "),e("code",[a._v("~/.bdk-bitcoin/compact_filters")]),a._v(" folder.")]),a._v(" "),e("p",[a._v("Looking into that folder different files and directories maintained by BDK can be seen.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("ls")]),a._v(" .bdk-bitcoin/compact_filters/\n000004.log CURRENT LOCK MANIFEST-000003 OPTIONS-000010\nbdk-test IDENTITY LOG OPTIONS-000008\n")])])])])]),a._v(" "),e("h3",{attrs:{id:"recieve-coins"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#recieve-coins"}},[a._v("#")]),a._v(" Recieve Coins")]),a._v(" "),e("p",[a._v("We will use the "),e("code",[a._v("core")]),a._v(" wallet to send 5 BTC to our"),e("code",[a._v("bdk-test")]),a._v(" wallet.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Fetch a new address using "),e("code",[a._v("bdk-cli")])]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" get_new_address\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Transfer funds to the previous address and generate a block, using "),e("code",[a._v("bitcoin-cli")])]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" sendtoaddress bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9 "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("5")]),a._v("\n\n\n$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),a._v(" bcrt1qw3ht9xtc9pgyvmqay0ap9fw8mxd27az8el0uz3\n")])])]),e("p",[e("code",[a._v("core")]),a._v(" has sent 5 BTC to our "),e("code",[a._v("bdk-test")]),a._v(" wallet. Which is confirmed in a new block.")]),a._v(" "),e("p",[e("code",[a._v("bdk-test")]),a._v(" can see that now by syncing again.")]),a._v(" "),e("p",[a._v("(Note: BDK required explicit "),e("code",[a._v("sync()")]),a._v(" calls to give wallet developers flexibility on when to sync).")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("500000000")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("We can see "),e("code",[a._v("500000000")]),a._v(" sats balance in our "),e("code",[a._v("bdk-test")]),a._v(" wallet.")]),a._v(" "),e("p",[a._v("BDK has fetched blockchain details concerning its wallet descriptors, from the core node, using compact filters.")])])]),a._v(" "),e("h3",{attrs:{id:"creating-a-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-transaction"}},[a._v("#")]),a._v(" Creating a transaction.")]),a._v(" "),e("p",[a._v("Now we want to create a transaction sending coins from "),e("code",[a._v("bdk-test")]),a._v(" wallet to the "),e("code",[a._v("core")]),a._v(" wallet.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("fetch a new "),e("code",[a._v("core")]),a._v(" address")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("core_addrs")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getnewaddress "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("tr")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'\\r'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Create a raw transaction using "),e("code",[a._v("bdk-cli")]),a._v(" to the above address. This will generate a "),e("code",[a._v("psbt")]),a._v(" which we will sign.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("psbt")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BDK_recv_desc "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" $BDK_chng_desc create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" $core_addrs:200000000 "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.psbt'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),e("p",[a._v("(Recommended to check all the other information returned by "),e("code",[a._v("bdk-cli create_tx")]),a._v(")")])])]),a._v(" "),e("h3",{attrs:{id:"sign-and-broadcast-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#sign-and-broadcast-the-transaction"}},[a._v("#")]),a._v(" Sign and Broadcast the transaction")]),a._v(" "),e("p",[a._v("Asking BDK to sign a transaction is as straight forward as it can get. BDK already holds the "),e("code",[a._v("xprv")]),a._v(" deatils to sign a transaction. It returns a finalised "),e("code",[a._v("signed_psbt")]),a._v(" which we will next broadcast to the network.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Sign the transaction")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("signed_psbt")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BDK_recv_desc "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" $BDK_chng_desc sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $psbt "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.psbt'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Broadcast the transaction")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$signed_psbt")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("This makes BDK broadcast the transaction via the connected core node, and it returns the corresponding Txid.")])])]),a._v(" "),e("h3",{attrs:{id:"confirming-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#confirming-the-transaction"}},[a._v("#")]),a._v(" Confirming the Transaction")]),a._v(" "),e("p",[a._v("The transaction has been received by the "),e("code",[a._v("core")]),a._v(" node and waiting in its mempool for inclusion in block.\nWe can see the transaction via its "),e("code",[a._v("txid")]),a._v(" received in previous step.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Check transaction in mempool")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" gettransaction c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e2248e52e0852252\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"amount"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("2.00000000")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"confirmations"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"trusted"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" false,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"walletconflicts"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"time"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1621697202")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"timereceived"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1621697202")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"bip125-replaceable"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"no"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"details"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"bcrt1q3h4hs6mve5dcl7da3d4acmlp20hh8c3t4mldwe"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"category"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"receive"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"amount"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("2.00000000")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"label"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('""')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"vout"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"hex"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"01000000000101d84e8cb7477f9fe6f265b56d5416ff47da9a70be18f65ec50731b8257c67f2bd0100000000ffffffff0273a2e11100000000160014874270187001febc4cebd8cb083cf2c783e8f1ac00c2eb0b000000001600148deb786b6ccd1b8ff9bd8b6bdc6fe153ef73e22b0247304402201037d9ef5b80392296311c8899b1f12a0987778d694a442a88bafa6fbd7a7c9a022011293176255897444d9c71b0b9cd13b2aedb749b142577566c90a63d61025e2c01210202427d16b29c1c8546255363a74326ee9ab3196770bb3fccc7b679d52f9c1ccf00000000"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("This means, core has recieved the transaction in its mempool and waiting for confirmation.")])]),a._v(" "),e("li",[e("p",[a._v("Generate 1 block to confirm the transaction")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),a._v(" bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"55436ff0169bbb3e70ab10cb7cdd45ab86204d5d7864a109142d91120d023197"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Sync the "),e("code",[a._v("bdk-test")]),a._v(" wallet and ask for available balance.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v(" $ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n $ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" get_balance\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n \t"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("299999859")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("If you see the balance updated, voila!")]),a._v(" "),e("p",[a._v("What happened here is:")]),a._v(" "),e("ul",[e("li",[a._v("core created a new block containing the transaction.")]),a._v(" "),e("li",[e("code",[a._v("bdk-cli")]),a._v(" fetched the corresponding filter data.")]),a._v(" "),e("li",[a._v("It noticed it got a concerning transaction.")]),a._v(" "),e("li",[a._v("It asked for the details of that transaction from the core node.")]),a._v(" "),e("li",[a._v("It updated its wallet details with this new information.")]),a._v(" "),e("li",[a._v("The update is reflected in the wallet balance.")])])])]),a._v(" "),e("h3",{attrs:{id:"shutdown-docker"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#shutdown-docker"}},[a._v("#")]),a._v(" Shutdown Docker")]),a._v(" "),e("p",[a._v("You may now shutdown the regtest docker container.")]),a._v(" "),e("p",[a._v("Note: This will also clean up any data in the bitcoin core, including the wallet.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("kill")]),a._v(" bdk-box\n")])])]),e("h2",{attrs:{id:"end-words"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#end-words"}},[a._v("#")]),a._v(" End Words")]),a._v(" "),e("p",[a._v("In this tutorial we went through the process of receiving, creating, signing and broadcasting transaction using the BDK wallet with "),e("code",[a._v("compact_filters")]),a._v(" feature. This demonstrates how BDK capabilities can be used to create SPV light wallets with integrated "),e("code",[a._v("BIP157")]),a._v(" type "),e("code",[a._v("compact_filters")]),a._v(" node.")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{393:function(a,e,t){"use strict";t.r(e);var s=t(7),r=Object(s.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h2",{attrs:{id:"introduction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[a._v("#")]),a._v(" Introduction")]),a._v(" "),e("h3",{attrs:{id:"compact-filters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#compact-filters"}},[a._v("#")]),a._v(" Compact Filters:")]),a._v(" "),e("p",[a._v("Compact filters are the latest specification of Bitcoin SPV node implementation as per "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP157"),e("OutboundLink")],1),a._v(" and "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP158"),e("OutboundLink")],1),a._v(". Such light clients were envisioned by Satoshi himself in his original white paper, but due to lack of robust privacy and trust guarantees using conventional "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("bloomfilters"),e("OutboundLink")],1),a._v(", these type of nodes never got popular.")]),a._v(" "),e("p",[a._v("Enters "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP157"),e("OutboundLink")],1),a._v(", which described a new type of filters for Bitcoin Blockchain data, known as "),e("code",[a._v("compact_filters")]),a._v(". The "),e("a",{attrs:{href:"https://github.com/lightninglabs/neutrino",target:"_blank",rel:"noopener noreferrer"}},[a._v("Neutrino"),e("OutboundLink")],1),a._v(' project pioneered the use of compact filter based light client nodes for using with Lightning Network wallets. Using compact filters, a light-node can talk to one or more full nodes, and fetch relevant information from the blockchain, with much more robust privacy and security guarantees than previously possible. Compact filter based nodes are best suitable to be used with mobile wallets, to create more trustless mobile applications on Bitcoin. Any wallet application that needs to have an "eye on the blockchain" has an use for such light clients.')]),a._v(" "),e("p",[e("code",[a._v("BIP157")]),a._v(" type filters allows to create tiny sized SPV nodes, that can fetch blockchain data and can identify inconsistency, so it can actively defend itself, while also preserving its privacy. Such nodes are most useful for Lightning Network mobile applications.")]),a._v(" "),e("p",[a._v("Example of such "),e("code",[a._v("compact_filters")]),a._v(" wallets in wild is "),e("a",{attrs:{href:"https://github.com/breez/breezmobile",target:"_blank",rel:"noopener noreferrer"}},[a._v("Breeze"),e("OutboundLink")],1),a._v(" Lightning mobile wallet.")]),a._v(" "),e("p",[a._v("Bitcoin core supports serving "),e("code",[a._v("BIP157")]),a._v(" type filters from "),e("code",[a._v("v0.21.0")]),a._v(".")]),a._v(" "),e("h3",{attrs:{id:"bdk-and-compact-filters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-and-compact-filters"}},[a._v("#")]),a._v(" BDK and Compact filters")]),a._v(" "),e("p",[a._v("BDK is a bitcoin wallet development library that can be used to create bitcoin wallets with custom "),e("code",[a._v("Database")]),a._v(" and "),e("code",[a._v("Blockchain")]),a._v(" backends. BDK is a "),e("a",{attrs:{href:"https://bitcoindevkit.org/descriptors/",target:"_blank",rel:"noopener noreferrer"}},[a._v("descriptor"),e("OutboundLink")],1),a._v(" based wallet, i.e. the wallet keychain is described by a set of descriptors.")]),a._v(" "),e("p",[a._v("Using BDK one can instantiate wallets of various kinds as per requirement. BDK abstracts away all the heavy lifting works, and allow wallet devs to concentrate on logic that they care about, i.e. writing wallet codes. For more detailed documentation on BDK capabilities check these "),e("a",{attrs:{href:"https://bitcoindevkit.org/blog/2020/12/hello-world/",target:"_blank",rel:"noopener noreferrer"}},[a._v("blog"),e("OutboundLink")],1),a._v(", "),e("a",{attrs:{href:"https://bitcoindevkit.org/blog/2020/11/descriptors-in-the-wild/",target:"_blank",rel:"noopener noreferrer"}},[a._v("bog"),e("OutboundLink")],1),a._v(" and "),e("a",{attrs:{href:"https://docs.rs/bdk/",target:"_blank",rel:"noopener noreferrer"}},[a._v("docs"),e("OutboundLink")],1),a._v(".")]),a._v(" "),e("p",[a._v("The main three components of abstraction in BDK are")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("Database")])]),a._v(" "),e("li",[e("code",[a._v("Descriptors")])]),a._v(" "),e("li",[e("code",[a._v("Blockchain")])])]),a._v(" "),e("p",[a._v("BDK comes with default implementations of all them that developers can start with out of the box. Developers can also create their own custom implementations and plug it into BDK (thanks to rust magic of "),e("code",[a._v("Traits")]),a._v(").")]),a._v(" "),e("p",[a._v("BDK also supports "),e("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[a._v("BIP158"),e("OutboundLink")],1),a._v(" communication protocol, which allows creation of "),e("code",[a._v("BIP157")]),a._v(" type compact filter SPV nodes. This capability is extended to wallet with BDK's "),e("code",[a._v("Blockchain")]),a._v(" data structure. The "),e("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/trait.Blockchain.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("API"),e("OutboundLink")],1),a._v(" for "),e("code",[a._v("compact_filters")]),a._v(" backend is similar to any other kind of backends, so wallet devs don't need to worry about all the details. Its ok if the dev haven't even heard of "),e("code",[a._v("BIP157")]),a._v(", BDK takes care of that in background.")]),a._v(" "),e("p",[a._v("This capability can be unlocked by compiling BDK with the "),e("code",[a._v("compact_filters")]),a._v(" feature. Once enabled, BDK will be able to create wallets with the "),e("code",[a._v("compact_filters")]),a._v(" type "),e("code",[a._v("Blockchain")]),a._v(" backend. (The default backend is electrum server)")]),a._v(" "),e("h3",{attrs:{id:"bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-cli"}},[a._v("#")]),a._v(" bdk-cli")]),a._v(" "),e("p",[e("code",[a._v("bdk-cli")]),a._v(" is a lightweight "),e("a",{attrs:{href:"https://codewith.mu/en/tutorials/1.0/repl",target:"_blank",rel:"noopener noreferrer"}},[a._v("REPL"),e("OutboundLink")],1),a._v(" wrapper over the BDK library to facilitate quick and easy demonstration of BDK capabilities in command-line. Wallet devs can use this tool to quickly try out different possibilities with BDK.")]),a._v(" "),e("p",[a._v("In this tutorial, We will use "),e("code",[a._v("bdk-cli")]),a._v(" to demonstrate some basic wallet functionalities using "),e("code",[a._v("compact_filters")]),a._v(" backend.")]),a._v(" "),e("h2",{attrs:{id:"tutorial-scope"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tutorial-scope"}},[a._v("#")]),a._v(" Tutorial Scope")]),a._v(" "),e("p",[a._v("Basic wallet workflow we will cover:")]),a._v(" "),e("ul",[e("li",[a._v("create and sync a wallet,")]),a._v(" "),e("li",[a._v("receive a transaction,")]),a._v(" "),e("li",[a._v("create a transaction,")]),a._v(" "),e("li",[a._v("sign and broadcast the transaction,")]),a._v(" "),e("li",[a._v("fetch updated balance,")])]),a._v(" "),e("p",[a._v("The BDK wallet will have a "),e("code",[a._v("BIP157")]),a._v(" SPV backend (aka "),e("code",[a._v("compact_filters")]),a._v(" backend) that will connect with a Bitcoin core node serving filter data.")]),a._v(" "),e("p",[a._v("It will publish and extract transaction data through that node.")]),a._v(" "),e("p",[a._v("We will have a Bitcoin Core wallet and a BDK wallet, sending and receiving transactions between each other, in regtest.")]),a._v(" "),e("h2",{attrs:{id:"prerequisites"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[a._v("#")]),a._v(" Prerequisites")]),a._v(" "),e("p",[a._v("Following things are required to start with the tutorial.")]),a._v(" "),e("ol",[e("li",[a._v("A Bitcoin Core regtest node listening at "),e("code",[a._v("localhost:18444")]),a._v(" signalling for compact filter support.")]),a._v(" "),e("li",[e("code",[a._v("bdk-cli")]),a._v(" compiled with "),e("code",[a._v("compact_filter")]),a._v(" features.")])]),a._v(" "),e("p",[a._v("If you already have these two setup and working, you can skip this and jump to the "),e("a",{attrs:{href:"#tutorial"}},[a._v("Tutorial")]),a._v(" section.")]),a._v(" "),e("h3",{attrs:{id:"install-and-run-bitcoind"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#install-and-run-bitcoind"}},[a._v("#")]),a._v(" Install and run "),e("code",[a._v("bitcoind")])]),a._v(" "),e("p",[a._v("You can definitely do it with your own "),e("code",[a._v("bitcoind")]),a._v(" installation. "),e("code",[a._v("BIP157")]),a._v(" support has been included in Bitcoin Core "),e("code",[a._v("v0.21.0")]),a._v(". So anything above that will work.")]),a._v(" "),e("p",[a._v("You also need to ensure proper configuration settings for signalling "),e("code",[a._v("compact_filters")]),a._v(" support.")]),a._v(" "),e("p",[a._v("For ease of testing, the BDK project hosts docker images that can be used to spawn Bitcoin Core with all the relevant configurations.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("spawn a regtest node using "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoin-regtest-box",target:"_blank",rel:"noopener noreferrer"}},[a._v("bitcoin-regtest-box"),e("OutboundLink")],1),a._v(" docker file.")]),a._v(" "),e("p",[a._v("Start the regtest box docker container.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" run "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--detach")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--rm")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-p")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("127.0")]),a._v(".0.1:18443-18444:18443-18444/tcp "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--name")]),a._v(" bdk-box bitcoindevkit/bitcoind\n")])])]),e("p",[a._v("This will spin up a docker container running "),e("code",[a._v("bicoind")]),a._v(" and listening to port "),e("code",[a._v("18444")]),a._v(" and "),e("code",[a._v("18333")]),a._v(". You can keep this terminal alive to see communication events with BDK and the node.")])]),a._v(" "),e("li",[e("p",[a._v("Check node is reachable")]),a._v(" "),e("p",[a._v("In another terminal try connecting to the node with "),e("code",[a._v("bitcoin-cli")])]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getnetworkinfo\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"version"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("210000")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"subversion"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"/Satoshi:0.21.1/"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"protocolversion"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("70016")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"localservices"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"0000000000000449"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"localservicesnames"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NETWORK"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"WITNESS"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"COMPACT_FILTERS"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"NETWORK_LIMITED"')]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(".\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n")])])]),e("p",[a._v("In the output, the "),e("code",[a._v("version")]),a._v(" should show "),e("code",[a._v("210000")]),a._v(". "),e("code",[a._v("localservicesnames")]),a._v(" should contain "),e("code",[a._v('"COMPACT_FILTERS"')]),a._v(". If you see this, then Bitcoin Core is correctly configured.")])])]),a._v(" "),e("h3",{attrs:{id:"install-and-run-bdk-cli"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#install-and-run-bdk-cli"}},[a._v("#")]),a._v(" Install and run bdk-cli")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Install "),e("code",[a._v("bdk-cli")]),a._v(" with "),e("code",[a._v("compact_filters")]),a._v(" feature")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("cargo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--git")]),a._v(" https://github.com/bitcoindevkit/bdk-cli.git bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--features")]),a._v(" compact_filters\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Check installation")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--help")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(".\nUSAGE:\n bdk-cli "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("OPTIONS"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("SUBCOMMAND"),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("\nFLAGS:\n -h, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--help")]),a._v(" Prints "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v(" information\n -V, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--version")]),a._v(" Prints version information\nOPTIONS:\n -n, "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("NETWORK"),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v(" Sets the network "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("default: testnet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n\nSUBCOMMANDS:\n "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v(" Prints this message or the "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("help")]),a._v(" of the given subcommand"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("s"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n key Key management sub-commands\n repl Enter REPL "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("command")]),a._v(" loop mode\n wallet Wallet options and sub-commands\n")])])])])]),a._v(" "),e("p",[a._v("Once these are setup correctly, you can start with the tutorial next.")]),a._v(" "),e("h2",{attrs:{id:"tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tutorial"}},[a._v("#")]),a._v(" Tutorial")]),a._v(" "),e("p",[a._v("[Note: For brevity "),e("code",[a._v("bdk-cli")]),a._v(" results are stored in command line variables using "),e("code",[a._v("jq")]),a._v(" tool. It is recommended to check the full results to see different information returned by "),e("code",[a._v("bdk-cli")]),a._v(" commands.]")]),a._v(" "),e("h3",{attrs:{id:"bitcoin-core-wallet-generation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-core-wallet-generation"}},[a._v("#")]),a._v(" Bitcoin Core Wallet Generation")]),a._v(" "),e("p",[a._v("This is standard procedure with "),e("code",[a._v("bitcoin-cli")]),a._v(".")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Create a wallet and generate 101 blocks.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" createwallet "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("test")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"name"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"test"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"warning"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('""')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getnewaddress\nbcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("101")]),a._v(" bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"3813ed6eb716f4743b9657d918799acf743add985a8ded28d8aa3629dd4496b6"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"70da855913bdf791b6e458c611cebdef79b7a9840eb103ce58c71c1c7e3c49bc"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"682ca732ef72719cd6f82c5047c7690fb1cd2df2543d035ac4ea99e974b8d172"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"78799e4771017d4f46aa3c240054e2d61f54cea07ec44cb18ae712761e0aaa1e"')]),a._v(",\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(".\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getbalance\n"),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("50.00000000")]),a._v("\n")])])]),e("p",[a._v("Now the core wallet has generated new blocks and is funded with test bitcoin.")])])]),a._v(" "),e("h3",{attrs:{id:"bdk-wallet-generation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bdk-wallet-generation"}},[a._v("#")]),a._v(" BDK Wallet Generation")]),a._v(" "),e("p",[a._v("BDK is a descriptor based wallet library. So in order to use it we will need some descriptors to work with.")]),a._v(" "),e("p",[a._v("BDK wallet will ask for two descriptors as input, corresponding to "),e("code",[a._v("receive")]),a._v(" and "),e("code",[a._v("change")]),a._v(" addresses. Its recommended to have these two descriptors separate as BDK will handle them separately and ensure "),e("code",[a._v("change")]),a._v(" addresses are never used for receiving funds.")]),a._v(" "),e("p",[a._v("Or developers can decide to use a single descriptor too, in that case BDK will use that descriptor for deriving both "),e("code",[a._v("receive")]),a._v(" and "),e("code",[a._v("change")]),a._v(" addresses.")]),a._v(" "),e("p",[a._v("We will use "),e("code",[a._v("bdk-cli")]),a._v(" itself to generate such descriptors.")]),a._v(" "),e("ul",[e("li",[e("h4",{attrs:{id:"generate-a-privatekey"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#generate-a-privatekey"}},[a._v("#")]),a._v(" Generate a privatekey")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BDK_xprv")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key generate "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n$ "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_xprv")]),a._v("\ntprv8ZgxMBicQKsPefY7tdq7EKny81n9tfSvUYfSHAZByXdjPAZVysvaB6sFd2YavqfqMBgbHaXUG5oWM6sYvdJn6vnUizzQKTYAJ36bQsfPv4N\n")])])]),e("p",[e("code",[a._v("bdk-cli key generate")]),a._v(" will generate a fresh master key with "),e("code",[a._v("mnemonic")]),a._v(" and "),e("code",[a._v("xprv")]),a._v(". We have extracted the value of extended private key and stored it in "),e("code",[a._v("BDK_xprv")]),a._v(" variable.")]),a._v(" "),e("p",[a._v("The returned "),e("code",[a._v("mnemonic")]),a._v(" can be used to restore back the wallet if wallet data directory is lost.")])]),a._v(" "),e("li",[e("h4",{attrs:{id:"generate-descriptors"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#generate-descriptors"}},[a._v("#")]),a._v(" Generate Descriptors")]),a._v(" "),e("p",[e("code",[a._v("bdk-cli key derive")]),a._v(" can derive an "),e("code",[a._v("xpub")]),a._v("s given a "),e("code",[a._v("master key")]),a._v(" and "),e("code",[a._v("derivation_path")]),a._v(".")]),a._v(" "),e("p",[a._v("We will use the following paths for our "),e("code",[a._v("receive")]),a._v(" and "),e("code",[a._v("change")]),a._v(" descriptors")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("receive")]),a._v(" path: "),e("code",[a._v("m/84h/1h/0h/0")])]),a._v(" "),e("li",[e("code",[a._v("change")]),a._v(" path: "),e("code",[a._v("m/84h/1h/0h/1")]),a._v(",")])]),a._v(" "),e("p",[a._v("We can then simply wrap them in a "),e("code",[a._v('"wpkh()"')]),a._v(" to create our descriptors string and store them.")]),a._v(" "),e("p",[a._v("When asked for a new address, BDK will derive one from the "),e("code",[a._v("receive")]),a._v(" descriptor.")]),a._v(" "),e("p",[a._v("And while constructing transaction, BDK will use the "),e("code",[a._v("change")]),a._v(" descriptor to derive change address.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BDK_recv_desc")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wpkh('),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" m/84h/1h/0h/0 "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $BDK_xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v(')"')]),a._v("\n$ "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v("\nwpkh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("ff09c7c9/84"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'/1'")]),a._v("/0'/0"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("tprv8hkdEGgwLLnqsdfkJFidpTj5d6z5qFdP6Qwzsviea3HrS9C2mXXaDivPKCCgcaWvnGNX9eciLUQs91PWYXJqrChfnAagViCgG6L5phaNyWr/*"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n")])])]),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BDK_chng_desc")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"wpkh('),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli key derive "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--path")]),a._v(" m/84h/1h/0h/1 "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--xprv")]),a._v(" $BDK_xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.xprv'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v(')"')]),a._v("\n$ "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v("\nwpkh"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("ff09c7c9/84"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'/1'")]),a._v("/0'/1"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("tprv8hkdEGgwLLnqtbYkGG7fSy7v43RF2SQGGjNuZtmBzEHh7H8xgpXBETQAbVPqi8rkvLNFKLYY4rDzXA4fn5Ha1yuazZqhQPe3uNKmFS7648s/*"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n")])])]),e("p",[a._v("Note: "),e("code",[a._v("BDK_xprv")]),a._v(" has been used as the "),e("code",[a._v("master key")]),a._v(", this will allow BDK to have signing capabilities.\nWe could have used an "),e("code",[a._v("xpub")]),a._v(" master key here instead, that would create an "),e("code",[a._v("watch-only")]),a._v(" wallet.")])]),a._v(" "),e("li",[e("h4",{attrs:{id:"create-and-sync-a-wallet"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#create-and-sync-a-wallet"}},[a._v("#")]),a._v(" Create and Sync a wallet")]),a._v(" "),e("p",[a._v("We will now instruct BDK to create a new wallet with following instructions")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("ul",[e("li",[a._v("name ("),e("code",[a._v("--wallet")]),a._v(") "),e("code",[a._v("bdk-test")]),a._v(",")]),a._v(" "),e("li",[e("code",[a._v("receive")]),a._v(" descriptor ("),e("code",[a._v("-d")]),a._v(") as "),e("code",[a._v("$BDK_recv_desc")]),a._v(" and change descriptor ("),e("code",[a._v("-c")]),a._v(") as "),e("code",[a._v("$BDK_chng_desc")]),a._v(",")]),a._v(" "),e("li",[a._v("connected to a full node ("),e("code",[a._v("--node")]),a._v(") listening at "),e("code",[a._v("127.0.0.1:18444")]),a._v(",")]),a._v(" "),e("li",[a._v("and finally create and sync the wallet with the "),e("code",[a._v("sync")]),a._v(" command.")])]),a._v(" "),e("p",[a._v("If you are using a "),e("code",[a._v("regtest")]),a._v(" node, also add "),e("code",[a._v("--network regtest")]),a._v(", the default is "),e("code",[a._v("testnet")]),a._v(".")]),a._v(" "),e("p",[e("code",[a._v("bdk-cli")]),a._v(" makes multiple parallel connections that can be configured with the "),e("code",[a._v("--conn-count")]),a._v(" parameter (default is 4). This makes syncing parallel and fast. Use "),e("code",[a._v("bdk-cli --help")]),a._v(" to see all other options.")]),a._v(" "),e("p",[a._v("Getting an empty return means wallet creation succeeded.")]),a._v(" "),e("p",[a._v("BDK has created a wallet named "),e("code",[a._v("bdk-test")]),a._v(" in its data directory. Which is by default stored at "),e("code",[a._v("~/.bdk-bitcoin/compact_filters")]),a._v(" folder.")]),a._v(" "),e("p",[a._v("Looking into that folder different files and directories maintained by BDK can be seen.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("ls")]),a._v(" .bdk-bitcoin/compact_filters/\n000004.log CURRENT LOCK MANIFEST-000003 OPTIONS-000010\nbdk-test IDENTITY LOG OPTIONS-000008\n")])])])])]),a._v(" "),e("h3",{attrs:{id:"recieve-coins"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#recieve-coins"}},[a._v("#")]),a._v(" Recieve Coins")]),a._v(" "),e("p",[a._v("We will use the "),e("code",[a._v("core")]),a._v(" wallet to send 5 BTC to our"),e("code",[a._v("bdk-test")]),a._v(" wallet.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Fetch a new address using "),e("code",[a._v("bdk-cli")])]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" get_new_address\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Transfer funds to the previous address and generate a block, using "),e("code",[a._v("bitcoin-cli")])]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" sendtoaddress bcrt1qx2479wywulf50pqx5uy64zhxq9f3tuvlh8u0s9 "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("5")]),a._v("\n\n\n$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),a._v(" bcrt1qw3ht9xtc9pgyvmqay0ap9fw8mxd27az8el0uz3\n")])])]),e("p",[e("code",[a._v("core")]),a._v(" has sent 5 BTC to our "),e("code",[a._v("bdk-test")]),a._v(" wallet. Which is confirmed in a new block.")]),a._v(" "),e("p",[e("code",[a._v("bdk-test")]),a._v(" can see that now by syncing again.")]),a._v(" "),e("p",[a._v("(Note: BDK required explicit "),e("code",[a._v("sync()")]),a._v(" calls to give wallet developers flexibility on when to sync).")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" get_balance\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("500000000")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("We can see "),e("code",[a._v("500000000")]),a._v(" sats balance in our "),e("code",[a._v("bdk-test")]),a._v(" wallet.")]),a._v(" "),e("p",[a._v("BDK has fetched blockchain details concerning its wallet descriptors, from the core node, using compact filters.")])])]),a._v(" "),e("h3",{attrs:{id:"creating-a-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-transaction"}},[a._v("#")]),a._v(" Creating a transaction.")]),a._v(" "),e("p",[a._v("Now we want to create a transaction sending coins from "),e("code",[a._v("bdk-test")]),a._v(" wallet to the "),e("code",[a._v("core")]),a._v(" wallet.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("fetch a new "),e("code",[a._v("core")]),a._v(" address")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("core_addrs")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" getnewaddress "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("tr")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'\\r'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Create a raw transaction using "),e("code",[a._v("bdk-cli")]),a._v(" to the above address. This will generate a "),e("code",[a._v("psbt")]),a._v(" which we will sign.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("psbt")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BDK_recv_desc "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" $BDK_chng_desc create_tx "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--to")]),a._v(" $core_addrs:200000000 "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.psbt'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])]),e("p",[a._v("(Recommended to check all the other information returned by "),e("code",[a._v("bdk-cli create_tx")]),a._v(")")])])]),a._v(" "),e("h3",{attrs:{id:"sign-and-broadcast-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#sign-and-broadcast-the-transaction"}},[a._v("#")]),a._v(" Sign and Broadcast the transaction")]),a._v(" "),e("p",[a._v("Asking BDK to sign a transaction is as straight forward as it can get. BDK already holds the "),e("code",[a._v("xprv")]),a._v(" deatils to sign a transaction. It returns a finalised "),e("code",[a._v("signed_psbt")]),a._v(" which we will next broadcast to the network.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Sign the transaction")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("signed_psbt")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),a._v("bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" $BDK_recv_desc "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" $BDK_chng_desc sign "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" $psbt "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("|")]),a._v(" jq "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'.psbt'")]),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Broadcast the transaction")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" broadcast "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--psbt")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$signed_psbt")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("This makes BDK broadcast the transaction via the connected core node, and it returns the corresponding Txid.")])])]),a._v(" "),e("h3",{attrs:{id:"confirming-the-transaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#confirming-the-transaction"}},[a._v("#")]),a._v(" Confirming the Transaction")]),a._v(" "),e("p",[a._v("The transaction has been received by the "),e("code",[a._v("core")]),a._v(" node and waiting in its mempool for inclusion in block.\nWe can see the transaction via its "),e("code",[a._v("txid")]),a._v(" received in previous step.")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("Check transaction in mempool")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" gettransaction c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e2248e52e0852252\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"amount"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("2.00000000")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"confirmations"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"trusted"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" false,\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"txid"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"c343f5b25372e285308eba912d1fe8fade9f64afde6d95306e248e52e0852252"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"walletconflicts"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"time"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1621697202")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"timereceived"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1621697202")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"bip125-replaceable"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"no"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"details"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"address"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"bcrt1q3h4hs6mve5dcl7da3d4acmlp20hh8c3t4mldwe"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"category"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"receive"')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"amount"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("2.00000000")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"label"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('""')]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"vout"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v(",\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"hex"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"01000000000101d84e8cb7477f9fe6f265b56d5416ff47da9a70be18f65ec50731b8257c67f2bd0100000000ffffffff0273a2e11100000000160014874270187001febc4cebd8cb083cf2c783e8f1ac00c2eb0b000000001600148deb786b6ccd1b8ff9bd8b6bdc6fe153ef73e22b0247304402201037d9ef5b80392296311c8899b1f12a0987778d694a442a88bafa6fbd7a7c9a022011293176255897444d9c71b0b9cd13b2aedb749b142577566c90a63d61025e2c01210202427d16b29c1c8546255363a74326ee9ab3196770bb3fccc7b679d52f9c1ccf00000000"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("This means, core has recieved the transaction in its mempool and waiting for confirmation.")])]),a._v(" "),e("li",[e("p",[a._v("Generate 1 block to confirm the transaction")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exec")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" bdk-box /root/bitcoin-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-regtest")]),a._v(" generatetoaddress "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),a._v(" bcrt1qatd7yq0jukwusuaufltlejmeydpvnpv43r5gc2\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"55436ff0169bbb3e70ab10cb7cdd45ab86204d5d7864a109142d91120d023197"')]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),a._v("\n")])])])]),a._v(" "),e("li",[e("p",[a._v("Sync the "),e("code",[a._v("bdk-test")]),a._v(" wallet and ask for available balance.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v(" $ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("sync")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n\n $ bdk-cli "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--network")]),a._v(" regtest wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--node")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"127.0.0.1:18444"')]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--wallet")]),a._v(" bdk-test "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_recv_desc")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-c")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BDK_chng_desc")]),a._v(" get_balance\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n \t"),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"satoshi"')]),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("299999859")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("p",[a._v("If you see the balance updated, voila!")]),a._v(" "),e("p",[a._v("What happened here is:")]),a._v(" "),e("ul",[e("li",[a._v("core created a new block containing the transaction.")]),a._v(" "),e("li",[e("code",[a._v("bdk-cli")]),a._v(" fetched the corresponding filter data.")]),a._v(" "),e("li",[a._v("It noticed it got a concerning transaction.")]),a._v(" "),e("li",[a._v("It asked for the details of that transaction from the core node.")]),a._v(" "),e("li",[a._v("It updated its wallet details with this new information.")]),a._v(" "),e("li",[a._v("The update is reflected in the wallet balance.")])])])]),a._v(" "),e("h3",{attrs:{id:"shutdown-docker"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#shutdown-docker"}},[a._v("#")]),a._v(" Shutdown Docker")]),a._v(" "),e("p",[a._v("You may now shutdown the regtest docker container.")]),a._v(" "),e("p",[a._v("Note: This will also clean up any data in the bitcoin core, including the wallet.")]),a._v(" "),e("div",{staticClass:"language-shell extra-class"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("$ "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("kill")]),a._v(" bdk-box\n")])])]),e("h2",{attrs:{id:"end-words"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#end-words"}},[a._v("#")]),a._v(" End Words")]),a._v(" "),e("p",[a._v("In this tutorial we went through the process of receiving, creating, signing and broadcasting transaction using the BDK wallet with "),e("code",[a._v("compact_filters")]),a._v(" feature. This demonstrates how BDK capabilities can be used to create SPV light wallets with integrated "),e("code",[a._v("BIP157")]),a._v(" type "),e("code",[a._v("compact_filters")]),a._v(" node.")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/45.41387e37.js b/assets/js/45.dbedb51c.js similarity index 99% rename from assets/js/45.41387e37.js rename to assets/js/45.dbedb51c.js index 04e953750d..859bc3cdc3 100644 --- a/assets/js/45.41387e37.js +++ b/assets/js/45.dbedb51c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{394:function(e,t,a){"use strict";a.r(t);var s=a(7),r=Object(s.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("In this post, we will use the "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" tool to create a multi-owned descriptor-based paper wallet. We will use "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" via the "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" tool to test our descriptor and to be able to sweep the funds from our paper wallet to a new address.")]),e._v(" "),t("h2",{attrs:{id:"about-paper-wallets"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#about-paper-wallets"}},[e._v("#")]),e._v(" About paper wallets")]),e._v(" "),t("p",[e._v("Paper wallets have a lot of drawbacks, as explained in the "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/Paper_wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("paper wallet Wiki article"),t("OutboundLink")],1),e._v(", as always, do your own research before deciding to use it with mainnet bitcoins. In this post we will\nonly be using testnet coins.")]),e._v(" "),t("h2",{attrs:{id:"descriptors"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[e._v("#")]),e._v(" Descriptors")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet/tree/339fa4418d94f6fdd96f3d0301cab8a0bc09e8bd",target:"_blank",rel:"noopener noreferrer"}},[e._v("previous version"),t("OutboundLink")],1),e._v(" of the "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" followed the original paper wallet design: WIF"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(" as secret part with the option to generate a different kind of addresses (legacy, nested segwit, and segwit).")]),e._v(" "),t("p",[e._v("There were plans to "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet/issues/5",target:"_blank",rel:"noopener noreferrer"}},[e._v("support mnemonic"),t("OutboundLink")],1),e._v(" instead of WIF keys because it may"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn2",id:"fnref2"}},[e._v("[2]")])]),e._v(" save the sweep transaction"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn3",id:"fnref3"}},[e._v("[3]")])]),e._v(" and there are more wallets capable of importing a mnemonic instead of a WIF.")]),e._v(" "),t("p",[e._v("However, choosing a single address type or having wallet support for a specific format is the kind of problem "),t("a",{attrs:{href:"/descriptors"}},[e._v("descriptors")]),e._v(" solve perfectly, so the latest "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" version now accepts a descriptor and the network as parameters.")]),e._v(" "),t("h2",{attrs:{id:"example-use-case"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-use-case"}},[e._v("#")]),e._v(" Example use case")]),e._v(" "),t("p",[e._v("So let's say your grandma wants to buy bitcoin and asked for your help.")]),e._v(" "),t("p",[e._v("You are a little afraid she may lose the private key. At the same time, you don't want to duplicate the keys and give those to her daughters Alice and Barbara, because both of them could spend and accuse the other of having done so.")]),e._v(" "),t("p",[e._v("Even though we trust everyone in the family it is better to play it safe and divide the responsibility of protecting Grandma's bitcoin.")]),e._v(" "),t("p",[e._v("This is a perfect case for a 2 of 3 multi-signature paper wallet. This way also protects the participants from having their copy of the wallet stolen. To compromise Grandma's wallet a thief would need to find and steal at least two of them.")]),e._v(" "),t("p",[e._v("Note that you as the wallet creator are still the single point of trust because you are going to generate the keys for everyone. Setups combining self generated keys from the participants is possible future work.")]),e._v(" "),t("h2",{attrs:{id:"creating-the-paper-wallet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#creating-the-paper-wallet"}},[e._v("#")]),e._v(" Creating the paper wallet")]),e._v(" "),t("p",[e._v("For this example the spending descriptor would be:")]),e._v(" "),t("p",[t("code",[e._v("wsh(multi(2,Grandma,Alice,Barbara))")])]),e._v(" "),t("p",[e._v("You need "),t("a",{attrs:{href:"https://www.rust-lang.org/tools/install",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust"),t("OutboundLink")],1),e._v(" installed to use "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(". The -n option below explicitly selects\ngenerating "),t("code",[e._v("testnet")]),e._v(" keys. Use "),t("code",[e._v("rusty-paper-wallet --help")]),e._v(" to see usage instructions and other\noptions.")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("$ "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("cargo")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" rusty-paper-wallet\n$ rusty-paper-wallet "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"wsh(multi(2,Grandma,Alice,Barbara))"')]),e._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-n")]),e._v(" testnet\ndata:text/html"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("base64,PCFET0N"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("..")]),e._v(".\n")])])]),t("p",[e._v("The "),t("a",{attrs:{href:"/descriptor-based-paper-wallets/data-url.txt"}},[e._v("output")]),e._v(" of the command is very long and has been shortened. The string is a "),t("a",{attrs:{href:"https://en.wikipedia.org/wiki/Data_URI_scheme",target:"_blank",rel:"noopener noreferrer"}},[e._v("data URI scheme"),t("OutboundLink")],1),e._v(" paste-able in the address bar of a browser. By using a data URI no files are written on the hard disk, leaving less trace of secret material on the computer.\nIt's also a good idea to use incognito mode in the browser to prevent it from saving the page in the history.")]),e._v(" "),t("p",[e._v("The following is the result:")]),e._v(" "),t("iframe",{staticClass:"example",attrs:{src:"/descriptor-based-paper-wallets/Bitcoin_Paper_Wallet.html"}}),e._v(" "),t("p",[e._v("Under the hood, the command created a key pair randomly for every alias present in the descriptor, then replaced the aliases with the created keys and generated the corresponding address. This address is the same for every paper wallet and it is shown in the upper part of the paper wallet (the public part) along with the alias, linking the paper wallet to the owner.")]),e._v(" "),t("p",[e._v("The lower part is the secret part, the written part is the descriptor with the aliases, followed by a legend linking the aliases with the keys. In the legend, all the keys are public but the one of the owner which is a private WIF. The secret QR code instead contains the descriptor already with the keys.")]),e._v(" "),t("p",[e._v("The paper wallet must then be printed, and it is better to use a printer without wifi and also to be aware that some sensitive data may remain in the printer's cache.")]),e._v(" "),t("p",[e._v("Then the paper wallet must be cut along the dotted lines, the secret part should be folded twice over the black zone"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn4",id:"fnref4"}},[e._v("[4]")])]),e._v(". The black zone helps to avoid showing the secret parts in the presence of back-light. Once the folding is done the paper wallet should be plasticized to prevent being damaged by water.")]),e._v(" "),t("h2",{attrs:{id:"bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk"}},[e._v("#")]),e._v(" BDK")]),e._v(" "),t("p",[e._v("Any descriptor based wallet can be used to check the balance of and sweep the funds from\nGrandma's paper wallet. For this post we'll demonstrate using the "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" tool to do these steps.\nAnother area where "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" could be used with "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" is to compile a more\ncomplicated miniscript spending policy into a descriptor, as we have done in the "),t("RouterLink",{attrs:{to:"/blog/2021/02/spending-policy-demo/#step-4-create-wallet-descriptors-for-each-participant"}},[e._v("spending policy demo")]),e._v(" post.")],1),e._v(" "),t("h2",{attrs:{id:"funding-tx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#funding-tx"}},[e._v("#")]),e._v(" Funding tx")]),e._v(" "),t("p",[e._v("Since Grandma's wallet was created as a "),t("code",[e._v("wsh")]),e._v(" descriptor, bitcoin can be sent to it from any\nsegwit capable wallet, we'll use a public "),t("a",{attrs:{href:"https://bitcoinfaucet.uo1.net/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin testnet faucet"),t("OutboundLink")],1),e._v(". Once the funds are sent the\ndeposit address "),t("code",[e._v("tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw")]),e._v(" we can also use this\naddress and a testnet explorer to "),t("a",{attrs:{href:"https://mempool.space/testnet/address/tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw",target:"_blank",rel:"noopener noreferrer"}},[e._v("confirm the funds were received"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h2",{attrs:{id:"sweep-tx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#sweep-tx"}},[e._v("#")]),e._v(" Sweep tx")]),e._v(" "),t("p",[e._v("Now that Grandma's paper wallet is funded it's time to demonstrate how to use "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" to sweep these\nfunds to a new address. Let's assume Grandma lost her original paper wallet and has asked\nher daughters to sweep them to a new single signature wallet so she can spend them.")]),e._v(" "),t("h3",{attrs:{id:"step-1-alice-creates-and-signs-a-psbt"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#step-1-alice-creates-and-signs-a-psbt"}},[e._v("#")]),e._v(" Step 1: Alice creates and signs a PSBT")]),e._v(" "),t("p",[e._v("Alice uses the private text or QR code from her paper wallet to find her private key and the\npublic keys for Grandma and Barbara. With this info she creates a PSBT to sweep Grandma's funds\nto a new address (in this example we'll send them back to our "),t("a",{attrs:{href:"https://bitcoinfaucet.uo1.net/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin testnet faucet"),t("OutboundLink")],1),e._v("). Notice how Alice\nincludes her wallet's descriptor checksum '#em3q73l5', this "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums",target:"_blank",rel:"noopener noreferrer"}},[e._v("guarantees"),t("OutboundLink")],1),e._v(" she has entered her descriptor correctly.")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("SWEEP_TO_ADDR")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2\n\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_WIF")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("cSSKRHDmQEEutp5LD14tAcixu2ehSNPDTqNek1zMa9Pet98qxHq3\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("BARBARA_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("02a3f3f2658b9812ddeabfbde2fde03f8a65369e4ed621f29fa8ba0cc519b789fb\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("GRANDMA_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_DESCRIPTOR")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"wsh(multi(2,'),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$GRANDMA_PUBKEY")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_WIF")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_PUBKEY")]),e._v('))#em3q73l5"')]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# confirm descriptor creates the expected deposit address")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_DESCRIPTOR")]),e._v(" get_new_address\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"address"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# sync the wallet and show the balance")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_DESCRIPTOR")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("sync")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_DESCRIPTOR")]),e._v(" get_balance\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"satoshi"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("10000")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# create and sign PSBT")]),e._v("\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("UNSIGNED_PSBT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$(")]),e._v("bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" $ALICE_DESCRIPTOR create_tx "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--send_all")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--to")]),e._v(" $SWEEP_TO_ADDR:0 "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v(" jq "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-r")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('".psbt"')]),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v(")")])]),e._v("\n\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_SIGNED_PSBT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$(")]),e._v("bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" $ALICE_DESCRIPTOR sign "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--psbt")]),e._v(" $UNSIGNED_PSBT "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v(" jq "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-r")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('".psbt"')]),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v(")")])]),e._v("\n")])])]),t("h3",{attrs:{id:"step-2-barbara-signs-alices-signed-psbt-and-broadcasts-the-tx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#step-2-barbara-signs-alices-signed-psbt-and-broadcasts-the-tx"}},[e._v("#")]),e._v(" Step 2: Barbara signs Alice's signed PSBT and broadcasts the tx")]),e._v(" "),t("p",[e._v("Now it's Barbara's turn to use the private text or QR code from her paper wallet to get her private\nkey and the public keys for Grandma and Alice. With this info plus Alice's signed PSBT she can\ncreate a fully signed PSBT to broadcast and complete the sweep of Grandma's funds.")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("02e486e32f0f87136fa042cb53219ace8537ea1d036deb2f4293570b94325d11cb\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("BARBARA_WIF")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("cSfMLzSZ9NjWUTqL3sFpgWJssnu2qgmE2cm5N1jPDRRJuDcrsPEB\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("GRANDMA_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("BARBARA_DESCRIPTOR")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"wsh(multi(2,'),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$GRANDMA_PUBKEY")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_PUBKEY")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_WIF")]),e._v('))#nxfa5n0z"')]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# confirm descriptor creates the expected deposit address")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" get_new_address\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"address"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# sync the wallet and show the balance")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("sync")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" get_balance\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"satoshi"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("10000")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("FINAL_PSBT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$(")]),e._v("bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" $BARBARA_DESCRIPTOR sign "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--psbt")]),e._v(" $ALICE_SIGNED_PSBT "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v(" jq "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-r")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('".psbt"')]),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v(")")])]),e._v("\n\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" broadcast "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--psbt")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$FINAL_PSBT")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"txid"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),t("p",[e._v("And finally we verify that Alice and Barbara successfully created and broadcast Grandma's "),t("a",{attrs:{href:"https://mempool.space/testnet/tx/9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59",target:"_blank",rel:"noopener noreferrer"}},[e._v("sweep tx"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("In this post we showed how to create a multi-sig descriptor based paper wallet using\n"),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" and then sweep the funds from our example paper wallet to a new address. If you\nfound this post interesting please comment below. Or give it a try yourself and if you run into any\nproblems or would like to suggest improvements leave an issue in the "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" or\n"),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" github repos. Thanks!")]),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("Wallet Input Format, a string encoding a ECDSA private key https://en.bitcoin.it/wiki/Wallet_import_format "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn2"}},[t("p",[e._v("Unless the user import the WIF directly into bitcoin core "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref2"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn3"}},[t("p",[e._v("Some wallets refers to sweep as the action to create a transaction taking all the funds from the paper wallet and sending those to the wallet itself. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref3"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn4"}},[t("p",[e._v("Ideally, the black zone should be twice as long as the secret part to cover it back and front, long descriptor may leave a shorter black zone, ensure to have you printer set with vertical layout for best results. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref4"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{392:function(e,t,a){"use strict";a.r(t);var s=a(7),r=Object(s.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("In this post, we will use the "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" tool to create a multi-owned descriptor-based paper wallet. We will use "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" via the "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" tool to test our descriptor and to be able to sweep the funds from our paper wallet to a new address.")]),e._v(" "),t("h2",{attrs:{id:"about-paper-wallets"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#about-paper-wallets"}},[e._v("#")]),e._v(" About paper wallets")]),e._v(" "),t("p",[e._v("Paper wallets have a lot of drawbacks, as explained in the "),t("a",{attrs:{href:"https://en.bitcoin.it/wiki/Paper_wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("paper wallet Wiki article"),t("OutboundLink")],1),e._v(", as always, do your own research before deciding to use it with mainnet bitcoins. In this post we will\nonly be using testnet coins.")]),e._v(" "),t("h2",{attrs:{id:"descriptors"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[e._v("#")]),e._v(" Descriptors")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet/tree/339fa4418d94f6fdd96f3d0301cab8a0bc09e8bd",target:"_blank",rel:"noopener noreferrer"}},[e._v("previous version"),t("OutboundLink")],1),e._v(" of the "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" followed the original paper wallet design: WIF"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(" as secret part with the option to generate a different kind of addresses (legacy, nested segwit, and segwit).")]),e._v(" "),t("p",[e._v("There were plans to "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet/issues/5",target:"_blank",rel:"noopener noreferrer"}},[e._v("support mnemonic"),t("OutboundLink")],1),e._v(" instead of WIF keys because it may"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn2",id:"fnref2"}},[e._v("[2]")])]),e._v(" save the sweep transaction"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn3",id:"fnref3"}},[e._v("[3]")])]),e._v(" and there are more wallets capable of importing a mnemonic instead of a WIF.")]),e._v(" "),t("p",[e._v("However, choosing a single address type or having wallet support for a specific format is the kind of problem "),t("a",{attrs:{href:"/descriptors"}},[e._v("descriptors")]),e._v(" solve perfectly, so the latest "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" version now accepts a descriptor and the network as parameters.")]),e._v(" "),t("h2",{attrs:{id:"example-use-case"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-use-case"}},[e._v("#")]),e._v(" Example use case")]),e._v(" "),t("p",[e._v("So let's say your grandma wants to buy bitcoin and asked for your help.")]),e._v(" "),t("p",[e._v("You are a little afraid she may lose the private key. At the same time, you don't want to duplicate the keys and give those to her daughters Alice and Barbara, because both of them could spend and accuse the other of having done so.")]),e._v(" "),t("p",[e._v("Even though we trust everyone in the family it is better to play it safe and divide the responsibility of protecting Grandma's bitcoin.")]),e._v(" "),t("p",[e._v("This is a perfect case for a 2 of 3 multi-signature paper wallet. This way also protects the participants from having their copy of the wallet stolen. To compromise Grandma's wallet a thief would need to find and steal at least two of them.")]),e._v(" "),t("p",[e._v("Note that you as the wallet creator are still the single point of trust because you are going to generate the keys for everyone. Setups combining self generated keys from the participants is possible future work.")]),e._v(" "),t("h2",{attrs:{id:"creating-the-paper-wallet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#creating-the-paper-wallet"}},[e._v("#")]),e._v(" Creating the paper wallet")]),e._v(" "),t("p",[e._v("For this example the spending descriptor would be:")]),e._v(" "),t("p",[t("code",[e._v("wsh(multi(2,Grandma,Alice,Barbara))")])]),e._v(" "),t("p",[e._v("You need "),t("a",{attrs:{href:"https://www.rust-lang.org/tools/install",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust"),t("OutboundLink")],1),e._v(" installed to use "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(". The -n option below explicitly selects\ngenerating "),t("code",[e._v("testnet")]),e._v(" keys. Use "),t("code",[e._v("rusty-paper-wallet --help")]),e._v(" to see usage instructions and other\noptions.")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("$ "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("cargo")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" rusty-paper-wallet\n$ rusty-paper-wallet "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"wsh(multi(2,Grandma,Alice,Barbara))"')]),e._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-n")]),e._v(" testnet\ndata:text/html"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("base64,PCFET0N"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("..")]),e._v(".\n")])])]),t("p",[e._v("The "),t("a",{attrs:{href:"/descriptor-based-paper-wallets/data-url.txt"}},[e._v("output")]),e._v(" of the command is very long and has been shortened. The string is a "),t("a",{attrs:{href:"https://en.wikipedia.org/wiki/Data_URI_scheme",target:"_blank",rel:"noopener noreferrer"}},[e._v("data URI scheme"),t("OutboundLink")],1),e._v(" paste-able in the address bar of a browser. By using a data URI no files are written on the hard disk, leaving less trace of secret material on the computer.\nIt's also a good idea to use incognito mode in the browser to prevent it from saving the page in the history.")]),e._v(" "),t("p",[e._v("The following is the result:")]),e._v(" "),t("iframe",{staticClass:"example",attrs:{src:"/descriptor-based-paper-wallets/Bitcoin_Paper_Wallet.html"}}),e._v(" "),t("p",[e._v("Under the hood, the command created a key pair randomly for every alias present in the descriptor, then replaced the aliases with the created keys and generated the corresponding address. This address is the same for every paper wallet and it is shown in the upper part of the paper wallet (the public part) along with the alias, linking the paper wallet to the owner.")]),e._v(" "),t("p",[e._v("The lower part is the secret part, the written part is the descriptor with the aliases, followed by a legend linking the aliases with the keys. In the legend, all the keys are public but the one of the owner which is a private WIF. The secret QR code instead contains the descriptor already with the keys.")]),e._v(" "),t("p",[e._v("The paper wallet must then be printed, and it is better to use a printer without wifi and also to be aware that some sensitive data may remain in the printer's cache.")]),e._v(" "),t("p",[e._v("Then the paper wallet must be cut along the dotted lines, the secret part should be folded twice over the black zone"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn4",id:"fnref4"}},[e._v("[4]")])]),e._v(". The black zone helps to avoid showing the secret parts in the presence of back-light. Once the folding is done the paper wallet should be plasticized to prevent being damaged by water.")]),e._v(" "),t("h2",{attrs:{id:"bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk"}},[e._v("#")]),e._v(" BDK")]),e._v(" "),t("p",[e._v("Any descriptor based wallet can be used to check the balance of and sweep the funds from\nGrandma's paper wallet. For this post we'll demonstrate using the "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" tool to do these steps.\nAnother area where "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" could be used with "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" is to compile a more\ncomplicated miniscript spending policy into a descriptor, as we have done in the "),t("RouterLink",{attrs:{to:"/blog/2021/02/spending-policy-demo/#step-4-create-wallet-descriptors-for-each-participant"}},[e._v("spending policy demo")]),e._v(" post.")],1),e._v(" "),t("h2",{attrs:{id:"funding-tx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#funding-tx"}},[e._v("#")]),e._v(" Funding tx")]),e._v(" "),t("p",[e._v("Since Grandma's wallet was created as a "),t("code",[e._v("wsh")]),e._v(" descriptor, bitcoin can be sent to it from any\nsegwit capable wallet, we'll use a public "),t("a",{attrs:{href:"https://bitcoinfaucet.uo1.net/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin testnet faucet"),t("OutboundLink")],1),e._v(". Once the funds are sent the\ndeposit address "),t("code",[e._v("tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw")]),e._v(" we can also use this\naddress and a testnet explorer to "),t("a",{attrs:{href:"https://mempool.space/testnet/address/tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw",target:"_blank",rel:"noopener noreferrer"}},[e._v("confirm the funds were received"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h2",{attrs:{id:"sweep-tx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#sweep-tx"}},[e._v("#")]),e._v(" Sweep tx")]),e._v(" "),t("p",[e._v("Now that Grandma's paper wallet is funded it's time to demonstrate how to use "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" to sweep these\nfunds to a new address. Let's assume Grandma lost her original paper wallet and has asked\nher daughters to sweep them to a new single signature wallet so she can spend them.")]),e._v(" "),t("h3",{attrs:{id:"step-1-alice-creates-and-signs-a-psbt"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#step-1-alice-creates-and-signs-a-psbt"}},[e._v("#")]),e._v(" Step 1: Alice creates and signs a PSBT")]),e._v(" "),t("p",[e._v("Alice uses the private text or QR code from her paper wallet to find her private key and the\npublic keys for Grandma and Barbara. With this info she creates a PSBT to sweep Grandma's funds\nto a new address (in this example we'll send them back to our "),t("a",{attrs:{href:"https://bitcoinfaucet.uo1.net/",target:"_blank",rel:"noopener noreferrer"}},[e._v("bitcoin testnet faucet"),t("OutboundLink")],1),e._v("). Notice how Alice\nincludes her wallet's descriptor checksum '#em3q73l5', this "),t("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums",target:"_blank",rel:"noopener noreferrer"}},[e._v("guarantees"),t("OutboundLink")],1),e._v(" she has entered her descriptor correctly.")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("SWEEP_TO_ADDR")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("tb1qm5tfegjevj27yvvna9elym9lnzcf0zraxgl8z2\n\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_WIF")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("cSSKRHDmQEEutp5LD14tAcixu2ehSNPDTqNek1zMa9Pet98qxHq3\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("BARBARA_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("02a3f3f2658b9812ddeabfbde2fde03f8a65369e4ed621f29fa8ba0cc519b789fb\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("GRANDMA_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_DESCRIPTOR")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"wsh(multi(2,'),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$GRANDMA_PUBKEY")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_WIF")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_PUBKEY")]),e._v('))#em3q73l5"')]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# confirm descriptor creates the expected deposit address")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_DESCRIPTOR")]),e._v(" get_new_address\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"address"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# sync the wallet and show the balance")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_DESCRIPTOR")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("sync")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_DESCRIPTOR")]),e._v(" get_balance\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"satoshi"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("10000")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# create and sign PSBT")]),e._v("\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("UNSIGNED_PSBT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$(")]),e._v("bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" $ALICE_DESCRIPTOR create_tx "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--send_all")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--to")]),e._v(" $SWEEP_TO_ADDR:0 "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v(" jq "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-r")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('".psbt"')]),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v(")")])]),e._v("\n\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_SIGNED_PSBT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$(")]),e._v("bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" alice "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" $ALICE_DESCRIPTOR sign "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--psbt")]),e._v(" $UNSIGNED_PSBT "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v(" jq "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-r")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('".psbt"')]),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v(")")])]),e._v("\n")])])]),t("h3",{attrs:{id:"step-2-barbara-signs-alices-signed-psbt-and-broadcasts-the-tx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#step-2-barbara-signs-alices-signed-psbt-and-broadcasts-the-tx"}},[e._v("#")]),e._v(" Step 2: Barbara signs Alice's signed PSBT and broadcasts the tx")]),e._v(" "),t("p",[e._v("Now it's Barbara's turn to use the private text or QR code from her paper wallet to get her private\nkey and the public keys for Grandma and Alice. With this info plus Alice's signed PSBT she can\ncreate a fully signed PSBT to broadcast and complete the sweep of Grandma's funds.")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("ALICE_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("02e486e32f0f87136fa042cb53219ace8537ea1d036deb2f4293570b94325d11cb\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("BARBARA_WIF")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("cSfMLzSZ9NjWUTqL3sFpgWJssnu2qgmE2cm5N1jPDRRJuDcrsPEB\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("GRANDMA_PUBKEY")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("03f1bd2bff8e9c61f58a8d46d18fd8f3149b1f2d76b3c423a7874a5d5811d67cee\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("BARBARA_DESCRIPTOR")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"wsh(multi(2,'),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$GRANDMA_PUBKEY")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$ALICE_PUBKEY")]),e._v(","),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_WIF")]),e._v('))#nxfa5n0z"')]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# confirm descriptor creates the expected deposit address")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" get_new_address\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"address"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"tb1qu6lcua9w2zkarjj5xwxh3l3qtcxh84hsra3jrvpszh69j2e54x7q3thycw"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# sync the wallet and show the balance")]),e._v("\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("sync")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" get_balance\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"satoshi"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("10000")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n\n$ "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[e._v("FINAL_PSBT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$(")]),e._v("bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" $BARBARA_DESCRIPTOR sign "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--psbt")]),e._v(" $ALICE_SIGNED_PSBT "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v(" jq "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-r")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('".psbt"')]),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v(")")])]),e._v("\n\n$ bdk-cli wallet "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-w")]),e._v(" barbara "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-d")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$BARBARA_DESCRIPTOR")]),e._v(" broadcast "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--psbt")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[e._v("$FINAL_PSBT")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"txid"')]),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59"')]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),t("p",[e._v("And finally we verify that Alice and Barbara successfully created and broadcast Grandma's "),t("a",{attrs:{href:"https://mempool.space/testnet/tx/9ecd8e6be92b7edd8bf1799f8f7090e58f813825f826bdb771b4cdb444cdeb59",target:"_blank",rel:"noopener noreferrer"}},[e._v("sweep tx"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("In this post we showed how to create a multi-sig descriptor based paper wallet using\n"),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" and then sweep the funds from our example paper wallet to a new address. If you\nfound this post interesting please comment below. Or give it a try yourself and if you run into any\nproblems or would like to suggest improvements leave an issue in the "),t("a",{attrs:{href:"https://github.com/RCasatta/rusty-paper-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("Rusty Paper Wallet"),t("OutboundLink")],1),e._v(" or\n"),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-cli"),t("OutboundLink")],1),e._v(" github repos. Thanks!")]),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("Wallet Input Format, a string encoding a ECDSA private key https://en.bitcoin.it/wiki/Wallet_import_format "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn2"}},[t("p",[e._v("Unless the user import the WIF directly into bitcoin core "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref2"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn3"}},[t("p",[e._v("Some wallets refers to sweep as the action to create a transaction taking all the funds from the paper wallet and sending those to the wallet itself. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref3"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn4"}},[t("p",[e._v("Ideally, the black zone should be twice as long as the secret part to cover it back and front, long descriptor may leave a shorter black zone, ensure to have you printer set with vertical layout for best results. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref4"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/46.883464d4.js b/assets/js/46.5deb1292.js similarity index 99% rename from assets/js/46.883464d4.js rename to assets/js/46.5deb1292.js index 3340e76c61..3920b4ef57 100644 --- a/assets/js/46.883464d4.js +++ b/assets/js/46.5deb1292.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{393: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([[46],{394: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/48.9a448976.js b/assets/js/48.f74437f6.js similarity index 99% rename from assets/js/48.9a448976.js rename to assets/js/48.f74437f6.js index 57f33f52d7..fc72b1b1ab 100644 --- a/assets/js/48.9a448976.js +++ b/assets/js/48.f74437f6.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{399: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([[48],{398: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/49.17ce6e83.js b/assets/js/49.b70acbda.js similarity index 99% rename from assets/js/49.17ce6e83.js rename to assets/js/49.b70acbda.js index 63014e7a93..aa155b378b 100644 --- a/assets/js/49.17ce6e83.js +++ b/assets/js/49.b70acbda.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{398: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([[49],{399: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/53.fb891878.js b/assets/js/53.08d5fa33.js similarity index 99% rename from assets/js/53.fb891878.js rename to assets/js/53.08d5fa33.js index 04c428e912..a5700973e5 100644 --- a/assets/js/53.fb891878.js +++ b/assets/js/53.08d5fa33.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{404: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([[53],{403: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/54.d9630932.js b/assets/js/54.4ffb88f8.js similarity index 99% rename from assets/js/54.d9630932.js rename to assets/js/54.4ffb88f8.js index 551e0016f2..519a2d09ca 100644 --- a/assets/js/54.d9630932.js +++ b/assets/js/54.4ffb88f8.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{403: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([[54],{404: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/60.08677303.js b/assets/js/60.e9dd6778.js similarity index 98% rename from assets/js/60.08677303.js rename to assets/js/60.e9dd6778.js index 6cfcf5a68d..d7ed268c8c 100644 --- a/assets/js/60.08677303.js +++ b/assets/js/60.e9dd6778.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[60],{410: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([[60],{411: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/61.63feb9f0.js b/assets/js/61.1cf26963.js similarity index 99% rename from assets/js/61.63feb9f0.js rename to assets/js/61.1cf26963.js index ca432a3cca..a1e204a886 100644 --- a/assets/js/61.63feb9f0.js +++ b/assets/js/61.1cf26963.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[61],{414: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([[61],{412: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/62.b483815a.js b/assets/js/62.43618b30.js similarity index 99% rename from assets/js/62.b483815a.js rename to assets/js/62.43618b30.js index 65e6807dbf..eb0df333b1 100644 --- a/assets/js/62.b483815a.js +++ b/assets/js/62.43618b30.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[62],{411:function(t,e,s){"use strict";s.r(e);var a=s(7),n=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.7.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.7.0")]),e("OutboundLink")],1),t._v(" improved APIs, a more robust signing process and various bugfixes and improvements.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/aaa9943a5f614da522cdac44af80adf941879210/CHANGELOG.md#v070---v060",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.7.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v070"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v070"}},[t._v("#")]),t._v(" What's new in v0.7.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h3",{attrs:{id:"new-signing-api"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#new-signing-api"}},[t._v("#")]),t._v(" New Signing API")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("Wallet::sign()")]),t._v(" method has been updated to take a "),e("em",[t._v("mutable reference")]),t._v(" to a PSBT rather than consuming it entirely. This makes it easier to sign the same PSBT multiple times with different signers:")]),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(" psbt "),e("span",{pre:!0,attrs:{class:"token operator"}},[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\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" alice_finalized "),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("sign")]),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 keyword"}},[t._v("mut")]),t._v(" psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),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(")")]),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 keyword"}},[t._v("let")]),t._v(" bob_finalized "),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("sign")]),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 keyword"}},[t._v("mut")]),t._v(" psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),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(")")]),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("p",[t._v("Under the hood, even more has changed around the way we make signatures: starting from this release, our signer will require by default that SegWit PSBTs also provide the "),e("code",[t._v("non_witness_utxo")]),t._v(' to mitigate the fee bruning "'),e("a",{attrs:{href:"https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd",target:"_blank",rel:"noopener noreferrer"}},[t._v("SegWit bug"),e("OutboundLink")],1),t._v('".')]),t._v(" "),e("p",[t._v("For this reason, the second argument of "),e("code",[t._v("Wallet::sign()")]),t._v(', which was initially used to optionally provide a different "current height" that the wallet would consider when trying to finalize the transaction, has been replaced with a more generic "options"\nargument of type '),e("a",{attrs:{href:"https://docs.rs/bdk/0.7.0/bdk/wallet/signer/struct.SignOptions.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("SignOptions")]),e("OutboundLink")],1),t._v(". This allows setting a different assumed block height and also opting out of requiring "),e("code",[t._v("non_witness_utxo")]),t._v(" by enabling the "),e("code",[t._v("trust_witness_utxo")]),t._v(" flag.")]),t._v(" "),e("p",[t._v("As a result of these new more strict requirements, BDK will also, by default, fill-in the "),e("code",[t._v("non_witness_utxo")]),t._v(" field when creating new PSBTs. The "),e("code",[t._v("TxBuilder::force_non_witness_utxo()")]),t._v(" option has been removed and a new one called\n"),e("code",[t._v("TxBuilder::only_witness_utxo()")]),t._v(" has been added, to allow users to opt-out of this new default behavior.")]),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("// Make a transaction that only contains the `witness_utxo`")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" details"),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("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("\n builder\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("send_to"),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("50_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("only_witness_utxo")]),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 builder"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),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("?")]),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 comment"}},[t._v("// Sign it by explicitly trusting just the `witness_utxo`")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),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("sign")]),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 keyword"}},[t._v("mut")]),t._v(" psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" trust_witness_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),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 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(" "),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("h3",{attrs:{id:"support-timelocks-in-the-policy-module"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#support-timelocks-in-the-policy-module"}},[t._v("#")]),t._v(" Support Timelocks in the "),e("code",[t._v("policy")]),t._v(" Module")]),t._v(" "),e("p",[t._v('A less-known part of BDK is its "policy" module: its goal is to take a descriptor and encode the spending policy represented by that descriptor in a more "user-friendly" format. On top of that, the module\ntries to provide a summary for what a user\'s descriptor can '),e("em",[t._v("contribute")]),t._v(" to a transaction. For instance, given a 2-of-2 multisig policy, a descriptor that contains only the two public keys can't "),e("em",[t._v("contribute")]),t._v(" anything,\nwhile a descriptor that has one or both private keys can, respectively, "),e("em",[t._v("contribute to")]),t._v(" and "),e("em",[t._v("satisfy")]),t._v(" the policy by making signatures.")]),t._v(" "),e("p",[t._v("In release "),e("code",[t._v("v0.5.0")]),t._v(" we added support for computing which parts of a policy are already satisfied by a given PSBT. This, combined with the contribution part, allow users to get a complete picture of what's already present\nand what's missing to fully satisfy a descriptor.")]),t._v(" "),e("p",[t._v("In this release we are starting to take timelocks into consideration when computing the "),e("em",[t._v("satisfaction")]),t._v(" component of a policy: this means that we can consider timelocks that are already expired as fully satisfied and also\nexclude policy branches that require specific "),e("code",[t._v("nLockTime")]),t._v(" or "),e("code",[t._v("nSequence")]),t._v(" values, if those aren't correctly set in the transaction.")]),t._v(" "),e("p",[t._v("Ultimately with those changes we are able to give our users a more complete picture of the completion stage of a PSBT, which also takes into account the expiration of timelocks.")]),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.6.0")]),t._v(" release around a month ago, we've had "),e("code",[t._v("39")]),t._v(" new commits made by "),e("code",[t._v("6")]),t._v(" different contributors for a total of "),e("code",[t._v("698")]),t._v(" additions and "),e("code",[t._v("309")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.6.0...v0.7.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/rajarshimaitra",target:"_blank",rel:"noopener noreferrer"}},[t._v("@rajarshimaitra"),e("OutboundLink")],1),t._v(" - Raj")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[62],{410:function(t,e,s){"use strict";s.r(e);var a=s(7),n=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.7.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.7.0")]),e("OutboundLink")],1),t._v(" improved APIs, a more robust signing process and various bugfixes and improvements.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/aaa9943a5f614da522cdac44af80adf941879210/CHANGELOG.md#v070---v060",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.7.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v070"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v070"}},[t._v("#")]),t._v(" What's new in v0.7.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h3",{attrs:{id:"new-signing-api"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#new-signing-api"}},[t._v("#")]),t._v(" New Signing API")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("Wallet::sign()")]),t._v(" method has been updated to take a "),e("em",[t._v("mutable reference")]),t._v(" to a PSBT rather than consuming it entirely. This makes it easier to sign the same PSBT multiple times with different signers:")]),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(" psbt "),e("span",{pre:!0,attrs:{class:"token operator"}},[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\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" alice_finalized "),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("sign")]),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 keyword"}},[t._v("mut")]),t._v(" psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),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(")")]),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 keyword"}},[t._v("let")]),t._v(" bob_finalized "),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("sign")]),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 keyword"}},[t._v("mut")]),t._v(" psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),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(")")]),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("p",[t._v("Under the hood, even more has changed around the way we make signatures: starting from this release, our signer will require by default that SegWit PSBTs also provide the "),e("code",[t._v("non_witness_utxo")]),t._v(' to mitigate the fee bruning "'),e("a",{attrs:{href:"https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd",target:"_blank",rel:"noopener noreferrer"}},[t._v("SegWit bug"),e("OutboundLink")],1),t._v('".')]),t._v(" "),e("p",[t._v("For this reason, the second argument of "),e("code",[t._v("Wallet::sign()")]),t._v(', which was initially used to optionally provide a different "current height" that the wallet would consider when trying to finalize the transaction, has been replaced with a more generic "options"\nargument of type '),e("a",{attrs:{href:"https://docs.rs/bdk/0.7.0/bdk/wallet/signer/struct.SignOptions.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("SignOptions")]),e("OutboundLink")],1),t._v(". This allows setting a different assumed block height and also opting out of requiring "),e("code",[t._v("non_witness_utxo")]),t._v(" by enabling the "),e("code",[t._v("trust_witness_utxo")]),t._v(" flag.")]),t._v(" "),e("p",[t._v("As a result of these new more strict requirements, BDK will also, by default, fill-in the "),e("code",[t._v("non_witness_utxo")]),t._v(" field when creating new PSBTs. The "),e("code",[t._v("TxBuilder::force_non_witness_utxo()")]),t._v(" option has been removed and a new one called\n"),e("code",[t._v("TxBuilder::only_witness_utxo()")]),t._v(" has been added, to allow users to opt-out of this new default behavior.")]),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("// Make a transaction that only contains the `witness_utxo`")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" details"),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("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("\n builder\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("send_to"),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("50_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("only_witness_utxo")]),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 builder"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),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("?")]),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 comment"}},[t._v("// Sign it by explicitly trusting just the `witness_utxo`")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),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("sign")]),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 keyword"}},[t._v("mut")]),t._v(" psbt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SignOptions")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" trust_witness_utxo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),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 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(" "),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("h3",{attrs:{id:"support-timelocks-in-the-policy-module"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#support-timelocks-in-the-policy-module"}},[t._v("#")]),t._v(" Support Timelocks in the "),e("code",[t._v("policy")]),t._v(" Module")]),t._v(" "),e("p",[t._v('A less-known part of BDK is its "policy" module: its goal is to take a descriptor and encode the spending policy represented by that descriptor in a more "user-friendly" format. On top of that, the module\ntries to provide a summary for what a user\'s descriptor can '),e("em",[t._v("contribute")]),t._v(" to a transaction. For instance, given a 2-of-2 multisig policy, a descriptor that contains only the two public keys can't "),e("em",[t._v("contribute")]),t._v(" anything,\nwhile a descriptor that has one or both private keys can, respectively, "),e("em",[t._v("contribute to")]),t._v(" and "),e("em",[t._v("satisfy")]),t._v(" the policy by making signatures.")]),t._v(" "),e("p",[t._v("In release "),e("code",[t._v("v0.5.0")]),t._v(" we added support for computing which parts of a policy are already satisfied by a given PSBT. This, combined with the contribution part, allow users to get a complete picture of what's already present\nand what's missing to fully satisfy a descriptor.")]),t._v(" "),e("p",[t._v("In this release we are starting to take timelocks into consideration when computing the "),e("em",[t._v("satisfaction")]),t._v(" component of a policy: this means that we can consider timelocks that are already expired as fully satisfied and also\nexclude policy branches that require specific "),e("code",[t._v("nLockTime")]),t._v(" or "),e("code",[t._v("nSequence")]),t._v(" values, if those aren't correctly set in the transaction.")]),t._v(" "),e("p",[t._v("Ultimately with those changes we are able to give our users a more complete picture of the completion stage of a PSBT, which also takes into account the expiration of timelocks.")]),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.6.0")]),t._v(" release around a month ago, we've had "),e("code",[t._v("39")]),t._v(" new commits made by "),e("code",[t._v("6")]),t._v(" different contributors for a total of "),e("code",[t._v("698")]),t._v(" additions and "),e("code",[t._v("309")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.6.0...v0.7.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/rajarshimaitra",target:"_blank",rel:"noopener noreferrer"}},[t._v("@rajarshimaitra"),e("OutboundLink")],1),t._v(" - Raj")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/63.2a61731d.js b/assets/js/63.2518a4ae.js similarity index 99% rename from assets/js/63.2a61731d.js rename to assets/js/63.2518a4ae.js index 50a24e68e4..a04111a070 100644 --- a/assets/js/63.2a61731d.js +++ b/assets/js/63.2518a4ae.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{415:function(t,s,a){"use strict";a.r(s);var e=a(7),n=Object(e.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: "),s("a",{attrs:{href:"https://crates.io/crates/bdk/0.8.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.8.0")]),s("OutboundLink")],1),t._v(" brings new APIs and other minor bugfixes and internal improvements.")]),t._v(" "),s("p",[t._v("You can find the full "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/67714adc80669129eff2cad8991609d3b1c41cb9/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.8.0 changelog"),s("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),s("h2",{attrs:{id:"whats-new-in-v080"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v080"}},[t._v("#")]),t._v(" What's new in v0.8.0")]),t._v(" "),s("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),s("h3",{attrs:{id:"getting-the-derivation-index"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getting-the-derivation-index"}},[t._v("#")]),t._v(" Getting the Derivation Index")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("Wallet::get_address()")]),t._v(" method now returns an "),s("a",{attrs:{href:"https://docs.rs/bdk/0.8.0/bdk/wallet/struct.AddressInfo.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("AddressInfo")]),s("OutboundLink")],1),t._v(" structure, rather than a simple "),s("code",[t._v("Address")]),t._v(". This new structure contains the address but also the derivation index, which can be useful in some contexts.")]),t._v(" "),s("p",[t._v("Since the structure implements "),s("code",[t._v("Deref")]),t._v(" it can be used directly as a "),s("code",[t._v("&Address")]),t._v(", which simplifies migrating to this change a little bit.")]),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(" address_info "),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("AddressInfo")]),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 comment"}},[t._v("// Print the address and derivation index")]),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('"Address #{}: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address_info"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address_info"),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\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the `AddressInfo` structure directly like an `Address`")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" script_pubkey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" address_info"),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("h3",{attrs:{id:"explicitly-enable-non-all-sighashes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#explicitly-enable-non-all-sighashes"}},[t._v("#")]),t._v(" Explicitly Enable non-ALL Sighashes")]),t._v(" "),s("p",[t._v("To mitigate potential attacks in multiparty protocols, this release includes a new "),s("a",{attrs:{href:"https://docs.rs/bdk/0.8.0/bdk/wallet/signer/struct.SignOptions.html#structfield.allow_all_sighashes",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("SignOptions::allow_all_sighashes")]),s("OutboundLink")],1),t._v(" option that must be explicitly enabled to let the signers produce signatures\nwith any non-ALL sighash.")]),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(" psbt "),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 punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fails if the psbt uses non-ALL sighashes")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),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("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\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Produces a signature successfully")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),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("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")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" allow_all_sighashes"),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 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(" "),s("span",{pre:!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("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.7.0")]),t._v(" release around a month ago, we've had "),s("code",[t._v("39")]),t._v(" new commits made by "),s("code",[t._v("6")]),t._v(" different contributors for a total of "),s("code",[t._v("1540")]),t._v(" additions and "),s("code",[t._v("1380")]),t._v(" deletions. Here's the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.7.0...v0.8.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",[t._v("[@futurepaul][@futurepaul] - Paul Miller")])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{413:function(t,s,a){"use strict";a.r(s);var e=a(7),n=Object(e.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: "),s("a",{attrs:{href:"https://crates.io/crates/bdk/0.8.0",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v0.8.0")]),s("OutboundLink")],1),t._v(" brings new APIs and other minor bugfixes and internal improvements.")]),t._v(" "),s("p",[t._v("You can find the full "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/67714adc80669129eff2cad8991609d3b1c41cb9/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.8.0 changelog"),s("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),s("h2",{attrs:{id:"whats-new-in-v080"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v080"}},[t._v("#")]),t._v(" What's new in v0.8.0")]),t._v(" "),s("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),s("h3",{attrs:{id:"getting-the-derivation-index"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getting-the-derivation-index"}},[t._v("#")]),t._v(" Getting the Derivation Index")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("Wallet::get_address()")]),t._v(" method now returns an "),s("a",{attrs:{href:"https://docs.rs/bdk/0.8.0/bdk/wallet/struct.AddressInfo.html",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("AddressInfo")]),s("OutboundLink")],1),t._v(" structure, rather than a simple "),s("code",[t._v("Address")]),t._v(". This new structure contains the address but also the derivation index, which can be useful in some contexts.")]),t._v(" "),s("p",[t._v("Since the structure implements "),s("code",[t._v("Deref")]),t._v(" it can be used directly as a "),s("code",[t._v("&Address")]),t._v(", which simplifies migrating to this change a little bit.")]),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(" address_info "),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("AddressInfo")]),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 comment"}},[t._v("// Print the address and derivation index")]),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('"Address #{}: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address_info"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" address_info"),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\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use the `AddressInfo` structure directly like an `Address`")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" script_pubkey "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" address_info"),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("h3",{attrs:{id:"explicitly-enable-non-all-sighashes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#explicitly-enable-non-all-sighashes"}},[t._v("#")]),t._v(" Explicitly Enable non-ALL Sighashes")]),t._v(" "),s("p",[t._v("To mitigate potential attacks in multiparty protocols, this release includes a new "),s("a",{attrs:{href:"https://docs.rs/bdk/0.8.0/bdk/wallet/signer/struct.SignOptions.html#structfield.allow_all_sighashes",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("SignOptions::allow_all_sighashes")]),s("OutboundLink")],1),t._v(" option that must be explicitly enabled to let the signers produce signatures\nwith any non-ALL sighash.")]),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(" psbt "),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 punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Fails if the psbt uses non-ALL sighashes")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),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("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\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Produces a signature successfully")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" finalized "),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("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")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" allow_all_sighashes"),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 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(" "),s("span",{pre:!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("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.7.0")]),t._v(" release around a month ago, we've had "),s("code",[t._v("39")]),t._v(" new commits made by "),s("code",[t._v("6")]),t._v(" different contributors for a total of "),s("code",[t._v("1540")]),t._v(" additions and "),s("code",[t._v("1380")]),t._v(" deletions. Here's the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.7.0...v0.8.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",[t._v("[@futurepaul][@futurepaul] - Paul Miller")])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/64.1a1630c4.js b/assets/js/64.c74d4d9a.js similarity index 99% rename from assets/js/64.1a1630c4.js rename to assets/js/64.c74d4d9a.js index b337d780f9..844803fcee 100644 --- a/assets/js/64.1a1630c4.js +++ b/assets/js/64.c74d4d9a.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{412: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.9.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.9.0")]),e("OutboundLink")],1),t._v(" brings support for Bitcoin Core backends, more sanity checks and bugfixes.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/7a9b691f68c41116dc7857bc0267a2e3b2eafdd3/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.9.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v090"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v090"}},[t._v("#")]),t._v(" What's new in v0.9.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h2",{attrs:{id:"bitcoin-core-blockchain-backend"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-core-blockchain-backend"}},[t._v("#")]),t._v(" Bitcoin Core "),e("code",[t._v("Blockchain")]),t._v(" Backend")]),t._v(" "),e("p",[t._v("This release finally adds support for using a Bitcoin Core node as the "),e("code",[t._v("Blockchain")]),t._v(" backend for a wallet, through the RPC. This is still considered experimental for the time being, since there are a few missing\nthings that we'd like to add, and adding those could force us to change the API a little.")]),t._v(" "),e("p",[t._v("Nonetheless, if you don't mind a breaking-change later on it's already fully functional.")]),t._v(" "),e("p",[t._v("The backend works by importing addresses in Bitcoin Core using the "),e("code",[t._v("importmulti")]),t._v(" call.")]),t._v(" "),e("p",[t._v("Using it is pretty straightforward, here's a quick example:")]),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(" config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n url"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:18332"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),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 auth"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoincore_rpc"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CookieFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/home/user/.bitcoin/.cookie"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),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 network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n wallet_name"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wallet_name"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),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 skip_blocks"),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(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),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("Similarly to the compact filters backend, the "),e("code",[t._v("skip_blocks")]),t._v(" field allows for starting a rescan of the blockchain at a given height rather than the genesis, saving some time. The rescan is only performed once, the\nfirst time an address is imported. Afterwards every "),e("code",[t._v("sync()")]),t._v(" call will only perform a few queries on the node and it will be much faster.")]),t._v(" "),e("h2",{attrs:{id:"updated-transactiondetails-struct"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#updated-transactiondetails-struct"}},[t._v("#")]),t._v(" Updated "),e("code",[t._v("TransactionDetails")]),t._v(" Struct")]),t._v(" "),e("p",[t._v("To better accomodate the Bitcoin Core RPC and potentially more future new backends, the "),e("a",{attrs:{href:"https://docs.rs/bdk/0.9.0/bdk/struct.TransactionDetails.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("TransactionDetails")]),e("OutboundLink")],1),t._v(" structure have been updated as follows:")]),t._v(" "),e("ul",[e("li",[t._v("The "),e("code",[t._v("fees")]),t._v(" field has been renamed to "),e("code",[t._v("fee")]),t._v(" and it has been made optional. "),e("code",[t._v("Blockchain")]),t._v(" backends can set this to "),e("code",[t._v("None")]),t._v(" when they have no way of computing the fee of a transaction")]),t._v(" "),e("li",[t._v("The "),e("code",[t._v("timestamp")]),t._v(" and "),e("code",[t._v("height")]),t._v(" fields have been merged into an optional "),e("a",{attrs:{href:"https://docs.rs/bdk/0.9.0/bdk/struct.ConfirmationTime.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("ConfirmationTime")]),e("OutboundLink")],1),t._v(" struct")])]),t._v(" "),e("h2",{attrs:{id:"verify-downloaded-txs"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#verify-downloaded-txs"}},[t._v("#")]),t._v(" Verify Downloaded TXs")]),t._v(" "),e("p",[t._v("This release also introduces an opt-in feature called "),e("code",[t._v("verify")]),t._v(" that can be enabled to verify the unconfirmed transactions that BDK downloads from untrusted sources like Electrum servers.")]),t._v(" "),e("p",[t._v('Verifying the transactions against the consensus rules can be an additional protection against some kind of attacks that could trick a wallet into creating wrong RBF (BIP 125) "bump" transactions. Check out '),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/352",target:"_blank",rel:"noopener noreferrer"}},[t._v("the issue"),e("OutboundLink")],1),t._v("\nfor more details.")]),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.8.0")]),t._v(" release around a month ago, we've had "),e("code",[t._v("45")]),t._v(" new commits made by "),e("code",[t._v("6")]),t._v(" different contributors for a total of "),e("code",[t._v("1336")]),t._v(" additions and "),e("code",[t._v("266")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.8.0...v0.9.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",[t._v("[@jb55][@jb55] - William Casarin")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{414: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.9.0",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("v0.9.0")]),e("OutboundLink")],1),t._v(" brings support for Bitcoin Core backends, more sanity checks and bugfixes.")]),t._v(" "),e("p",[t._v("You can find the full "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/7a9b691f68c41116dc7857bc0267a2e3b2eafdd3/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("v0.9.0 changelog"),e("OutboundLink")],1),t._v(" on GitHub.")]),t._v(" "),e("h2",{attrs:{id:"whats-new-in-v090"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#whats-new-in-v090"}},[t._v("#")]),t._v(" What's new in v0.9.0")]),t._v(" "),e("p",[t._v("Below are some highlights of the new release:")]),t._v(" "),e("h2",{attrs:{id:"bitcoin-core-blockchain-backend"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-core-blockchain-backend"}},[t._v("#")]),t._v(" Bitcoin Core "),e("code",[t._v("Blockchain")]),t._v(" Backend")]),t._v(" "),e("p",[t._v("This release finally adds support for using a Bitcoin Core node as the "),e("code",[t._v("Blockchain")]),t._v(" backend for a wallet, through the RPC. This is still considered experimental for the time being, since there are a few missing\nthings that we'd like to add, and adding those could force us to change the API a little.")]),t._v(" "),e("p",[t._v("Nonetheless, if you don't mind a breaking-change later on it's already fully functional.")]),t._v(" "),e("p",[t._v("The backend works by importing addresses in Bitcoin Core using the "),e("code",[t._v("importmulti")]),t._v(" call.")]),t._v(" "),e("p",[t._v("Using it is pretty straightforward, here's a quick example:")]),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(" config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcConfig")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n url"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:18332"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),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 auth"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bitcoincore_rpc"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Auth")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CookieFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/home/user/.bitcoin/.cookie"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),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 network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n wallet_name"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wallet_name"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),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 skip_blocks"),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(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RpcBlockchain")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),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("Similarly to the compact filters backend, the "),e("code",[t._v("skip_blocks")]),t._v(" field allows for starting a rescan of the blockchain at a given height rather than the genesis, saving some time. The rescan is only performed once, the\nfirst time an address is imported. Afterwards every "),e("code",[t._v("sync()")]),t._v(" call will only perform a few queries on the node and it will be much faster.")]),t._v(" "),e("h2",{attrs:{id:"updated-transactiondetails-struct"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#updated-transactiondetails-struct"}},[t._v("#")]),t._v(" Updated "),e("code",[t._v("TransactionDetails")]),t._v(" Struct")]),t._v(" "),e("p",[t._v("To better accomodate the Bitcoin Core RPC and potentially more future new backends, the "),e("a",{attrs:{href:"https://docs.rs/bdk/0.9.0/bdk/struct.TransactionDetails.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("TransactionDetails")]),e("OutboundLink")],1),t._v(" structure have been updated as follows:")]),t._v(" "),e("ul",[e("li",[t._v("The "),e("code",[t._v("fees")]),t._v(" field has been renamed to "),e("code",[t._v("fee")]),t._v(" and it has been made optional. "),e("code",[t._v("Blockchain")]),t._v(" backends can set this to "),e("code",[t._v("None")]),t._v(" when they have no way of computing the fee of a transaction")]),t._v(" "),e("li",[t._v("The "),e("code",[t._v("timestamp")]),t._v(" and "),e("code",[t._v("height")]),t._v(" fields have been merged into an optional "),e("a",{attrs:{href:"https://docs.rs/bdk/0.9.0/bdk/struct.ConfirmationTime.html",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("ConfirmationTime")]),e("OutboundLink")],1),t._v(" struct")])]),t._v(" "),e("h2",{attrs:{id:"verify-downloaded-txs"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#verify-downloaded-txs"}},[t._v("#")]),t._v(" Verify Downloaded TXs")]),t._v(" "),e("p",[t._v("This release also introduces an opt-in feature called "),e("code",[t._v("verify")]),t._v(" that can be enabled to verify the unconfirmed transactions that BDK downloads from untrusted sources like Electrum servers.")]),t._v(" "),e("p",[t._v('Verifying the transactions against the consensus rules can be an additional protection against some kind of attacks that could trick a wallet into creating wrong RBF (BIP 125) "bump" transactions. Check out '),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/352",target:"_blank",rel:"noopener noreferrer"}},[t._v("the issue"),e("OutboundLink")],1),t._v("\nfor more details.")]),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.8.0")]),t._v(" release around a month ago, we've had "),e("code",[t._v("45")]),t._v(" new commits made by "),e("code",[t._v("6")]),t._v(" different contributors for a total of "),e("code",[t._v("1336")]),t._v(" additions and "),e("code",[t._v("266")]),t._v(" deletions. Here's the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/v0.8.0...v0.9.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",[t._v("[@jb55][@jb55] - William Casarin")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/65.5db91110.js b/assets/js/65.084b8455.js similarity index 99% rename from assets/js/65.5db91110.js rename to assets/js/65.084b8455.js index 5b53f3fddf..d8af24c391 100644 --- a/assets/js/65.5db91110.js +++ b/assets/js/65.084b8455.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[65],{413:function(e,t,o){"use strict";o.r(t);var a=o(7),i=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Over the past few months the work on "),t("a",{attrs:{href:"https://github.com/LLFourn/bdk_core_staging",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk_core"),t("OutboundLink")],1),e._v(" quietly continued behind the scenes, and as the time went on it started expanding beyond the scope of just improving the "),t("em",[e._v("syncing")]),e._v(" mechanism of BDK. Being a new fresh\nproject it allowed for iterating much faster, and we soon realized we could make large improvements to the general architecture of BDK to fix many of the issues and shortcomings found over time.")]),e._v(" "),t("p",[e._v("For this reason, we decided to move forward with the project and start planning the integration into BDK itself. This blog post will briefly describe the new concept for how BDK will be structured and lay down a plan\nfor the development in the next few months.")]),e._v(" "),t("h2",{attrs:{id:"goals"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#goals"}},[e._v("#")]),e._v(" Goals")]),e._v(" "),t("p",[e._v("First of all, we should outline at least the main goals of BDK 1.0, ergo what we want to improve over the current state of the project.")]),e._v(" "),t("h3",{attrs:{id:"stable-api"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#stable-api"}},[e._v("#")]),e._v(" Stable API")]),e._v(" "),t("p",[e._v("Ever since the "),t("code",[e._v("0.1.0")]),e._v(" release of BDK we've always broken the API with each release. Most of the time in minor and very contained ways, but in "),t("em",[e._v("some")]),e._v(" way nonetheless. One of the main sources of breakage have been\nthe "),t("code",[e._v("Blockchain")]),e._v(" and "),t("code",[e._v("Database")]),e._v(" traits. Those two together are used in essentially any operation a user may do on a "),t("code",[e._v("Wallet")]),e._v(", and are thus impacted by any relatively large change or new feature added to the code.")]),e._v(" "),t("p",[e._v("Want to "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/515",target:"_blank",rel:"noopener noreferrer"}},[e._v("keep track of whether a UTXO is spent"),t("OutboundLink")],1),e._v("? You need to change the "),t("code",[e._v("Database")]),e._v(" that stores this information. Want to "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/669",target:"_blank",rel:"noopener noreferrer"}},[e._v("know the timestamp of the latest block"),t("OutboundLink")],1),e._v("?\nYou need to change the "),t("code",[e._v("Blockchain")]),e._v(" trait to fetch that extra bit of information. And the list goes on and on.")]),e._v(" "),t("p",[e._v("Since making changes to these traits is always so painful for us and our downstream users, this ended up delaying or considerably slowing down the development of new features in BDK.")]),e._v(" "),t("p",[e._v("bdk_core tries to minimize the (ab)use of traits, and this will help immensely when trying to provide a stable API for our users.")]),e._v(" "),t("h3",{attrs:{id:"upstreaming-our-code"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#upstreaming-our-code"}},[e._v("#")]),e._v(" Upstreaming our code")]),e._v(" "),t("p",[e._v("BDK internally implements many features that could be useful to other projects as well. While working on this integration we will also try to upstream some of our code to the relevant crates, mainly "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("rust-miniscript")]),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("This has essentially three benefits:")]),e._v(" "),t("ol",[t("li",[e._v("A new set of eyes will take a look at the code, potentially spotting issues or suggesting improvements")]),e._v(" "),t("li",[e._v("This will lower the amount of code that we have to maintain ourselves")]),e._v(" "),t("li",[e._v("Other people can benefit from our code, which was previously tightly integrated into BDK and hard to re-use")])]),e._v(" "),t("h3",{attrs:{id:"partially-syncing-a-wallet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#partially-syncing-a-wallet"}},[e._v("#")]),e._v(" Partially Syncing a Wallet")]),e._v(" "),t("p",[e._v("This single point was the main reason the bdk_core project was kickstarted, and it means giving our users the ability to incrementally sync a wallet over time instead of working in single big batches.")]),e._v(" "),t("p",[e._v("This is explained very well in the "),t("RouterLink",{attrs:{to:"/blog/bdk-core-pt1/"}},[e._v("first bdk_core post")]),e._v(", so I won't go into details here. Think of this as a much more flexible way to sync a wallet, which in turn will allow us to simplify our current implementation\nof blockchain backends like compact block filters, and also offer a better API for our users.")],1),e._v(" "),t("h3",{attrs:{id:"no-std"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#no-std"}},[e._v("#")]),e._v(" "),t("code",[e._v("no_std")])]),e._v(" "),t("p",[e._v("bdk_core is built with "),t("code",[e._v("no_std")]),e._v(" in mind since the beginning, something we've been wanting to support in BDK "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/205",target:"_blank",rel:"noopener noreferrer"}},[e._v("for a long time"),t("OutboundLink")],1),e._v('. Being more modular means the "core" module doesn\'t really need that many dependencies,\nand this really simplifies the '),t("code",[e._v("no_std")]),e._v(" work.")]),e._v(" "),t("p",[e._v("This will allow the main components of BDK to work on embedded hardware as well, making it possible to use the library as a foundation for any Bitcoin hardware device like hardware wallets.")]),e._v(" "),t("h3",{attrs:{id:"lower-msrv"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#lower-msrv"}},[e._v("#")]),e._v(" Lower MSRV")]),e._v(" "),t("p",[e._v("Removing many of our current dependencies from the core components of BDK will also allow us to lower our MSRV considerably, which in turn will allow BDK to compile on older distros or entirely different toolchains like\n"),t("a",{attrs:{href:"https://github.com/thepowersgang/mrustc",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("mrustc")]),t("OutboundLink")],1),e._v(", which usually don't keep up with "),t("code",[e._v("rustc")]),e._v(" in terms of language features.")]),e._v(" "),t("h2",{attrs:{id:"architecture"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#architecture"}},[e._v("#")]),e._v(" Architecture")]),e._v(" "),t("p",[e._v("Roughly speaking, after integrating bdk_core into BDK the architecture will look like this:")]),e._v(" "),t("ul",[t("li",[e._v("bdk_core: this crate will contain all the low level components of a Bitcoin wallet. For example, using this low level API it will be possible to keep track of arbitrary scripts (without the limitations"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v("\nof descriptors) or apply individual blocks to the state of the wallet")]),e._v(" "),t("li",[e._v("bdk_compat: this crate will use the components provided by bdk_core to implement a descriptor-based wallet that supports up to two "),t("em",[e._v("keychains")]),e._v(", like our current "),t("code",[e._v("Wallet")]),e._v(" implementation does. It will allow our\nusers to upgrade to BDK 1.0 with minimal changes to their code, but being a compatibility layer it will probably lack many of the advanced features that bdk_core brings to the table")]),e._v(" "),t("li",[e._v("bdk_"),t("em",[e._v("")]),e._v(": the blockchain backends like Esplora, Electrum, RPC, will be moved into individual separate crates that users can decide to include individually")])]),e._v(" "),t("h2",{attrs:{id:"timeline"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#timeline"}},[e._v("#")]),e._v(" Timeline")]),e._v(" "),t("p",[e._v("We can't provide a precise timeline because it's a big development effort and it also depends on some relatively large PRs making into upstream project. That said, here's our rough plan:")]),e._v(" "),t("ol",[t("li",[e._v("October: during this month we will work on opening a PR to integrate bdk_core into BDK")]),e._v(" "),t("li",[e._v("November: review of the PR, work on upstreaming our code to "),t("code",[e._v("rust-miniscript")])]),e._v(" "),t("li",[e._v("December: finishing touches, examples, documentation")])]),e._v(" "),t("h2",{attrs:{id:"feature-freezing-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#feature-freezing-bdk"}},[e._v("#")]),e._v(" Feature Freezing BDK")]),e._v(" "),t("p",[e._v("With our focus shifting to bdk_core we are officially "),t("em",[e._v("feature freezing")]),e._v(" BDK starting from release "),t("code",[e._v("0.23")]),e._v(" (which will be published on October 6th). This means that we won't be adding any new features to BDK until the\nintegration is completed, because it takes a lot of effort to implement and/or review them, and there's the risk that most of the code will have to be re-done or thrown away anyway when moving to bdk_core.")]),e._v(" "),t("p",[e._v("A notable exception to this rule will be the upcoming "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/770",target:"_blank",rel:"noopener noreferrer"}},[e._v("upgrade to "),t("code",[e._v("rust-bitcoin")]),e._v(" "),t("code",[e._v("0.29")]),t("OutboundLink")],1),e._v(", which is now planned for the release "),t("code",[e._v("0.24")]),e._v(" since "),t("code",[e._v("rust-miniscript")]),e._v(" "),t("code",[e._v("8.0.0")]),e._v(" hasn't been released in time for "),t("code",[e._v("0.23")]),e._v(".")]),e._v(" "),t("p",[e._v("During this feature freeze period we will keep maintaining the library, updating our dependencies, fixing bugs and making releases accordingly.")]),e._v(" "),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("This is an exciting new development for BDK, a well needed refresh to an architecture that hasn't changed much over time, but that it's starting to show its age. This integration will open up so many new possibilities\nfor our downstream users, and it's a major step towards our goal of providing simple, yet powerful tools for Bitcoin developers 🚀.")]),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("Not every script can be expressed as descriptor "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[65],{415:function(e,t,o){"use strict";o.r(t);var a=o(7),i=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Over the past few months the work on "),t("a",{attrs:{href:"https://github.com/LLFourn/bdk_core_staging",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk_core"),t("OutboundLink")],1),e._v(" quietly continued behind the scenes, and as the time went on it started expanding beyond the scope of just improving the "),t("em",[e._v("syncing")]),e._v(" mechanism of BDK. Being a new fresh\nproject it allowed for iterating much faster, and we soon realized we could make large improvements to the general architecture of BDK to fix many of the issues and shortcomings found over time.")]),e._v(" "),t("p",[e._v("For this reason, we decided to move forward with the project and start planning the integration into BDK itself. This blog post will briefly describe the new concept for how BDK will be structured and lay down a plan\nfor the development in the next few months.")]),e._v(" "),t("h2",{attrs:{id:"goals"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#goals"}},[e._v("#")]),e._v(" Goals")]),e._v(" "),t("p",[e._v("First of all, we should outline at least the main goals of BDK 1.0, ergo what we want to improve over the current state of the project.")]),e._v(" "),t("h3",{attrs:{id:"stable-api"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#stable-api"}},[e._v("#")]),e._v(" Stable API")]),e._v(" "),t("p",[e._v("Ever since the "),t("code",[e._v("0.1.0")]),e._v(" release of BDK we've always broken the API with each release. Most of the time in minor and very contained ways, but in "),t("em",[e._v("some")]),e._v(" way nonetheless. One of the main sources of breakage have been\nthe "),t("code",[e._v("Blockchain")]),e._v(" and "),t("code",[e._v("Database")]),e._v(" traits. Those two together are used in essentially any operation a user may do on a "),t("code",[e._v("Wallet")]),e._v(", and are thus impacted by any relatively large change or new feature added to the code.")]),e._v(" "),t("p",[e._v("Want to "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/515",target:"_blank",rel:"noopener noreferrer"}},[e._v("keep track of whether a UTXO is spent"),t("OutboundLink")],1),e._v("? You need to change the "),t("code",[e._v("Database")]),e._v(" that stores this information. Want to "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/669",target:"_blank",rel:"noopener noreferrer"}},[e._v("know the timestamp of the latest block"),t("OutboundLink")],1),e._v("?\nYou need to change the "),t("code",[e._v("Blockchain")]),e._v(" trait to fetch that extra bit of information. And the list goes on and on.")]),e._v(" "),t("p",[e._v("Since making changes to these traits is always so painful for us and our downstream users, this ended up delaying or considerably slowing down the development of new features in BDK.")]),e._v(" "),t("p",[e._v("bdk_core tries to minimize the (ab)use of traits, and this will help immensely when trying to provide a stable API for our users.")]),e._v(" "),t("h3",{attrs:{id:"upstreaming-our-code"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#upstreaming-our-code"}},[e._v("#")]),e._v(" Upstreaming our code")]),e._v(" "),t("p",[e._v("BDK internally implements many features that could be useful to other projects as well. While working on this integration we will also try to upstream some of our code to the relevant crates, mainly "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("rust-miniscript")]),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("This has essentially three benefits:")]),e._v(" "),t("ol",[t("li",[e._v("A new set of eyes will take a look at the code, potentially spotting issues or suggesting improvements")]),e._v(" "),t("li",[e._v("This will lower the amount of code that we have to maintain ourselves")]),e._v(" "),t("li",[e._v("Other people can benefit from our code, which was previously tightly integrated into BDK and hard to re-use")])]),e._v(" "),t("h3",{attrs:{id:"partially-syncing-a-wallet"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#partially-syncing-a-wallet"}},[e._v("#")]),e._v(" Partially Syncing a Wallet")]),e._v(" "),t("p",[e._v("This single point was the main reason the bdk_core project was kickstarted, and it means giving our users the ability to incrementally sync a wallet over time instead of working in single big batches.")]),e._v(" "),t("p",[e._v("This is explained very well in the "),t("RouterLink",{attrs:{to:"/blog/bdk-core-pt1/"}},[e._v("first bdk_core post")]),e._v(", so I won't go into details here. Think of this as a much more flexible way to sync a wallet, which in turn will allow us to simplify our current implementation\nof blockchain backends like compact block filters, and also offer a better API for our users.")],1),e._v(" "),t("h3",{attrs:{id:"no-std"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#no-std"}},[e._v("#")]),e._v(" "),t("code",[e._v("no_std")])]),e._v(" "),t("p",[e._v("bdk_core is built with "),t("code",[e._v("no_std")]),e._v(" in mind since the beginning, something we've been wanting to support in BDK "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues/205",target:"_blank",rel:"noopener noreferrer"}},[e._v("for a long time"),t("OutboundLink")],1),e._v('. Being more modular means the "core" module doesn\'t really need that many dependencies,\nand this really simplifies the '),t("code",[e._v("no_std")]),e._v(" work.")]),e._v(" "),t("p",[e._v("This will allow the main components of BDK to work on embedded hardware as well, making it possible to use the library as a foundation for any Bitcoin hardware device like hardware wallets.")]),e._v(" "),t("h3",{attrs:{id:"lower-msrv"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#lower-msrv"}},[e._v("#")]),e._v(" Lower MSRV")]),e._v(" "),t("p",[e._v("Removing many of our current dependencies from the core components of BDK will also allow us to lower our MSRV considerably, which in turn will allow BDK to compile on older distros or entirely different toolchains like\n"),t("a",{attrs:{href:"https://github.com/thepowersgang/mrustc",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("mrustc")]),t("OutboundLink")],1),e._v(", which usually don't keep up with "),t("code",[e._v("rustc")]),e._v(" in terms of language features.")]),e._v(" "),t("h2",{attrs:{id:"architecture"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#architecture"}},[e._v("#")]),e._v(" Architecture")]),e._v(" "),t("p",[e._v("Roughly speaking, after integrating bdk_core into BDK the architecture will look like this:")]),e._v(" "),t("ul",[t("li",[e._v("bdk_core: this crate will contain all the low level components of a Bitcoin wallet. For example, using this low level API it will be possible to keep track of arbitrary scripts (without the limitations"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v("\nof descriptors) or apply individual blocks to the state of the wallet")]),e._v(" "),t("li",[e._v("bdk_compat: this crate will use the components provided by bdk_core to implement a descriptor-based wallet that supports up to two "),t("em",[e._v("keychains")]),e._v(", like our current "),t("code",[e._v("Wallet")]),e._v(" implementation does. It will allow our\nusers to upgrade to BDK 1.0 with minimal changes to their code, but being a compatibility layer it will probably lack many of the advanced features that bdk_core brings to the table")]),e._v(" "),t("li",[e._v("bdk_"),t("em",[e._v("")]),e._v(": the blockchain backends like Esplora, Electrum, RPC, will be moved into individual separate crates that users can decide to include individually")])]),e._v(" "),t("h2",{attrs:{id:"timeline"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#timeline"}},[e._v("#")]),e._v(" Timeline")]),e._v(" "),t("p",[e._v("We can't provide a precise timeline because it's a big development effort and it also depends on some relatively large PRs making into upstream project. That said, here's our rough plan:")]),e._v(" "),t("ol",[t("li",[e._v("October: during this month we will work on opening a PR to integrate bdk_core into BDK")]),e._v(" "),t("li",[e._v("November: review of the PR, work on upstreaming our code to "),t("code",[e._v("rust-miniscript")])]),e._v(" "),t("li",[e._v("December: finishing touches, examples, documentation")])]),e._v(" "),t("h2",{attrs:{id:"feature-freezing-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#feature-freezing-bdk"}},[e._v("#")]),e._v(" Feature Freezing BDK")]),e._v(" "),t("p",[e._v("With our focus shifting to bdk_core we are officially "),t("em",[e._v("feature freezing")]),e._v(" BDK starting from release "),t("code",[e._v("0.23")]),e._v(" (which will be published on October 6th). This means that we won't be adding any new features to BDK until the\nintegration is completed, because it takes a lot of effort to implement and/or review them, and there's the risk that most of the code will have to be re-done or thrown away anyway when moving to bdk_core.")]),e._v(" "),t("p",[e._v("A notable exception to this rule will be the upcoming "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pull/770",target:"_blank",rel:"noopener noreferrer"}},[e._v("upgrade to "),t("code",[e._v("rust-bitcoin")]),e._v(" "),t("code",[e._v("0.29")]),t("OutboundLink")],1),e._v(", which is now planned for the release "),t("code",[e._v("0.24")]),e._v(" since "),t("code",[e._v("rust-miniscript")]),e._v(" "),t("code",[e._v("8.0.0")]),e._v(" hasn't been released in time for "),t("code",[e._v("0.23")]),e._v(".")]),e._v(" "),t("p",[e._v("During this feature freeze period we will keep maintaining the library, updating our dependencies, fixing bugs and making releases accordingly.")]),e._v(" "),t("h2",{attrs:{id:"conclusion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[e._v("#")]),e._v(" Conclusion")]),e._v(" "),t("p",[e._v("This is an exciting new development for BDK, a well needed refresh to an architecture that hasn't changed much over time, but that it's starting to show its age. This integration will open up so many new possibilities\nfor our downstream users, and it's a major step towards our goal of providing simple, yet powerful tools for Bitcoin developers 🚀.")]),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("Not every script can be expressed as descriptor "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/69.34e6059d.js b/assets/js/69.c4fd27b4.js similarity index 99% rename from assets/js/69.34e6059d.js rename to assets/js/69.c4fd27b4.js index 197d7802bc..44d01e47ac 100644 --- a/assets/js/69.34e6059d.js +++ b/assets/js/69.c4fd27b4.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[69],{419: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("h1",{attrs:{id:"compiler"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compiler"}},[t._v("#")]),t._v(" Compiler")]),t._v(" "),s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("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 "),s("code",[t._v("bdk")]),t._v(" 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 "),s("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("in this page"),s("OutboundLink")],1),t._v(',\nspecifically in the "Policy to Miniscript compiler". The compiler included in BDK does basically the same job, but produces descriptors for '),s("code",[t._v("rust-miniscript")]),t._v(" that have some minor differences from\nthe ones made by the C++ implementation used in that website.")]),t._v(" "),s("h2",{attrs:{id:"installation"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),s("p",[t._v("To install the miniscript compiler run the following command:")]),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("cargo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/bdk "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--features")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compiler"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--example")]),t._v(" miniscriptc\n")])])]),s("p",[t._v("Once the command is done, you should have a "),s("code",[t._v("miniscriptc")]),t._v(" command available. You can check if that's the case by running "),s("code",[t._v("miniscriptc --help")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"usage"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#usage"}},[t._v("#")]),t._v(" Usage")]),t._v(" "),s("p",[t._v('In this case the interface is very simple: it accepts two arguments called "POLICY" and "TYPE", in this order. The first one, as the name implies, sets the spending policy to compile. The latter defines the type\nof address that should be used to encapsulate the produced script, like a P2SH, P2WSH, etc.')]),t._v(" "),s("p",[t._v("Optionally, the "),s("code",[t._v("--parsed_policy")]),t._v(' flag can be enabled and it will make the compiler print the JSON "human-readable" version of the spending policy, as described in the '),s("RouterLink",{attrs:{to:"/bdk-cli/interface/#policies"}},[s("code",[t._v("policies subcommand")])]),t._v(" of the CLI.")],1),t._v(" "),s("p",[t._v("The "),s("code",[t._v("--network")]),t._v(" flag can be used to change the network encoding of the address shown.")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("Tip")]),t._v(" "),s("p",[t._v("Keep in mind that since the compiler loads and interprets the descriptor, all the public keys specified in the policy must be valid public keys. This differs from the web tool linked above that also accepts\nplaceholders too. As described in the previous sections of this guide, the keys can be either "),s("code",[t._v("xpub")]),t._v("/"),s("code",[t._v("xprv")]),t._v(" with or without metadata and a derivation path, WIF keys or raw hex public keys.")])]),t._v(" "),s("h2",{attrs:{id:"example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example"}},[t._v("#")]),t._v(" Example")]),t._v(" "),s("p",[t._v("Let's take this policy for example:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("miniscriptc "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--parsed_policy")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"and(pk(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR),or(50@pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c),older(1000)))"')]),t._v(" sh-wsh\n")])])]),s("p",[t._v("The compiler should print something like:")]),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 punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2020")]),t._v("-04-29T10:42:05Z INFO miniscriptc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" Compiling policy: and"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",or"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),t._v("@pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",older"),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(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2020")]),t._v("-04-29T10:42:05Z INFO miniscriptc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". Descriptor: sh"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wsh"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("and_v"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("or_c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c:pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",v:older"),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("))")]),t._v(",c:pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR"),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 number"}},[t._v("2020")]),t._v("-04-29T10:42:05Z INFO miniscriptc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". First address: 2MsqrJuZewY3o3ADAy1Uhi5vsBqTANjH3Cf\n")])])]),s("p",[t._v("JSON policy:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"THRESH"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"items"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"THRESH"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"items"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SIGNATURE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"pubkey"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RELATIVETIMELOCK"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"value"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"COMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"condition"')]),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 property"}},[t._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),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("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 property"}},[t._v('"threshold"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[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 property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIALCOMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"n"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"m"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[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 property"}},[t._v('"items"')]),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 number"}},[t._v("1")]),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 property"}},[t._v('"conditions"')]),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 property"}},[t._v('"[1]"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),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("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 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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SIGNATURE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"pubkey"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"COMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"condition"')]),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 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("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 property"}},[t._v('"threshold"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIALCOMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"n"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"m"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"items"')]),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 number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),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 property"}},[t._v('"conditions"')]),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 property"}},[t._v('"[0, 1]"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),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("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("h2",{attrs:{id:"troubleshooting"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#troubleshooting"}},[t._v("#")]),t._v(" Troubleshooting")]),t._v(" "),s("h4",{attrs:{id:"nothing-is-printed"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#nothing-is-printed"}},[t._v("#")]),t._v(" Nothing is printed")]),t._v(" "),s("p",[t._v("This might mean that you have a "),s("code",[t._v("RUST_LOG")]),t._v(" variable set to a value that suppresses the compiler's log. You can try adding "),s("code",[t._v("miniscriptc=info")]),t._v(" to your "),s("code",[t._v("RUST_LOG")]),t._v(" value and see if that works, or open a new clean\nshell.")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[69],{420: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("h1",{attrs:{id:"compiler"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compiler"}},[t._v("#")]),t._v(" Compiler")]),t._v(" "),s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("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 "),s("code",[t._v("bdk")]),t._v(" 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 "),s("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("in this page"),s("OutboundLink")],1),t._v(',\nspecifically in the "Policy to Miniscript compiler". The compiler included in BDK does basically the same job, but produces descriptors for '),s("code",[t._v("rust-miniscript")]),t._v(" that have some minor differences from\nthe ones made by the C++ implementation used in that website.")]),t._v(" "),s("h2",{attrs:{id:"installation"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),s("p",[t._v("To install the miniscript compiler run the following command:")]),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("cargo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/bdk "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--features")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compiler"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--example")]),t._v(" miniscriptc\n")])])]),s("p",[t._v("Once the command is done, you should have a "),s("code",[t._v("miniscriptc")]),t._v(" command available. You can check if that's the case by running "),s("code",[t._v("miniscriptc --help")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"usage"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#usage"}},[t._v("#")]),t._v(" Usage")]),t._v(" "),s("p",[t._v('In this case the interface is very simple: it accepts two arguments called "POLICY" and "TYPE", in this order. The first one, as the name implies, sets the spending policy to compile. The latter defines the type\nof address that should be used to encapsulate the produced script, like a P2SH, P2WSH, etc.')]),t._v(" "),s("p",[t._v("Optionally, the "),s("code",[t._v("--parsed_policy")]),t._v(' flag can be enabled and it will make the compiler print the JSON "human-readable" version of the spending policy, as described in the '),s("RouterLink",{attrs:{to:"/bdk-cli/interface/#policies"}},[s("code",[t._v("policies subcommand")])]),t._v(" of the CLI.")],1),t._v(" "),s("p",[t._v("The "),s("code",[t._v("--network")]),t._v(" flag can be used to change the network encoding of the address shown.")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("Tip")]),t._v(" "),s("p",[t._v("Keep in mind that since the compiler loads and interprets the descriptor, all the public keys specified in the policy must be valid public keys. This differs from the web tool linked above that also accepts\nplaceholders too. As described in the previous sections of this guide, the keys can be either "),s("code",[t._v("xpub")]),t._v("/"),s("code",[t._v("xprv")]),t._v(" with or without metadata and a derivation path, WIF keys or raw hex public keys.")])]),t._v(" "),s("h2",{attrs:{id:"example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example"}},[t._v("#")]),t._v(" Example")]),t._v(" "),s("p",[t._v("Let's take this policy for example:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("miniscriptc "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--parsed_policy")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"and(pk(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR),or(50@pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c),older(1000)))"')]),t._v(" sh-wsh\n")])])]),s("p",[t._v("The compiler should print something like:")]),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 punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2020")]),t._v("-04-29T10:42:05Z INFO miniscriptc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" Compiling policy: and"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",or"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),t._v("@pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",older"),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(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2020")]),t._v("-04-29T10:42:05Z INFO miniscriptc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". Descriptor: sh"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wsh"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("and_v"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("or_c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c:pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(",v:older"),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("))")]),t._v(",c:pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR"),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 number"}},[t._v("2020")]),t._v("-04-29T10:42:05Z INFO miniscriptc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v(". First address: 2MsqrJuZewY3o3ADAy1Uhi5vsBqTANjH3Cf\n")])])]),s("p",[t._v("JSON policy:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"THRESH"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"items"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"THRESH"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"items"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SIGNATURE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"pubkey"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RELATIVETIMELOCK"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"value"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"COMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"condition"')]),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 property"}},[t._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),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("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 property"}},[t._v('"threshold"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[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 property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIALCOMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"n"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"m"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[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 property"}},[t._v('"items"')]),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 number"}},[t._v("1")]),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 property"}},[t._v('"conditions"')]),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 property"}},[t._v('"[1]"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),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("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 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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SIGNATURE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"pubkey"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"COMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"condition"')]),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 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("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 property"}},[t._v('"threshold"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"satisfaction"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NONE"')]),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 property"}},[t._v('"contribution"')]),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 property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PARTIALCOMPLETE"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"n"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"m"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"items"')]),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 number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),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 property"}},[t._v('"conditions"')]),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 property"}},[t._v('"[0, 1]"')]),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 punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"csv"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),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("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("h2",{attrs:{id:"troubleshooting"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#troubleshooting"}},[t._v("#")]),t._v(" Troubleshooting")]),t._v(" "),s("h4",{attrs:{id:"nothing-is-printed"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#nothing-is-printed"}},[t._v("#")]),t._v(" Nothing is printed")]),t._v(" "),s("p",[t._v("This might mean that you have a "),s("code",[t._v("RUST_LOG")]),t._v(" variable set to a value that suppresses the compiler's log. You can try adding "),s("code",[t._v("miniscriptc=info")]),t._v(" to your "),s("code",[t._v("RUST_LOG")]),t._v(" value and see if that works, or open a new clean\nshell.")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/70.42bd691e.js b/assets/js/70.c2fb4c8e.js similarity index 98% rename from assets/js/70.42bd691e.js rename to assets/js/70.c2fb4c8e.js index bdb14e5ecf..3e8ea4f155 100644 --- a/assets/js/70.42bd691e.js +++ b/assets/js/70.c2fb4c8e.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[70],{420: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("h1",{attrs:{id:"concept"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#concept"}},[e._v("#")]),e._v(" Concept")]),e._v(" "),t("p",[e._v("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.")]),e._v(" "),t("p",[e._v("BDK is aiming first of all to be a "),t("strong",[e._v("set of libraries and tools")]),e._v(", all meant to be very reusable and adaptable. Developers working on their own wallets or other projects that are trying to integrate\nBitcoin can pick the tools they need and piece them together to prototype and quickly ship a working product. This means that the "),t("code",[e._v("bdk-cli")]),e._v(" that we've just installed is designed to be a "),t("strong",[e._v("very thin layer")]),e._v(" over the\nAPIs exposed by the various components of the library, "),t("strong",[e._v("not a full, end-user-ready Bitcoin wallet")]),e._v(".")]),e._v(" "),t("p",[e._v('This concept leads to a few design choices that are arguably very bad for the "UX" of this wallet, but that allow developers to work more directly with the underlying library. For instance:')]),e._v(" "),t("ul",[t("li",[e._v("BDK has an internal database that's used to store data about received transactions, spendable UTXOs, etc. This database is stored by default in your home folder, in "),t("code",[e._v("~/.bdk-bitcoin")]),e._v(". The database\n"),t("strong",[e._v("will never")]),e._v(" contain any data that can't be recreated purely by looking at the blockchain. Keys, descriptors, Electrum endpoints "),t("strong",[e._v("are not stored in the database")]),e._v(". This explains why you'll have to specify them every\ntime in the command line. It can be seen more like a "),t("em",[e._v("cache")]),e._v(" and can be safely deleted without risking funds.")]),e._v(" "),t("li",[e._v("BDK doesn't automatically \"monitor\" the blockchain, instead there's a "),t("code",[e._v("sync")]),e._v(" command that has to be called by the user.")]),e._v(" "),t("li",[e._v("When you create a transaction and then sign it, it's not automatically broadcast to the network. There's a "),t("code",[e._v("broadcast")]),e._v(" command that does this. Moreover, the command doesn't accept a normal Bitcoin raw transaction,\nbut instead a "),t("em",[e._v("PSBT")]),e._v(". That's because internally transactions are always moved as PSBTs, and again, the "),t("code",[e._v("broadcast")]),e._v(" command is just a very thin wrapper over the raw library call.")])]),e._v(" "),t("p",[e._v("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\nto understand, and that's absolutely normal. Just try to survive through the pain and you'll be rewarded!")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[70],{421: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("h1",{attrs:{id:"concept"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#concept"}},[e._v("#")]),e._v(" Concept")]),e._v(" "),t("p",[e._v("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.")]),e._v(" "),t("p",[e._v("BDK is aiming first of all to be a "),t("strong",[e._v("set of libraries and tools")]),e._v(", all meant to be very reusable and adaptable. Developers working on their own wallets or other projects that are trying to integrate\nBitcoin can pick the tools they need and piece them together to prototype and quickly ship a working product. This means that the "),t("code",[e._v("bdk-cli")]),e._v(" that we've just installed is designed to be a "),t("strong",[e._v("very thin layer")]),e._v(" over the\nAPIs exposed by the various components of the library, "),t("strong",[e._v("not a full, end-user-ready Bitcoin wallet")]),e._v(".")]),e._v(" "),t("p",[e._v('This concept leads to a few design choices that are arguably very bad for the "UX" of this wallet, but that allow developers to work more directly with the underlying library. For instance:')]),e._v(" "),t("ul",[t("li",[e._v("BDK has an internal database that's used to store data about received transactions, spendable UTXOs, etc. This database is stored by default in your home folder, in "),t("code",[e._v("~/.bdk-bitcoin")]),e._v(". The database\n"),t("strong",[e._v("will never")]),e._v(" contain any data that can't be recreated purely by looking at the blockchain. Keys, descriptors, Electrum endpoints "),t("strong",[e._v("are not stored in the database")]),e._v(". This explains why you'll have to specify them every\ntime in the command line. It can be seen more like a "),t("em",[e._v("cache")]),e._v(" and can be safely deleted without risking funds.")]),e._v(" "),t("li",[e._v("BDK doesn't automatically \"monitor\" the blockchain, instead there's a "),t("code",[e._v("sync")]),e._v(" command that has to be called by the user.")]),e._v(" "),t("li",[e._v("When you create a transaction and then sign it, it's not automatically broadcast to the network. There's a "),t("code",[e._v("broadcast")]),e._v(" command that does this. Moreover, the command doesn't accept a normal Bitcoin raw transaction,\nbut instead a "),t("em",[e._v("PSBT")]),e._v(". That's because internally transactions are always moved as PSBTs, and again, the "),t("code",[e._v("broadcast")]),e._v(" command is just a very thin wrapper over the raw library call.")])]),e._v(" "),t("p",[e._v("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\nto understand, and that's absolutely normal. Just try to survive through the pain and you'll be rewarded!")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/71.2b84faa7.js b/assets/js/71.12dfcc1e.js similarity index 99% rename from assets/js/71.2b84faa7.js rename to assets/js/71.12dfcc1e.js index e5ac6b6ee1..ec2bcad114 100644 --- a/assets/js/71.2b84faa7.js +++ b/assets/js/71.12dfcc1e.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[71],{421: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("h1",{attrs:{id:"installation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),e("h2",{attrs:{id:"requirements"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#requirements"}},[t._v("#")]),t._v(" Requirements")]),t._v(" "),e("p",[t._v("The only requirement to run the "),e("code",[t._v("bdk-cli")]),t._v(" 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 "),e("a",{attrs:{href:"https://rustup.rs/",target:"_blank",rel:"noopener noreferrer"}},[t._v("rustup.rs"),e("OutboundLink")],1),t._v(". You can head there and\nfollow their instructions, after which you can test if everything went fine by running\n"),e("code",[t._v("cargo version")]),t._v(", which should print something like:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("cargo 1.56.0 (4ed5d137b 2021-10-04)\n")])])]),e("p",[t._v("As an alternative to installing the Rust toolchain, you can try using a\n"),e("a",{attrs:{href:"https://hub.docker.com/_/rust",target:"_blank",rel:"noopener noreferrer"}},[t._v("Docker image"),e("OutboundLink")],1),t._v(" and working inside of it, but that's meant for more\nadvanced users and won't be covered in this guide.")]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("At the time of writing, the project requires cargo >= 1.56.0, which is our minimum supported rust version (MSRV) as of May 2022. If you have an older version installed with rustup.rs, you can upgrade it with "),e("code",[t._v("rustup update")]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"installing-the-bdk-cli-tool"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#installing-the-bdk-cli-tool"}},[t._v("#")]),t._v(" Installing the "),e("code",[t._v("bdk-cli")]),t._v(" tool")]),t._v(" "),e("p",[t._v("Once Cargo is installed, you can proceed to install the interactive "),e("code",[t._v("bdk-cli")]),t._v(" tool directly from\nthe GitHub repository, by running:")]),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("# all features with the blocking esplora client ")]),t._v("\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(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/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("esplora-ureq,compiler\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# all features with the async esplora client ")]),t._v("\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(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/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("esplora-reqwest,compiler\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# minimal install (only repl feature is on by default)")]),t._v("\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(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/bdk-cli\n")])])]),e("p",[t._v("This command may take a while to finish, since it will fetch and compile all the dependencies and the "),e("code",[t._v("bdk")]),t._v(" library itself.")]),t._v(" "),e("p",[t._v("Once it's done, you can check if everything went fine by running "),e("code",[t._v("bdk-cli --help")]),t._v(" which should print something like this:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("bdk-cli 0.5.0\nAlekos Filini :Riccardo Casatta :Steve Myers \nThe BDK Command Line Wallet App\n\nbdk-cli is a light weight command 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 in 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!\n\n\nUSAGE:\n bdk-cli [OPTIONS] \n\nFLAGS:\n -h, --help \n Prints help information\n\n -V, --version \n Prints version information\n\n\nOPTIONS:\n -n, --network \n Sets the network [default: testnet]\n\n\nSUBCOMMANDS:\n compile Compile a miniscript policy to an output descriptor\n help Prints this message or the help of the given subcommand(s)\n key Key Management Operations\n repl REPL command loop mode\n wallet Wallet Operations\n\n")])])]),e("p",[t._v("An example command to sync a testnet wallet to a default electrum server looks like this:")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[t._v("bdk-cli wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-w")]),t._v(" example "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--descriptor")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh(tprv8ZgxMBicQKsPexGYyaFwnAsCXCjmz2FaTm6LtesyyihjbQE3gRMfXqQBXKM43DvC1UgRVv1qom1qFxNMSqVAs88qx9PhgFnfGVUdiiDf6j4/0/*)"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n")])])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[71],{419: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("h1",{attrs:{id:"installation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),e("h2",{attrs:{id:"requirements"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#requirements"}},[t._v("#")]),t._v(" Requirements")]),t._v(" "),e("p",[t._v("The only requirement to run the "),e("code",[t._v("bdk-cli")]),t._v(" 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 "),e("a",{attrs:{href:"https://rustup.rs/",target:"_blank",rel:"noopener noreferrer"}},[t._v("rustup.rs"),e("OutboundLink")],1),t._v(". You can head there and\nfollow their instructions, after which you can test if everything went fine by running\n"),e("code",[t._v("cargo version")]),t._v(", which should print something like:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("cargo 1.56.0 (4ed5d137b 2021-10-04)\n")])])]),e("p",[t._v("As an alternative to installing the Rust toolchain, you can try using a\n"),e("a",{attrs:{href:"https://hub.docker.com/_/rust",target:"_blank",rel:"noopener noreferrer"}},[t._v("Docker image"),e("OutboundLink")],1),t._v(" and working inside of it, but that's meant for more\nadvanced users and won't be covered in this guide.")]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Note")]),t._v(" "),e("p",[t._v("At the time of writing, the project requires cargo >= 1.56.0, which is our minimum supported rust version (MSRV) as of May 2022. If you have an older version installed with rustup.rs, you can upgrade it with "),e("code",[t._v("rustup update")]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"installing-the-bdk-cli-tool"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#installing-the-bdk-cli-tool"}},[t._v("#")]),t._v(" Installing the "),e("code",[t._v("bdk-cli")]),t._v(" tool")]),t._v(" "),e("p",[t._v("Once Cargo is installed, you can proceed to install the interactive "),e("code",[t._v("bdk-cli")]),t._v(" tool directly from\nthe GitHub repository, by running:")]),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("# all features with the blocking esplora client ")]),t._v("\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(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/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("esplora-ureq,compiler\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# all features with the async esplora client ")]),t._v("\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(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/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("esplora-reqwest,compiler\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# minimal install (only repl feature is on by default)")]),t._v("\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(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--git")]),t._v(" https://github.com/bitcoindevkit/bdk-cli\n")])])]),e("p",[t._v("This command may take a while to finish, since it will fetch and compile all the dependencies and the "),e("code",[t._v("bdk")]),t._v(" library itself.")]),t._v(" "),e("p",[t._v("Once it's done, you can check if everything went fine by running "),e("code",[t._v("bdk-cli --help")]),t._v(" which should print something like this:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("bdk-cli 0.5.0\nAlekos Filini :Riccardo Casatta :Steve Myers \nThe BDK Command Line Wallet App\n\nbdk-cli is a light weight command 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 in 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!\n\n\nUSAGE:\n bdk-cli [OPTIONS] \n\nFLAGS:\n -h, --help \n Prints help information\n\n -V, --version \n Prints version information\n\n\nOPTIONS:\n -n, --network \n Sets the network [default: testnet]\n\n\nSUBCOMMANDS:\n compile Compile a miniscript policy to an output descriptor\n help Prints this message or the help of the given subcommand(s)\n key Key Management Operations\n repl REPL command loop mode\n wallet Wallet Operations\n\n")])])]),e("p",[t._v("An example command to sync a testnet wallet to a default electrum server looks like this:")]),t._v(" "),e("div",{staticClass:"language-bash extra-class"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[t._v("bdk-cli wallet "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-w")]),t._v(" example "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--descriptor")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh(tprv8ZgxMBicQKsPexGYyaFwnAsCXCjmz2FaTm6LtesyyihjbQE3gRMfXqQBXKM43DvC1UgRVv1qom1qFxNMSqVAs88qx9PhgFnfGVUdiiDf6j4/0/*)"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),t._v("\n")])])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/76.2c842c7e.js b/assets/js/76.f9c90561.js similarity index 99% rename from assets/js/76.2c842c7e.js rename to assets/js/76.f9c90561.js index 135fd4e762..487bf4bd66 100644 --- a/assets/js/76.2c842c7e.js +++ b/assets/js/76.f9c90561.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[76],{425:function(t,a,s){"use strict";s.r(a);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",{staticClass:"more-cases-heading"},[t._v("\n Meet the projects building with BDK\n")]),t._v(" "),a("CodeSwitcher",{attrs:{languages:{all:"All",mobile:"Mobile",desktop:"Desktop",hardware:"Hardware",web:"Web",custodial:"Custodial",exchange:"Exchange",infra:"Infrastructure"}},scopedSlots:t._u([{key:"mobile",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("h3",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("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.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://peachbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})]),t._v(" "),a("h3",[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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/stackmate-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[t._v("Stackmate")])]),t._v(" "),a("p",[t._v("A multi-purpose Bitcoin Wallet.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"exchange",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"desktop",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/anchorwatch-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[t._v("AnchorWatch")])]),t._v(" "),a("p",[t._v("Protect your bitcoin with regulated insurance and enterprise-grade multi-institutional custody.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"hardware",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("h3",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("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.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"custodial",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/seba-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[t._v("Seba Bank")])]),t._v(" "),a("p",[t._v("From everyday banking to crypto custody and trading, get the most out of your assets with a regulated global crypto bank.")])])])]},proxy:!0},{key:"infra",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"web",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"all",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("h3",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("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.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})]),t._v(" "),a("h3",[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:"case-study-item"},[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/anchorwatch-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[t._v("AnchorWatch")])]),t._v(" "),a("p",[t._v("Protect your bitcoin with regulated insurance and enterprise-grade multi-institutional custody.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/seba-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[t._v("Seba Bank")])]),t._v(" "),a("p",[t._v("From everyday banking to crypto custody and trading, get the most out of your assets with a regulated global crypto bank.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/stackmate-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[t._v("Stackmate")])]),t._v(" "),a("p",[t._v("A multi-purpose Bitcoin Wallet.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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.")])])])]},proxy:!0}])})],1)}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[76],{426:function(t,a,s){"use strict";s.r(a);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",{staticClass:"more-cases-heading"},[t._v("\n Meet the projects building with BDK\n")]),t._v(" "),a("CodeSwitcher",{attrs:{languages:{all:"All",mobile:"Mobile",desktop:"Desktop",hardware:"Hardware",web:"Web",custodial:"Custodial",exchange:"Exchange",infra:"Infrastructure"}},scopedSlots:t._u([{key:"mobile",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("h3",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("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.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://peachbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})]),t._v(" "),a("h3",[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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/stackmate-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[t._v("Stackmate")])]),t._v(" "),a("p",[t._v("A multi-purpose Bitcoin Wallet.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"exchange",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"desktop",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/anchorwatch-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[t._v("AnchorWatch")])]),t._v(" "),a("p",[t._v("Protect your bitcoin with regulated insurance and enterprise-grade multi-institutional custody.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"hardware",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("h3",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("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.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"custodial",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/seba-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[t._v("Seba Bank")])]),t._v(" "),a("p",[t._v("From everyday banking to crypto custody and trading, get the most out of your assets with a regulated global crypto bank.")])])])]},proxy:!0},{key:"infra",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"web",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})]),t._v(" "),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.")])])])]},proxy:!0},{key:"all",fn:function(){return[a("div",{staticClass:"case-studies"},[a("div",{staticClass:"case-study-item"},[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("h3",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("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.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})]),t._v(" "),a("h3",[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:"case-study-item"},[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/anchorwatch-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[t._v("AnchorWatch")])]),t._v(" "),a("p",[t._v("Protect your bitcoin with regulated insurance and enterprise-grade multi-institutional custody.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/seba-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://www.seba.swiss/",target:"_blank"}},[t._v("Seba Bank")])]),t._v(" "),a("p",[t._v("From everyday banking to crypto custody and trading, get the most out of your assets with a regulated global crypto bank.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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:"case-study-item"},[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("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:"case-study-item"},[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/stackmate-130.png"}})]),t._v(" "),a("h3",[a("a",{attrs:{href:"https://github.com/StackmateNetwork",target:"_blank"}},[t._v("Stackmate")])]),t._v(" "),a("p",[t._v("A multi-purpose Bitcoin Wallet.")])]),t._v(" "),a("div",{staticClass:"case-study-item"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})]),t._v(" "),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:"case-study-item"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})]),t._v(" "),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:"case-study-item"},[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("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.")])])])]},proxy:!0}])})],1)}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/77.1bd88a81.js b/assets/js/77.1cad2d43.js similarity index 99% rename from assets/js/77.1bd88a81.js rename to assets/js/77.1cad2d43.js index c4b1dcfb59..b5147515e0 100644 --- a/assets/js/77.1bd88a81.js +++ b/assets/js/77.1cad2d43.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[77],{426:function(t,v,e){"use strict";e.r(v);var _=e(7),r=Object(_.a)({},(function(){var t=this,v=t._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[v("h1",{attrs:{id:"descriptors"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[t._v("#")]),t._v(" Descriptors")]),t._v(" "),v("p",[t._v('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.')]),t._v(" "),v("p",[t._v("The ecosystem around descriptors is still very much in its early stage, but they are starting to see some adoption in "),v("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Core"),v("OutboundLink")],1),t._v(' and other projects. BDK\naims to produce the first "Native Descriptor" Bitcoin library that can be used by developers to build their own '),v("a",{attrs:{href:"https://www.youtube.com/watch?v=xC25NzIjzog",target:"_blank",rel:"noopener noreferrer"}},[t._v('"Native Descriptor Wallets"'),v("OutboundLink")],1),t._v(".")]),t._v(" "),v("h3",{attrs:{id:"compatibility-matrix"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#compatibility-matrix"}},[t._v("#")]),t._v(" Compatibility Matrix")]),t._v(" "),v("p",[t._v("Below are some tables to highlight the differences between Bitcoin Core's descriptor support, rust-miniscript's one and BDK's.")]),t._v(" "),v("h4",{attrs:{id:"key-types"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#key-types"}},[t._v("#")]),t._v(" Key Types")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Key Type")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[t._v("Hex PublicKey")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[t._v("WIF PrivateKey")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[t._v("Extended Keys (xpub/xprv)")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])])])])]),t._v(" "),v("h4",{attrs:{id:"script-types-top-level"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#script-types-top-level"}},[t._v("#")]),t._v(" Script Types (top level)")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Script Type")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[v("code",[t._v("pk()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("pkh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("wpkh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sh(wpkh())")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("wsh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sh(wsh())")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("combo()")])]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("addr()")])]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("raw()")])]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[t._v("Bare scripts")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✗")])])])])]),t._v(" "),v("h4",{attrs:{id:"operators"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#operators"}},[t._v("#")]),t._v(" Operators")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Operator")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[v("code",[t._v("pk()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("pkh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("older()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("after()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sha256()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("hash256()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("ripemd160()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("hash160()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("andor()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("and_{v,b,n}()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("or_{b,c,d,i}()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("multi()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("thresh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sortedmulti()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])])])])]),t._v(" "),v("h4",{attrs:{id:"modifiers"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#modifiers"}},[t._v("#")]),t._v(" Modifiers")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Script Type")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[v("code",[t._v("a:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("s:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("c:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("t:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("d:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("v:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("j:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("n:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("l:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("u:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])])])])]),t._v(" "),v("p",[t._v("For a more thorough description of these operators and modifiers see "),v("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sipa's Miniscript Page"),v("OutboundLink")],1),t._v(" and "),v("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Core's"),v("OutboundLink")],1),t._v(".")]),t._v(" "),v("h3",{attrs:{id:"examples"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[t._v("#")]),t._v(" Examples")]),t._v(" "),v("p",[t._v("Some examples of valid BDK descriptors are:")]),t._v(" "),v("div",{staticClass:"descriptor-examples-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Spending Policy")]),t._v(" "),v("th",[t._v("Descriptor")]),t._v(" "),v("th",[t._v("Address 0")]),t._v(" "),v("th",[t._v("Address 1")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[t._v("Static P2PKH")]),t._v(" "),v("td",[v("code",[t._v("pkh(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR)")])]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")])]),t._v(" "),v("tr",[v("td",[t._v("Static P2PKH, watch-only")]),t._v(" "),v("td",[v("code",[t._v("pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)")])]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")])]),t._v(" "),v("tr",[v("td",[t._v("P2WSH 2-of-2 with one private key")]),t._v(" "),v("td",[v("code",[t._v("wsh(multi(2,tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*,tpubDBYDcH8P2PedrEN3HxWYJJJMZEdgnrqMsjeKpPNzwe7jmGwk5M3HRdSf5vudAXwrJPfUsfvUPFooKWmz79Lh111U51RNotagXiGNeJe3i6t/1/*))")])]),t._v(" "),v("td",[t._v("tb1qqsat6c82fvdy73rfzye8f7nwxcz3xny7t56azl73g95mt3tmzvgs9a8vjs")]),t._v(" "),v("td",[t._v("tb1q7sgx6gscgtau57jduend6a8l445ahpk3dt3u5zu58rx5qm27lhkqgfdjdr")])]),t._v(" "),v("tr",[v("td",[t._v("P2WSH-P2SH one key + 10 days timelock")]),t._v(" "),v("td",[v("code",[t._v("sh(wsh(and_v(vc:pk_h(tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*),older(1440))))")])]),t._v(" "),v("td",[t._v("2Mtk2nyS98MCi2P7TkoBGLaJviBy956XxB1")]),t._v(" "),v("td",[t._v("2MuEStKzYhqb5HCFgHz9153tZsL5sVqV5xC")])])])])]),t._v(" "),v("h3",{attrs:{id:"implementation-details"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#implementation-details"}},[t._v("#")]),t._v(" Implementation Details")]),t._v(" "),v("p",[t._v("BDK extends the capabilities of "),v("a",{attrs:{href:"https://github.com/apoelstra/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[t._v("rust-miniscript"),v("OutboundLink")],1),t._v(" by introducing the concept of an "),v("em",[t._v("ExtendedDescriptor")]),t._v(': it represents a descriptor that contains one or more "derivable keys" like '),v("code",[t._v("xpubs")]),t._v(" or "),v("code",[t._v("xprvs")]),t._v('\nand can be "derived" from a normal Descriptor by deriving every single one of its keys. It is currently called "StringDescriptor" in the code, because it\'s implemented as a wrapped '),v("code",[t._v("miniscript::Descriptor")]),t._v(".")]),t._v(" "),v("p",[t._v("ExtendedDescriptors are derived using a single index instead of a full derivation path: this is because normally most of the path is fixed and can be represented right after the xpub/xprv itself, and only the\nfinal index changes for each address. This is what's normally called a "),v("em",[t._v("DescriptorExtendedKey")]),t._v(" in the codebase, it is represented with a similar syntax to Bitcoin Core's, such as:")]),t._v(" "),v("div",{staticClass:"language- extra-class"},[v("pre",{pre:!0,attrs:{class:"language-text"}},[v("code",[t._v("[d34db33f/44'/0'/0']xpub6ERApfZwUNrhL.......rBGRjaDMzQLcgJvLJuZZvRcEL/0/*\n")])])])])}),[],!1,null,null,null);v.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[77],{425:function(t,v,e){"use strict";e.r(v);var _=e(7),r=Object(_.a)({},(function(){var t=this,v=t._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[v("h1",{attrs:{id:"descriptors"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[t._v("#")]),t._v(" Descriptors")]),t._v(" "),v("p",[t._v('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.')]),t._v(" "),v("p",[t._v("The ecosystem around descriptors is still very much in its early stage, but they are starting to see some adoption in "),v("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Core"),v("OutboundLink")],1),t._v(' and other projects. BDK\naims to produce the first "Native Descriptor" Bitcoin library that can be used by developers to build their own '),v("a",{attrs:{href:"https://www.youtube.com/watch?v=xC25NzIjzog",target:"_blank",rel:"noopener noreferrer"}},[t._v('"Native Descriptor Wallets"'),v("OutboundLink")],1),t._v(".")]),t._v(" "),v("h3",{attrs:{id:"compatibility-matrix"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#compatibility-matrix"}},[t._v("#")]),t._v(" Compatibility Matrix")]),t._v(" "),v("p",[t._v("Below are some tables to highlight the differences between Bitcoin Core's descriptor support, rust-miniscript's one and BDK's.")]),t._v(" "),v("h4",{attrs:{id:"key-types"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#key-types"}},[t._v("#")]),t._v(" Key Types")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Key Type")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[t._v("Hex PublicKey")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[t._v("WIF PrivateKey")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[t._v("Extended Keys (xpub/xprv)")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])])])])]),t._v(" "),v("h4",{attrs:{id:"script-types-top-level"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#script-types-top-level"}},[t._v("#")]),t._v(" Script Types (top level)")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Script Type")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[v("code",[t._v("pk()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("pkh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("wpkh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sh(wpkh())")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("wsh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sh(wsh())")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("combo()")])]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("addr()")])]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("raw()")])]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✗")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[t._v("Bare scripts")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✗")])])])])]),t._v(" "),v("h4",{attrs:{id:"operators"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#operators"}},[t._v("#")]),t._v(" Operators")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Operator")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[v("code",[t._v("pk()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("pkh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("older()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("after()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sha256()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("hash256()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("ripemd160()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("hash160()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("andor()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("and_{v,b,n}()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("or_{b,c,d,i}()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("multi()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("thresh()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("sortedmulti()")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])])])])]),t._v(" "),v("h4",{attrs:{id:"modifiers"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#modifiers"}},[t._v("#")]),t._v(" Modifiers")]),t._v(" "),v("div",{staticClass:"descriptor-support-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Script Type")]),t._v(" "),v("th",[t._v("BDK")]),t._v(" "),v("th",[t._v("rust-miniscript")]),t._v(" "),v("th",[t._v("Bitcoin Core")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[v("code",[t._v("a:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("s:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("c:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("t:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("d:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("v:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("j:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("n:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("l:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])]),t._v(" "),v("tr",[v("td",[v("code",[t._v("u:")])]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")]),t._v(" "),v("td",[t._v("✓")])])])])]),t._v(" "),v("p",[t._v("For a more thorough description of these operators and modifiers see "),v("a",{attrs:{href:"http://bitcoin.sipa.be/miniscript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sipa's Miniscript Page"),v("OutboundLink")],1),t._v(" and "),v("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Core's"),v("OutboundLink")],1),t._v(".")]),t._v(" "),v("h3",{attrs:{id:"examples"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[t._v("#")]),t._v(" Examples")]),t._v(" "),v("p",[t._v("Some examples of valid BDK descriptors are:")]),t._v(" "),v("div",{staticClass:"descriptor-examples-table"},[v("table",[v("thead",[v("tr",[v("th",[t._v("Spending Policy")]),t._v(" "),v("th",[t._v("Descriptor")]),t._v(" "),v("th",[t._v("Address 0")]),t._v(" "),v("th",[t._v("Address 1")])])]),t._v(" "),v("tbody",[v("tr",[v("td",[t._v("Static P2PKH")]),t._v(" "),v("td",[v("code",[t._v("pkh(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR)")])]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")])]),t._v(" "),v("tr",[v("td",[t._v("Static P2PKH, watch-only")]),t._v(" "),v("td",[v("code",[t._v("pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)")])]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")]),t._v(" "),v("td",[t._v("mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr")])]),t._v(" "),v("tr",[v("td",[t._v("P2WSH 2-of-2 with one private key")]),t._v(" "),v("td",[v("code",[t._v("wsh(multi(2,tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*,tpubDBYDcH8P2PedrEN3HxWYJJJMZEdgnrqMsjeKpPNzwe7jmGwk5M3HRdSf5vudAXwrJPfUsfvUPFooKWmz79Lh111U51RNotagXiGNeJe3i6t/1/*))")])]),t._v(" "),v("td",[t._v("tb1qqsat6c82fvdy73rfzye8f7nwxcz3xny7t56azl73g95mt3tmzvgs9a8vjs")]),t._v(" "),v("td",[t._v("tb1q7sgx6gscgtau57jduend6a8l445ahpk3dt3u5zu58rx5qm27lhkqgfdjdr")])]),t._v(" "),v("tr",[v("td",[t._v("P2WSH-P2SH one key + 10 days timelock")]),t._v(" "),v("td",[v("code",[t._v("sh(wsh(and_v(vc:pk_h(tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*),older(1440))))")])]),t._v(" "),v("td",[t._v("2Mtk2nyS98MCi2P7TkoBGLaJviBy956XxB1")]),t._v(" "),v("td",[t._v("2MuEStKzYhqb5HCFgHz9153tZsL5sVqV5xC")])])])])]),t._v(" "),v("h3",{attrs:{id:"implementation-details"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#implementation-details"}},[t._v("#")]),t._v(" Implementation Details")]),t._v(" "),v("p",[t._v("BDK extends the capabilities of "),v("a",{attrs:{href:"https://github.com/apoelstra/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[t._v("rust-miniscript"),v("OutboundLink")],1),t._v(" by introducing the concept of an "),v("em",[t._v("ExtendedDescriptor")]),t._v(': it represents a descriptor that contains one or more "derivable keys" like '),v("code",[t._v("xpubs")]),t._v(" or "),v("code",[t._v("xprvs")]),t._v('\nand can be "derived" from a normal Descriptor by deriving every single one of its keys. It is currently called "StringDescriptor" in the code, because it\'s implemented as a wrapped '),v("code",[t._v("miniscript::Descriptor")]),t._v(".")]),t._v(" "),v("p",[t._v("ExtendedDescriptors are derived using a single index instead of a full derivation path: this is because normally most of the path is fixed and can be represented right after the xpub/xprv itself, and only the\nfinal index changes for each address. This is what's normally called a "),v("em",[t._v("DescriptorExtendedKey")]),t._v(" in the codebase, it is represented with a similar syntax to Bitcoin Core's, such as:")]),t._v(" "),v("div",{staticClass:"language- extra-class"},[v("pre",{pre:!0,attrs:{class:"language-text"}},[v("code",[t._v("[d34db33f/44'/0'/0']xpub6ERApfZwUNrhL.......rBGRjaDMzQLcgJvLJuZZvRcEL/0/*\n")])])])])}),[],!1,null,null,null);v.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/79.bf24138b.js b/assets/js/79.210c655a.js similarity index 97% rename from assets/js/79.bf24138b.js rename to assets/js/79.210c655a.js index 080d39e13a..4c480b4301 100644 --- a/assets/js/79.bf24138b.js +++ b/assets/js/79.210c655a.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[79],{429:function(e,t,o){"use strict";o.r(t);var i=o(7),a=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"bitcoin-dev-kit-foundation"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-foundation"}},[e._v("#")]),e._v(" Bitcoin Dev Kit Foundation")]),e._v(" "),t("p",[e._v("The Bitcoin Dev Kit Foundation (EIN 93-2023051) 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. The Foundation is organized and operated exclusively for charitable, educational, and scientific purposes within the meaning of 501c(3) of the Internal Revenue Code.")]),e._v(" "),t("p",[e._v("The Foundation aims to achieve this mission by funding the developers who contribute to and maintain the Bitcoin Dev Kit software libraries, documentation, and related infrastructure. We independently raise funds on behalf of the development team, and recruit for, fund, and operate the grant program.")]),e._v(" "),t("h2",{attrs:{id:"board"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#board"}},[e._v("#")]),e._v(" Board")]),e._v(" "),t("p",[e._v("The current BDK Foundation board is made up of five directors. The board members are all unpaid volunteer positions. All board members are long-time contributors and supporters of the BDK project:")]),e._v(" "),t("ul",[t("li",[e._v("Riccardo Casatta")]),e._v(" "),t("li",[e._v("Alekos Filini")]),e._v(" "),t("li",[e._v("Lloyd Fournier")]),e._v(" "),t("li",[e._v("Steve Lee")]),e._v(" "),t("li",[e._v("Steve Myers")])]),e._v(" "),t("h2",{attrs:{id:"operations"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#operations"}},[e._v("#")]),e._v(" Operations")]),e._v(" "),t("p",[e._v("Our operations team handles the day-to-day operations of the Foundation and reports to the board of directors. Our officers are all also active contributors to the development of the software. The five current officers are:")]),e._v(" "),t("ul",[t("li",[e._v("Steve Myers, President")]),e._v(" "),t("li",[e._v("Daniela Brozzoni, Vice-President")]),e._v(" "),t("li",[e._v("Joe Wood, Treasurer")]),e._v(" "),t("li",[e._v("thunderbiscuit, Secretary")]),e._v(" "),t("li",[e._v("Evan Lin, At-large")])])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[79],{428:function(e,t,o){"use strict";o.r(t);var i=o(7),a=Object(i.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"bitcoin-dev-kit-foundation"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-foundation"}},[e._v("#")]),e._v(" Bitcoin Dev Kit Foundation")]),e._v(" "),t("p",[e._v("The Bitcoin Dev Kit Foundation (EIN 93-2023051) 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. The Foundation is organized and operated exclusively for charitable, educational, and scientific purposes within the meaning of 501c(3) of the Internal Revenue Code.")]),e._v(" "),t("p",[e._v("The Foundation aims to achieve this mission by funding the developers who contribute to and maintain the Bitcoin Dev Kit software libraries, documentation, and related infrastructure. We independently raise funds on behalf of the development team, and recruit for, fund, and operate the grant program.")]),e._v(" "),t("h2",{attrs:{id:"board"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#board"}},[e._v("#")]),e._v(" Board")]),e._v(" "),t("p",[e._v("The current BDK Foundation board is made up of five directors. The board members are all unpaid volunteer positions. All board members are long-time contributors and supporters of the BDK project:")]),e._v(" "),t("ul",[t("li",[e._v("Riccardo Casatta")]),e._v(" "),t("li",[e._v("Alekos Filini")]),e._v(" "),t("li",[e._v("Lloyd Fournier")]),e._v(" "),t("li",[e._v("Steve Lee")]),e._v(" "),t("li",[e._v("Steve Myers")])]),e._v(" "),t("h2",{attrs:{id:"operations"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#operations"}},[e._v("#")]),e._v(" Operations")]),e._v(" "),t("p",[e._v("Our operations team handles the day-to-day operations of the Foundation and reports to the board of directors. Our officers are all also active contributors to the development of the software. The five current officers are:")]),e._v(" "),t("ul",[t("li",[e._v("Steve Myers, President")]),e._v(" "),t("li",[e._v("Daniela Brozzoni, Vice-President")]),e._v(" "),t("li",[e._v("Joe Wood, Treasurer")]),e._v(" "),t("li",[e._v("thunderbiscuit, Secretary")]),e._v(" "),t("li",[e._v("Evan Lin, At-large")])])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/80.9c59a7bc.js b/assets/js/80.79a4d68e.js similarity index 99% rename from assets/js/80.9c59a7bc.js rename to assets/js/80.79a4d68e.js index 4da5cf9ac2..0d1b7fa324 100644 --- a/assets/js/80.9c59a7bc.js +++ b/assets/js/80.79a4d68e.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[80],{428: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("h1",{attrs:{id:"bitcoin-dev-kit"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit"}},[t._v("#")]),t._v(" Bitcoin Dev Kit")]),t._v(" "),a("p",[t._v("The "),a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Dev Kit (BDK)"),a("OutboundLink")],1),t._v(" 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 "),a("em",[t._v("reference implementation")]),t._v(" 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.")]),t._v(" "),a("p",[t._v("The main long-term goal is to concentrate the development efforts of multiple people and companies into one open source and very well reviewed project, instead of dispersing them over multiple closed/semi-closed or\npoorly designed projects.")]),t._v(" "),a("p",[t._v('While some parts of the library are still considered "experimental" (check the docs for more info), the core '),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(" architecture is now considered stable. We still can't commit to keeping this same exact API forever,\nbut we are not expecting to do any major breaking change in that area.")]),t._v(" "),a("p",[t._v("If you want to try out the library for your projects, now it's finally a good time to do it! You can start by checking out the "),a("RouterLink",{attrs:{to:"/getting-started/"}},[t._v('"getting started"')]),t._v(" section in our blog or joining our "),a("a",{attrs:{href:"https://discord.gg/dstn4dQ",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord"),a("OutboundLink")],1),t._v("\nserver to chat with us.")],1),t._v(" "),a("h2",{attrs:{id:"initial-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#initial-configuration"}},[t._v("#")]),t._v(" Initial Configuration")]),t._v(" "),a("p",[t._v("Most Rust projects use Cargo to download and build the libraries the code depends on. To configure BDK package in the "),a("code",[t._v("Cargo.toml")]),t._v(", the following line can be added:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('[dependencies]\nbdk = "0.28.1"\n')])])]),a("p",[t._v("Or it is possible to install only the features that will be used in the project.")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('[dependencies]\nbdk = { version = "0.28.1", default-feature = false, features = ["all-keys", "key-value-db", "rpc"] }\n')])])]),a("p",[t._v("BDK uses a set of "),a("a",{attrs:{href:"https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section",target:"_blank",rel:"noopener noreferrer"}},[t._v("feature flags"),a("OutboundLink")],1),t._v(" to reduce the amount of compiled code by allowing projects to only enable the features they need.")]),t._v(" "),a("p",[t._v("By default, BDK enables two internal features, "),a("code",[t._v("key-value-db")]),t._v(" and "),a("code",[t._v("electrum")]),t._v(".")]),t._v(" "),a("p",[t._v("It is recommended that new users use the default features which will enable basic descriptor wallet functionality. More advanced users can disable the "),a("code",[t._v("default")]),t._v(" features ("),a("code",[t._v("--no-default-features")]),t._v(") and build the BDK library with only the necessary features.")]),t._v(" "),a("p",[t._v("Below is a list of the available feature flags and the additional functionality they provide.")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("all-keys")]),t._v(": all features for working with bitcoin keys")]),t._v(" "),a("li",[a("code",[t._v("async-interface")]),t._v(": async functions in bdk traits")]),t._v(" "),a("li",[a("code",[t._v("keys-bip39")]),t._v(": "),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP-39"),a("OutboundLink")],1),t._v(" mnemonic codes for generating deterministic keys")])]),t._v(" "),a("h2",{attrs:{id:"internal-features"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#internal-features"}},[t._v("#")]),t._v(" Internal Features")]),t._v(" "),a("p",[t._v("These features do not expose any new API, but influence internal implementation aspects of BDK.")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("compact_filters")]),t._v(": "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/compact_filters/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("compact_filters"),a("OutboundLink")],1),t._v(" client protocol for interacting with the bitcoin P2P network")]),t._v(" "),a("li",[a("code",[t._v("electrum")]),t._v(": "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/electrum/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("electrum"),a("OutboundLink")],1),t._v(" client protocol for interacting with electrum servers")]),t._v(" "),a("li",[a("code",[t._v("esplora")]),t._v(": "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/esplora/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora"),a("OutboundLink")],1),t._v(" client protocol for interacting with blockstream "),a("a",{attrs:{href:"https://github.com/Blockstream/electrs",target:"_blank",rel:"noopener noreferrer"}},[t._v("electrs"),a("OutboundLink")],1),t._v(" servers")]),t._v(" "),a("li",[a("code",[t._v("key-value-db")]),t._v(": key value "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("database"),a("OutboundLink")],1),t._v(" based on "),a("a",{attrs:{href:"https://crates.io/crates/sled",target:"_blank",rel:"noopener noreferrer"}},[t._v("sled"),a("OutboundLink")],1),t._v(" for caching blockchain data")])]),t._v(" "),a("h2",{attrs:{id:"playground"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#playground"}},[t._v("#")]),t._v(" Playground")]),t._v(" "),a("p",[t._v("As a way of demonstrating the flexibility of this project, a minimalistic command line tool (called "),a("code",[t._v("bdk-cli")]),t._v(") is available as a debugging tool in the "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("bdk-cli")]),a("OutboundLink")],1),t._v("\nrepo. It has been compiled to WebAssembly and can be used directly from the browser. See the "),a("a",{attrs:{href:"/bdk-cli/playground"}},[t._v("playground")]),t._v(" section to give it a try!")]),t._v(" "),a("p",[t._v("The playground relies on "),a("a",{attrs:{href:"https://blockstream.info",target:"_blank",rel:"noopener noreferrer"}},[t._v("Esplora"),a("OutboundLink")],1),t._v(" to monitor the blockchain and is currently locked in testnet-only mode, for obvious safety reasons. The native command line tool can also be used in regtest mode when installed on\na computer. See the "),a("a",{attrs:{href:"/bdk-cli"}},[t._v("bdk-cli")]),t._v(" section to learn more.")]),t._v(" "),a("h2",{attrs:{id:"descriptors"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[t._v("#")]),t._v(" Descriptors")]),t._v(" "),a("p",[t._v('One of the original milestones of this project was to provide wallets with "almost magical" support for very complex spending policies, without having to individually translate them into code. It may sound disappointing, but there isn\'t, in fact,\nany real magic in this wallet: the generalization is achieved thanks to '),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[a("em",[t._v("descriptors")]),a("OutboundLink")],1),t._v(", that are now slowly starting to see adoption in a few other Bitcoin projects as well.")]),t._v(" "),a("p",[t._v("The author of this project strongly believes descriptors will be a big part of the future generation of Bitcoin wallets, since they provide a very flexible scripting language that can also be extended as the\ntechnology and tooling of Bitcoin evolves and changes (Schnorr signatures, Taproot, etc).")]),t._v(" "),a("p",[t._v("To learn more, check out the specific "),a("a",{attrs:{href:"/descriptors"}},[t._v("Descriptors section")]),t._v(".")]),t._v(" "),a("p",[t._v("The following code shows how to generate a random mnemonic, the extended (and deterministic) keys from that mnemonic and finally the descriptors from the extended private keys.")]),t._v(" "),a("p",[t._v("To be able to run this code, the "),a("code",[t._v("bdk")]),t._v(" dependency in "),a("code",[t._v("Cargo.toml")]),t._v(" must be set as follows:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('[dependencies]\nbdk = { version = "0.28.1", default-feature = false, features = ["all-keys"] }\n')])])]),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("Network")]),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("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 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("DerivableKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),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("GeneratedKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip39"),a("span",{pre:!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("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),a("span",{pre:!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("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("template"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),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("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("miniscript"),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 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 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("\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('"Hello, world!"')]),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(" network "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),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(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Or this can be Network::Bitcoin, Network::Signet or Network::Regtest")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate fresh mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),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("GeneratedKey")]),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 namespace"}},[t._v("miniscript"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[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 operator"}},[t._v("=")]),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("generate")]),a("span",{pre:!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("WordCount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("English")]),a("span",{pre:!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 function"}},[t._v("unwrap")]),a("span",{pre:!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("// Convert mnemonic to string")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic_words "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),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(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Parse a mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),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("Mnemonic")]),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("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("mnemonic_words"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!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("// Generate the extended key")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_extended_key")]),a("span",{pre:!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 function"}},[t._v("unwrap")]),a("span",{pre:!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("// Get xprv from the extended key")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" xkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_xprv")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!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 comment"}},[t._v('// Create a BDK wallet structure using BIP 84 descriptor ("m/84h/1h/0h/0" and "m/84h/1h/0h/1")')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),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 "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),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 class-name"}},[t._v("Bip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),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 network"),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(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!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 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('"mnemonic: {}\\n\\nrecv desc (pub key): {:#?}\\n\\nchng desc (pub key): {:#?}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n mnemonic_words"),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 function"}},[t._v("get_descriptor_for_keychain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[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(".")]),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(",")]),t._v("\n wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptor_for_keychain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[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 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(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("More information about each component used in the code can be found in "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("BDK Documentation"),a("OutboundLink")],1),t._v(".")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[80],{429: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("h1",{attrs:{id:"bitcoin-dev-kit"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit"}},[t._v("#")]),t._v(" Bitcoin Dev Kit")]),t._v(" "),a("p",[t._v("The "),a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Dev Kit (BDK)"),a("OutboundLink")],1),t._v(" 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 "),a("em",[t._v("reference implementation")]),t._v(" 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.")]),t._v(" "),a("p",[t._v("The main long-term goal is to concentrate the development efforts of multiple people and companies into one open source and very well reviewed project, instead of dispersing them over multiple closed/semi-closed or\npoorly designed projects.")]),t._v(" "),a("p",[t._v('While some parts of the library are still considered "experimental" (check the docs for more info), the core '),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(" architecture is now considered stable. We still can't commit to keeping this same exact API forever,\nbut we are not expecting to do any major breaking change in that area.")]),t._v(" "),a("p",[t._v("If you want to try out the library for your projects, now it's finally a good time to do it! You can start by checking out the "),a("RouterLink",{attrs:{to:"/getting-started/"}},[t._v('"getting started"')]),t._v(" section in our blog or joining our "),a("a",{attrs:{href:"https://discord.gg/dstn4dQ",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord"),a("OutboundLink")],1),t._v("\nserver to chat with us.")],1),t._v(" "),a("h2",{attrs:{id:"initial-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#initial-configuration"}},[t._v("#")]),t._v(" Initial Configuration")]),t._v(" "),a("p",[t._v("Most Rust projects use Cargo to download and build the libraries the code depends on. To configure BDK package in the "),a("code",[t._v("Cargo.toml")]),t._v(", the following line can be added:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('[dependencies]\nbdk = "0.28.1"\n')])])]),a("p",[t._v("Or it is possible to install only the features that will be used in the project.")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('[dependencies]\nbdk = { version = "0.28.1", default-feature = false, features = ["all-keys", "key-value-db", "rpc"] }\n')])])]),a("p",[t._v("BDK uses a set of "),a("a",{attrs:{href:"https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section",target:"_blank",rel:"noopener noreferrer"}},[t._v("feature flags"),a("OutboundLink")],1),t._v(" to reduce the amount of compiled code by allowing projects to only enable the features they need.")]),t._v(" "),a("p",[t._v("By default, BDK enables two internal features, "),a("code",[t._v("key-value-db")]),t._v(" and "),a("code",[t._v("electrum")]),t._v(".")]),t._v(" "),a("p",[t._v("It is recommended that new users use the default features which will enable basic descriptor wallet functionality. More advanced users can disable the "),a("code",[t._v("default")]),t._v(" features ("),a("code",[t._v("--no-default-features")]),t._v(") and build the BDK library with only the necessary features.")]),t._v(" "),a("p",[t._v("Below is a list of the available feature flags and the additional functionality they provide.")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("all-keys")]),t._v(": all features for working with bitcoin keys")]),t._v(" "),a("li",[a("code",[t._v("async-interface")]),t._v(": async functions in bdk traits")]),t._v(" "),a("li",[a("code",[t._v("keys-bip39")]),t._v(": "),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP-39"),a("OutboundLink")],1),t._v(" mnemonic codes for generating deterministic keys")])]),t._v(" "),a("h2",{attrs:{id:"internal-features"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#internal-features"}},[t._v("#")]),t._v(" Internal Features")]),t._v(" "),a("p",[t._v("These features do not expose any new API, but influence internal implementation aspects of BDK.")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("compact_filters")]),t._v(": "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/compact_filters/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("compact_filters"),a("OutboundLink")],1),t._v(" client protocol for interacting with the bitcoin P2P network")]),t._v(" "),a("li",[a("code",[t._v("electrum")]),t._v(": "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/electrum/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("electrum"),a("OutboundLink")],1),t._v(" client protocol for interacting with electrum servers")]),t._v(" "),a("li",[a("code",[t._v("esplora")]),t._v(": "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/blockchain/esplora/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora"),a("OutboundLink")],1),t._v(" client protocol for interacting with blockstream "),a("a",{attrs:{href:"https://github.com/Blockstream/electrs",target:"_blank",rel:"noopener noreferrer"}},[t._v("electrs"),a("OutboundLink")],1),t._v(" servers")]),t._v(" "),a("li",[a("code",[t._v("key-value-db")]),t._v(": key value "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/database/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("database"),a("OutboundLink")],1),t._v(" based on "),a("a",{attrs:{href:"https://crates.io/crates/sled",target:"_blank",rel:"noopener noreferrer"}},[t._v("sled"),a("OutboundLink")],1),t._v(" for caching blockchain data")])]),t._v(" "),a("h2",{attrs:{id:"playground"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#playground"}},[t._v("#")]),t._v(" Playground")]),t._v(" "),a("p",[t._v("As a way of demonstrating the flexibility of this project, a minimalistic command line tool (called "),a("code",[t._v("bdk-cli")]),t._v(") is available as a debugging tool in the "),a("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-cli",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("bdk-cli")]),a("OutboundLink")],1),t._v("\nrepo. It has been compiled to WebAssembly and can be used directly from the browser. See the "),a("a",{attrs:{href:"/bdk-cli/playground"}},[t._v("playground")]),t._v(" section to give it a try!")]),t._v(" "),a("p",[t._v("The playground relies on "),a("a",{attrs:{href:"https://blockstream.info",target:"_blank",rel:"noopener noreferrer"}},[t._v("Esplora"),a("OutboundLink")],1),t._v(" to monitor the blockchain and is currently locked in testnet-only mode, for obvious safety reasons. The native command line tool can also be used in regtest mode when installed on\na computer. See the "),a("a",{attrs:{href:"/bdk-cli"}},[t._v("bdk-cli")]),t._v(" section to learn more.")]),t._v(" "),a("h2",{attrs:{id:"descriptors"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#descriptors"}},[t._v("#")]),t._v(" Descriptors")]),t._v(" "),a("p",[t._v('One of the original milestones of this project was to provide wallets with "almost magical" support for very complex spending policies, without having to individually translate them into code. It may sound disappointing, but there isn\'t, in fact,\nany real magic in this wallet: the generalization is achieved thanks to '),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[a("em",[t._v("descriptors")]),a("OutboundLink")],1),t._v(", that are now slowly starting to see adoption in a few other Bitcoin projects as well.")]),t._v(" "),a("p",[t._v("The author of this project strongly believes descriptors will be a big part of the future generation of Bitcoin wallets, since they provide a very flexible scripting language that can also be extended as the\ntechnology and tooling of Bitcoin evolves and changes (Schnorr signatures, Taproot, etc).")]),t._v(" "),a("p",[t._v("To learn more, check out the specific "),a("a",{attrs:{href:"/descriptors"}},[t._v("Descriptors section")]),t._v(".")]),t._v(" "),a("p",[t._v("The following code shows how to generate a random mnemonic, the extended (and deterministic) keys from that mnemonic and finally the descriptors from the extended private keys.")]),t._v(" "),a("p",[t._v("To be able to run this code, the "),a("code",[t._v("bdk")]),t._v(" dependency in "),a("code",[t._v("Cargo.toml")]),t._v(" must be set as follows:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('[dependencies]\nbdk = { version = "0.28.1", default-feature = false, features = ["all-keys"] }\n')])])]),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("Network")]),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("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 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("DerivableKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),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("GeneratedKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip39"),a("span",{pre:!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("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),a("span",{pre:!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("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("template"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),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("::")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("miniscript"),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 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 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("\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('"Hello, world!"')]),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(" network "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),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(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Or this can be Network::Bitcoin, Network::Signet or Network::Regtest")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate fresh mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),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("GeneratedKey")]),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 namespace"}},[t._v("miniscript"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[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 operator"}},[t._v("=")]),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("generate")]),a("span",{pre:!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("WordCount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Language")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("English")]),a("span",{pre:!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 function"}},[t._v("unwrap")]),a("span",{pre:!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("// Convert mnemonic to string")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mnemonic_words "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),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(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Parse a mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),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("Mnemonic")]),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("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("mnemonic_words"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!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("// Generate the extended key")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedKey")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_extended_key")]),a("span",{pre:!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 function"}},[t._v("unwrap")]),a("span",{pre:!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("// Get xprv from the extended key")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xprv "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" xkey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_xprv")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!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 comment"}},[t._v('// Create a BDK wallet structure using BIP 84 descriptor ("m/84h/1h/0h/0" and "m/84h/1h/0h/1")')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),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 "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),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 class-name"}},[t._v("Bip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xprv"),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 network"),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(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),a("span",{pre:!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 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('"mnemonic: {}\\n\\nrecv desc (pub key): {:#?}\\n\\nchng desc (pub key): {:#?}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n mnemonic_words"),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 function"}},[t._v("get_descriptor_for_keychain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[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(".")]),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(",")]),t._v("\n wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_descriptor_for_keychain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[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 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(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("More information about each component used in the code can be found in "),a("a",{attrs:{href:"https://docs.rs/bdk/latest/bdk/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("BDK Documentation"),a("OutboundLink")],1),t._v(".")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/app.2350a6e1.js b/assets/js/app.76456079.js similarity index 77% rename from assets/js/app.2350a6e1.js rename to assets/js/app.76456079.js index b225b52d4e..b664410141 100644 --- a/assets/js/app.2350a6e1.js +++ b/assets/js/app.76456079.js @@ -1,4 +1,4 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(t){function e(e){for(var r,a,c=e[0],l=e[1],s=e[2],u=0,d=[];u
'};function o(t,e,n){return tn?n:t}function i(t){return 100*(-1+t)}n.configure=function(t){var e,n;for(e in t)void 0!==(n=t[e])&&t.hasOwnProperty(e)&&(r[e]=n);return this},n.status=null,n.set=function(t){var e=n.isStarted();t=o(t,r.minimum,1),n.status=1===t?null:t;var l=n.render(!e),s=l.querySelector(r.barSelector),p=r.speed,u=r.easing;return l.offsetWidth,a((function(e){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(s,function(t,e,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+i(t)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+i(t)+"%,0)"}:{"margin-left":i(t)+"%"}).transition="all "+e+"ms "+n,o}(t,p,u)),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())}),r.trickleSpeed)};return r.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()*r.trickleRate)},t=0,e=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===e&&n.start(),t++,e++,r.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=r.template;var o,a=e.querySelector(r.barSelector),l=t?"-100":i(n.status||0),p=document.querySelector(r.parent);return c(a,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(o=e.querySelector(r.spinnerSelector))&&d(o),p!=document.body&&s(p,"nprogress-custom-parent"),p.appendChild(e),e},n.remove=function(){p(document.documentElement,"nprogress-busy"),p(document.querySelector(r.parent),"nprogress-custom-parent");var t=document.getElementById("nprogress");t&&d(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 r,o=t.length,i=e.charAt(0).toUpperCase()+e.slice(1);o--;)if((r=t[o]+i)in n)return r;return e}(n))}function r(t,e,r){e=n(e),t.style[e]=r}return function(t,e){var n,o,i=arguments;if(2==i.length)for(n in e)void 0!==(o=e[n])&&e.hasOwnProperty(n)&&r(t,n,o);else r(t,i[1],i[2])}}();function l(t,e){return("string"==typeof t?t:u(t)).indexOf(" "+e+" ")>=0}function s(t,e){var n=u(t),r=n+e;l(n,e)||(t.className=r.substring(1))}function p(t,e){var n,r=u(t);l(t,e)&&(n=r.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))}function u(t){return(" "+(t.className||"")+" ").replace(/\s+/gi," ")}function d(t){t&&t.parentNode&&t.parentNode.removeChild(t)}return n})?r.call(e,n,e,t):r)||(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 r=n(0),o=n(54).f,i=n(13),a=n(96),c=n(34),l=n(69),s=n(135);t.exports=function(t,e){var n,p,u,d,g,h=t.target,m=t.global,f=t.stat;if(n=m?r:f?r[h]||c(h,{}):r[h]&&r[h].prototype)for(p in e){if(d=e[p],u=t.dontCallGetSet?(g=o(n,p))&&g.value:n[p],!s(m?p:h+(f?".":"#")+p,t.forced)&&void 0!==u){if(typeof d==typeof u)continue;l(d,u)}(t.sham||u&&u.sham)&&i(d,"sham",!0),a(n,p,d,t)}}},function(t,e,n){"use strict";var r=n(27),o=Function.prototype.call;t.exports=r?o.bind(o):function(){return o.apply(o,arguments)}},function(t,e,n){"use strict";var r=n(3);t.exports=!r((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 r=n(55),o=n(56);t.exports=function(t){return r(o(t))}},function(t,e,n){"use strict";var r=n(0),o=n(1),i=function(t){return o(t)?t:void 0};t.exports=function(t,e){return arguments.length<2?i(r[t]):r[t]&&r[t][e]}},function(t,e,n){"use strict";var r=n(1),o=n(117),i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not a function")}},function(t,e,n){"use strict";var r=n(0),o=n(64),i=n(9),a=n(66),c=n(62),l=n(61),s=r.Symbol,p=o("wks"),u=l?s.for||s:s&&s.withoutSetter||a;t.exports=function(t){return i(p,t)||(p[t]=c&&i(s,t)?s[t]:u("Symbol."+t)),p[t]}},function(t,e,n){"use strict";var r=n(65),o=n(0),i=n(34),a=t.exports=o["__core-js_shared__"]||i("__core-js_shared__",{});(a.versions||(a.versions=[])).push({version:"3.36.0",mode:r?"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 r=n(0),o=Object.defineProperty;t.exports=function(t,e){try{o(r,t,{value:e,configurable:!0,writable:!0})}catch(n){r[t]=e}return e}},function(t,e,n){"use strict";var r=n(56),o=Object;t.exports=function(t){return o(r(t))}},function(t,e,n){"use strict";var r=n(8),o=String,i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not an object")}},function(t,e,n){"use strict";var r=n(132);t.exports=function(t){return r(t.length)}},function(t,e,n){var r=n(158),o=n(11),i=Object.prototype,a=i.hasOwnProperty,c=i.propertyIsEnumerable,l=r(function(){return arguments}())?r:function(t){return o(t)&&a.call(t,"callee")&&!c.call(t,"callee")};t.exports=l},function(t,e,n){var r=n(10)(n(6),"Map");t.exports=r},function(t,e,n){var r=n(177),o=n(184),i=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 r=n(4),o=n(44),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,a=/^\w*$/;t.exports=function(t,e){if(r(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!o(t))||(a.test(t)||!i.test(t)||null!=e&&t in Object(e))}},function(t,e,n){var r=n(12),o=n(11);t.exports=function(t){return"symbol"==typeof t||o(t)&&"[object Symbol]"==r(t)}},function(t,e,n){t.exports=function(){"use strict";var t=6e4,e=36e5,n="millisecond",r="second",o="minute",i="hour",a="day",c="week",l="month",s="quarter",p="year",u="date",d="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 r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},v={s:f,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),o=n%60;return(e<=0?"+":"-")+f(r,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!r&&o&&(b=o),o||!r&&b},x=function(t,e){if(k(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new B(n)},D=v;D.l=_,D.i=k,D.w=function(t,e){return x(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var B=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 r=e.match(g);if(r){var o=r[2]-1||0,i=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)):new Date(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)}}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()===d)},f.isSame=function(t,e){var n=x(t);return this.startOf(e)<=n&&n<=this.endOf(e)},f.isAfter=function(t,e){return x(t)-1&&t%1==0&&t79&&a<83||!i("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 r=n(5),o=n(26),i=n(113),a=n(28),c=n(29),l=n(58),s=n(9),p=n(67),u=Object.getOwnPropertyDescriptor;e.f=r?u:function(t,e){if(t=c(t),e=l(e),p)try{return u(t,e)}catch(t){}if(s(t,e))return a(!o(i.f,t,e),t[e])}},function(t,e,n){"use strict";var r=n(2),o=n(3),i=n(17),a=Object,c=r("".split);t.exports=o((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"===i(t)?c(t,""):a(t)}:a},function(t,e,n){"use strict";var r=n(57),o=TypeError;t.exports=function(t){if(r(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 r=n(114),o=n(59);t.exports=function(t){var e=r(t,"string");return o(e)?e:e+""}},function(t,e,n){"use strict";var r=n(30),o=n(1),i=n(60),a=n(61),c=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=r("Symbol");return o(e)&&i(e.prototype,c(t))}},function(t,e,n){"use strict";var r=n(2);t.exports=r({}.isPrototypeOf)},function(t,e,n){"use strict";var r=n(62);t.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(t,e,n){"use strict";var r=n(63),o=n(3),i=n(0).String;t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol("symbol detection");return!i(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},function(t,e,n){"use strict";var r,o,i=n(0),a=n(115),c=i.process,l=i.Deno,s=c&&c.versions||l&&l.version,p=s&&s.v8;p&&(o=(r=p.split("."))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!o&&a&&(!(r=a.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=a.match(/Chrome\/(\d+)/))&&(o=+r[1]),t.exports=o},function(t,e,n){"use strict";var r=n(33);t.exports=function(t,e){return r[t]||(r[t]=e||{})}},function(t,e,n){"use strict";t.exports=!1},function(t,e,n){"use strict";var r=n(2),o=0,i=Math.random(),a=r(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++o+i,36)}},function(t,e,n){"use strict";var r=n(5),o=n(3),i=n(119);t.exports=!r&&!o((function(){return 7!==Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(t,e,n){"use strict";t.exports={}},function(t,e,n){"use strict";var r=n(9),o=n(126),i=n(54),a=n(15);t.exports=function(t,e,n){for(var c=o(e),l=a.f,s=i.f,p=0;pp))return!1;var d=l.get(t),g=l.get(e);if(d&&g)return d==e&&g==t;var h=-1,m=!0,f=2&n?new r: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)||d(t)&&t.toString===u?JSON.stringify(t,null,2):String(t)}function v(t){var e=parseFloat(t);return isNaN(e)?t:e}function b(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(r,1)}}var k=Object.prototype.hasOwnProperty;function _(t,e){return k.call(t,e)}function x(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var D=/-(\w)/g,B=x((function(t){return t.replace(D,(function(t,e){return e?e.toUpperCase():""}))})),P=x((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),K=/\B([A-Z])/g,S=x((function(t){return t.replace(K,"-$1").toLowerCase()}));var T=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>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,r=new Array(n);n--;)r[n]=t[n+e];return r}function O(t,e){for(var n in e)t[n]=e[n];return t}function E(t){for(var e={},n=0;n0,J=Z&&Z.indexOf("edge/")>0;Z&&Z.indexOf("android");var Q=Z&&/iphone|ipad|ipod|ios/.test(Z);Z&&/chrome\/\d+/.test(Z),Z&&/phantomjs/.test(Z);var tt,et=Z&&Z.match(/firefox\/(\d+)/),nt={}.watch,rt=!1;if(G)try{var ot={};Object.defineProperty(ot,"passive",{get:function(){rt=!0}}),window.addEventListener("test-passive",null,ot)}catch(t){}var it=function(){return void 0===tt&&(tt=!G&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=G&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ct(t){return"function"==typeof t&&/native code/.test(t.toString())}var lt,st="undefined"!=typeof Symbol&&ct(Symbol)&&"undefined"!=typeof Reflect&&ct(Reflect.ownKeys);lt="undefined"!=typeof Set&&ct(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 pt=null;function ut(t){void 0===t&&(t=null),t||pt&&pt._scope.off(),pt=t,t&&t._scope.on()}var dt=function(){function t(t,e,n,r,o,i,a,c){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,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}(),gt=function(t){void 0===t&&(t="");var e=new dt;return e.text=t,e.isComment=!0,e};function ht(t){return new dt(void 0,void 0,void 0,String(t))}function mt(t){var e=new dt(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}var ft=0,vt=[],bt=function(){function t(){this._pending=!1,this.id=ft++,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,vt.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,r=e.length;n0&&(Zt((s=t(s,"".concat(n||"","_").concat(r)))[0])&&Zt(u)&&(d[p]=ht(u.text+s[0].text),s.shift()),d.push.apply(d,s)):l(s)?Zt(u)?d[p]=ht(u.text+s):""!==s&&d.push(ht(s)):Zt(s)&&Zt(u)?d[p]=ht(u.text+s.text):(c(e._isVList)&&a(s.tag)&&i(s.key)&&a(n)&&(s.key="__vlist".concat(n,"_").concat(r,"__")),d.push(s)));return d}(t):void 0}function Zt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Xt(t,e){var n,r,i,c,l=null;if(o(t)||"string"==typeof t)for(l=new Array(t.length),n=0,r=t.length;n0,c=e?!!e.$stable:!a,l=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(c&&o&&o!==r&&l===o.$key&&!a&&!o.$hasNormal)return o;for(var s in i={},e)e[s]&&"$"!==s[0]&&(i[s]=me(t,n,s,e[s]))}else i={};for(var p in n)p in i||(i[p]=fe(n,p));return e&&Object.isExtensible(e)&&(e._normalized=i),H(i,"$stable",c),H(i,"$key",l),H(i,"$hasNormal",a),i}function me(t,e,n,r){var i=function(){var e=pt;ut(t);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==typeof n&&!o(n)?[n]:Gt(n))&&n[0];return ut(e),n&&(!i||1===n.length&&i.isComment&&!ge(i))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:i,enumerable:!0,configurable:!0}),i}function fe(t,e){return function(){return t[e]}}function ve(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),be(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||be(t._listenersProxy={},t.$listeners,r,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||we(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:T(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return It(t,e,n)}))}}}function be(t,e,n,r,o){var i=!1;for(var a in e)a in t?e[a]!==n[a]&&(i=!0):(i=!0,ye(t,a,r,o));for(var a in t)a in e||(i=!0,delete t[a]);return i}function ye(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function we(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var ke=null;function _e(t,e){return(t.__esModule||st&&"Module"===t[Symbol.toStringTag])&&(t=t.default),p(t)?e.extend(t):t}function xe(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(ln=function(){return sn.now()})}var pn=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(cn=ln(),on=!0,tn.sort(pn),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Re(un))}}function gn(t,e){if(t){for(var n=Object.create(null),r=st?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(i&&!_(o,"default"))a=!1;else if(""===a||a===S(t)){var l=$n(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,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var c=a.name;c&&!e(c)&&Yn(n,i,r,o)}}}function Yn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,w(n,e)}Vn.prototype._init=function(t){var e=this;e._uid=Wn++,e._isVue=!0,e.__v_skip=!0,e._scope=new Lt(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.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=Tn(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&&Ge(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?he(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,o){return De(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return De(t,e,n,r,o,!0)};var i=n&&n.data;Ot(t,"$attrs",i&&i.attrs||r,null,!0),Ot(t,"$listeners",e._parentListeners||r,null,!0)}(e),Qe(e,"beforeCreate",void 0,!1),function(t){var e=gn(t.$options.inject,t);e&&(Kt(!1),Object.keys(e).forEach((function(n){Ot(t,n,e[n])})),Kt(!0))}(e),Rn(e),function(t){var e=t.$options.provide;if(e){var n=s(e)?e.call(t):e;if(!p(n))return;for(var r=zt(t),o=st?Reflect.ownKeys(n):Object.keys(n),i=0;i1?C(n):n;for(var r=C(arguments,1),o='event handler for "'.concat(t,'"'),i=0,a=n.length;iparseInt(this.max)&&Yn(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)Yn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Xn(t,(function(t){return Zn(e,t)}))})),this.$watch("exclude",(function(e){Xn(t,(function(t){return!Zn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=xe(t),n=e&&e.componentOptions;if(n){var r=Gn(n),o=this.include,i=this.exclude;if(o&&(!r||!Zn(o,r))||i&&r&&Zn(i,r))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,w(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 z}};Object.defineProperty(t,"config",e),t.util={warn:_n,extend:O,mergeOptions:Tn,defineReactive:Ot},t.set=Et,t.delete=At,t.nextTick=Re,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,O(t.options.components,Qn),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=Tn(this.options,t),this}}(t),qn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&d(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:it}),Object.defineProperty(Vn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Vn,"FunctionalRenderContext",{value:hn}),Vn.version="2.7.14";var tr=b("style,class"),er=b("input,textarea,option,select,progress"),nr=b("contenteditable,draggable,spellcheck"),rr=b("events,caret,typing,plaintext-only"),or=b("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"),ir="http://www.w3.org/1999/xlink",ar=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},cr=function(t){return ar(t)?t.slice(6,t.length):""},lr=function(t){return null==t||!1===t};function sr(t){for(var e=t.data,n=t,r=t;a(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=pr(r.data,e));for(;a(n=n.parent);)n&&n.data&&(e=pr(e,n.data));return function(t,e){if(a(t)||a(e))return ur(t,dr(e));return""}(e.staticClass,e.class)}function pr(t,e){return{staticClass:ur(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function ur(t,e){return t?e?t+" "+e:t:e||""}function dr(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?jr(t,e,n):or(e)?lr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return lr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):ar(e)?lr(n)?t.removeAttributeNS(ir,cr(e)):t.setAttributeNS(ir,e,n):jr(t,e,n)}function jr(t,e,n){if(lr(n))t.removeAttribute(e);else{if(X&&!Y&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Mr={create:Fr,update:Fr};function Rr(t,e){var n=e.elm,r=e.data,o=t.data;if(!(i(r.staticClass)&&i(r.class)&&(i(o)||i(o.staticClass)&&i(o.class)))){var c=sr(e),l=n._transitionClasses;a(l)&&(c=ur(c,dr(l))),c!==n._prevClass&&(n.setAttribute("class",c),n._prevClass=c)}}var Ir,Nr={create:Rr,update:Rr};function Lr(t,e,n){var r=Ir;return function o(){var i=e.apply(null,arguments);null!==i&&Wr(t,o,n,r)}}var zr=Ce&&!(et&&Number(et[1])<=53);function Ur(t,e,n,r){if(zr){var o=cn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}Ir.addEventListener(t,e,rt?{capture:n,passive:r}:n)}function Wr(t,e,n,r){(r||Ir).removeEventListener(t,e._wrapper||e,n)}function Hr(t,e){if(!i(t.data.on)||!i(e.data.on)){var n=e.data.on||{},r=t.data.on||{};Ir=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,r,Ur,Wr,Lr,e.context),Ir=void 0}}var Vr,qr={create:Hr,update:Hr,destroy:function(t){return Hr(t,xr)}};function Gr(t,e){if(!i(t.data.domProps)||!i(e.data.domProps)){var n,r,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=O({},s)),l)n in s||(o[n]="");for(n in s){if(r=s[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===l[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=r;var p=i(r)?"":String(r);Zr(o,p)&&(o.value=p)}else if("innerHTML"===n&&mr(o.tagName)&&i(o.innerHTML)){(Vr=Vr||document.createElement("div")).innerHTML="".concat(r,"");for(var u=Vr.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;u.firstChild;)o.appendChild(u.firstChild)}else if(r!==l[n])try{o[n]=r}catch(t){}}}}function Zr(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,r=t._vModifiers;if(a(r)){if(r.number)return v(n)!==v(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Xr={create:Gr,update:Gr},Yr=x((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Jr(t){var e=Qr(t.style);return t.staticStyle?O(t.staticStyle,e):e}function Qr(t){return Array.isArray(t)?E(t):"string"==typeof t?Yr(t):t}var to,eo=/^--/,no=/\s*!important$/,ro=function(t,e,n){if(eo.test(e))t.style.setProperty(e,n);else if(no.test(n))t.style.setProperty(S(e),n.replace(no,""),"important");else{var r=io(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(lo).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 po(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(lo).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")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function uo(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&O(e,go(t.name||"v")),O(e,t),e}return"string"==typeof t?go(t):void 0}}var go=x((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")}})),ho=G&&!Y,mo="transition",fo="transitionend",vo="animation",bo="animationend";ho&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(mo="WebkitTransition",fo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(vo="WebkitAnimation",bo="webkitAnimationEnd"));var yo=G?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function wo(t){yo((function(){yo(t)}))}function ko(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),so(t,e))}function _o(t,e){t._transitionClasses&&w(t._transitionClasses,e),po(t,e)}function xo(t,e,n){var r=Bo(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var c="transition"===o?fo:bo,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,u=i.length):"animation"===e?s>0&&(n="animation",p=s,u=l.length):u=(n=(p=Math.max(a,s))>0?a>s?"transition":"animation":null)?"transition"===n?i.length:l.length:0,{type:n,timeout:p,propCount:u,hasTransform:"transition"===n&&Do.test(r[mo+"Property"])}}function Po(t,e){for(;t.length1}function Eo(t,e){!0!==e.data.show&&So(e)}var Ao=function(t){var e,n,r={},s=t.modules,p=t.nodeOps;for(e=0;eh?w(t,i(n[v+1])?null:n[v+1].elm,n,g,v,r):g>v&&_(e,u,h)}(u,m,v,n,s):a(v)?(a(t.text)&&p.setTextContent(u,""),w(u,null,v,0,v.length-1,n)):a(m)?_(m,0,m.length-1):a(t.text)&&p.setTextContent(u,""):t.text!==e.text&&p.setTextContent(u,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 r=0;r-1,a.selected!==i&&(a.selected=i);else if(j(Ro(a),r))return void(t.selectedIndex!==c&&(t.selectedIndex=c));o||(t.selectedIndex=-1)}}function Mo(t,e){return e.every((function(e){return!j(e,t)}))}function Ro(t){return"_value"in t?t._value:t.value}function Io(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 zo(t){return!t.componentInstance||t.data&&t.data.transition?t:zo(t.componentInstance._vnode)}var Uo={model:Fo,show:{bind:function(t,e,n){var r=e.value,o=(n=zo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,So(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=zo(n)).data&&n.data.transition?(n.data.show=!0,r?So(n,(function(){t.style.display=t.__vOriginalDisplay})):To(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},Wo={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(xe(e.children)):t}function Vo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var r in o)e[B(r)]=o[r];return e}function qo(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Go=function(t){return t.tag||ge(t)},Zo=function(t){return"show"===t.name},Xo={name:"transition",props:Wo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Go)).length){0;var r=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 i=Ho(o);if(!i)return o;if(this._leaving)return qo(t,o);var a="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?a+"comment":a+i.tag:l(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var c=(i.data||(i.data={})).transition=Vo(this),s=this._vnode,p=Ho(s);if(i.data.directives&&i.data.directives.some(Zo)&&(i.data.show=!0),p&&p.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,p)&&!ge(p)&&(!p.componentInstance||!p.componentInstance._vnode.isComment)){var u=p.data.transition=O({},c);if("out-in"===r)return this._leaving=!0,Vt(u,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),qo(t,o);if("in-out"===r){if(ge(i))return s;var d,g=function(){d()};Vt(c,"afterEnter",g),Vt(c,"enterCancelled",g),Vt(u,"delayLeave",(function(t){d=t}))}}return o}}},Yo=O({tag:String,moveClass:String},Wo);function Jo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Qo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ti(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate(".concat(r,"px,").concat(o,"px)"),i.transitionDuration="0s"}}delete Yo.mode;var ei={Transition:Xo,TransitionGroup:{props:Yo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Xe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Vo(this),c=0;c-1?vr[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:vr[t]=/HTMLUnknownElement/.test(e.toString())},O(Vn.options.directives,Uo),O(Vn.options.components,ei),Vn.prototype.__patch__=G?Ao:A,Vn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=gt),Qe(t,"beforeMount"),r=function(){t._update(t._render(),n)},new We(t,r,A,{before:function(){t._isMounted&&!t._isDestroyed&&Qe(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var i=0;i=0&&(e=t.slice(r),t=t.slice(0,r));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?_i(l.path,s,n||o.append):s,u=function(t,e,n){void 0===e&&(e={});var r,o=n||si;try{r=o(t||"")}catch(t){r={}}for(var i in e){var a=e[i];r[i]=Array.isArray(a)?a.map(li):li(a)}return r}(l.query,o.query,r&&r.options.parseQuery),d=o.hash||l.hash;return d&&"#"!==d.charAt(0)&&(d="#"+d),{_normalized:!0,path:p,query:u,hash:d}}var Ui,Wi=function(){},Hi={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,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,c=o.href,l={},s=n.options.linkActiveClass,p=n.options.linkExactActiveClass,u=null==s?"router-link-active":s,d=null==p?"router-link-exact-active":p,g=null==this.activeClass?u:this.activeClass,h=null==this.exactActiveClass?d:this.exactActiveClass,m=a.redirectedFrom?di(null,zi(a.redirectedFrom),null,n):a;l[h]=vi(r,m,this.exactPath),l[g]=this.exact||this.exactPath?l[h]:function(t,e){return 0===t.path.replace(ui,"/").indexOf(e.path.replace(ui,"/"))&&(!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)}(r,m);var f=l[h]?this.ariaCurrentValue:null,v=function(t){Vi(t)&&(e.replace?n.replace(i,Wi):n.push(i,Wi))},b={click:Vi};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 r=0;r-1&&(c.params[d]=n.params[d]);return c.path=Li(p.path,c.params),l(p,c,a)}if(c.path){c.params={};for(var g=0;g-1}function xa(t,e){return _a(t)&&t._isRouter&&(null==e||t.type===e)}function Da(t,e,n){var r=function(o){o>=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function Ba(t){return function(e,n,r){var o=!1,i=0,a=null;Pa(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){o=!0,i++;var l,s=Ta((function(e){var o;((o=e).__esModule||Sa&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:Ui.extend(e),n.components[c]=e,--i<=0&&r()})),p=Ta((function(t){var e="Failed to resolve async component "+c+": "+t;a||(a=_a(t)?t:new Error(e),r(a))}));try{l=t(s,p)}catch(t){p(t)}if(l)if("function"==typeof l.then)l.then(s,p);else{var u=l.component;u&&"function"==typeof u.then&&u.then(s,p)}}})),o||r()}}function Pa(t,e){return Ka(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Ka(t){return Array.prototype.concat.apply([],t)}var Sa="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ta(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var Ca=function(t,e){this.router=t,this.base=function(t){if(!t)if(qi){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=hi,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Oa(t,e,n,r){var o=Pa(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=Ui.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return Ka(r?o.reverse():o)}function Ea(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 r,o=this;try{r=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),e&&e(r),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(r)})))}),(function(t){n&&n(t),t&&!o.ready&&(xa(t,va.redirected)&&i===hi||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},Ca.prototype.confirmTransition=function(t,e,n){var r=this,o=this.current;this.pending=t;var i,a,c=function(t){!xa(t)&&_a(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},l=t.matched.length-1,s=o.matched.length-1;if(vi(t,o)&&l===s&&t.matched[l]===o.matched[s])return this.ensureURL(),t.hash&&ia(this.router,o,t,!1),c(((a=wa(i=o,t,va.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var p=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=ha&&n;r&&this.listeners.push(oa());var o=function(){var n=t.current,o=Fa(t.base);t.current===hi&&o===t._startLocation||t.transitionTo(o,(function(t){r&&ia(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 r=this,o=this.current;this.transitionTo(t,(function(t){ma(xi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){fa(xi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Fa(this.base)!==this.current.fullPath){var e=xi(this.base+this.current.fullPath);t?ma(e):fa(e)}},e.prototype.getCurrentLocation=function(){return Fa(this.base)},e}(Ca);function Fa(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(xi(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var $a=function(t){function e(e,n,r){t.call(this,e,n),r&&function(t){var e=Fa(t);if(!/^\/#/.test(e))return window.location.replace(xi(t+"/#"+e)),!0}(this.base)||ja()}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=ha&&e;n&&this.listeners.push(oa());var r=function(){var e=t.current;ja()&&t.transitionTo(Ma(),(function(r){n&&ia(t.router,r,e,!0),ha||Na(r.fullPath)}))},o=ha?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Ia(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),ia(r.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;Ma()!==e&&(t?Ia(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ma()},e}(Ca);function ja(){var t=Ma();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ma(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Ra(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ia(t){ha?ma(Ra(t)):window.location.hash=t}function Na(t){ha?fa(Ra(t)):window.location.replace(Ra(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 r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.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 r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){xa(t,va.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),za=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Xi(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ha&&!1!==t.fallback,this.fallback&&(e="hash"),qi||(e="abstract"),this.mode=e,e){case"history":this.history=new Aa(this,t.base);break;case"hash":this.history=new $a(this,t.base,this.fallback);break;case"abstract":this.history=new La(this,t.base);break;default:0}},Ua={currentRoute:{configurable:!0}};za.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},Ua.currentRoute.get=function(){return this.history&&this.history.current},za.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 Aa||n instanceof $a){var r=function(t){n.setupListeners(),function(t){var r=n.current,o=e.options.scrollBehavior;ha&&o&&"fullPath"in t&&ia(e,t,r,!1)}(t)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},za.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},za.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},za.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},za.prototype.onReady=function(t,e){this.history.onReady(t,e)},za.prototype.onError=function(t){this.history.onError(t)},za.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},za.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},za.prototype.go=function(t){this.history.go(t)},za.prototype.back=function(){this.go(-1)},za.prototype.forward=function(){this.go(1)},za.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]}))}))):[]},za.prototype.resolve=function(t,e,n){var r=zi(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?xi(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},za.prototype.getRoutes=function(){return this.matcher.getRoutes()},za.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},za.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(za.prototype,Ua);var Wa=za;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}za.install=function t(e){if(!t.installed||Ui!==e){t.installed=!0,Ui=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(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,r(this,this)},destroyed:function(){r(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",wi),e.component("RouterLink",Hi);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},za.version="3.6.5",za.isNavigationFailure=xa,za.NavigationFailureType=va,za.START_LOCATION=hi,qi&&window.Vue&&window.Vue.use(za);n(53);n(100),n(46);var Va={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(23)]).then(n.bind(null,318)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(22)]).then(n.bind(null,287)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(32)]).then(n.bind(null,262)),"components/Home":()=>Promise.all([n.e(0),n.e(27)]).then(n.bind(null,319)),"components/NavLink":()=>n.e(35).then(n.bind(null,254)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(20)]).then(n.bind(null,276)),"components/Navbar":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,286)),"components/Page":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,298)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(28)]).then(n.bind(null,288)),"components/PageNav":()=>Promise.all([n.e(0),n.e(24)]).then(n.bind(null,289)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,269)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(33)]).then(n.bind(null,321)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,265)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(30)]).then(n.bind(null,263)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,256)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,382)),"global-components/CodeBlock":()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,372)),"global-components/CodeGroup":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,373)),"layouts/404":()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,374)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,375)),NotFound:()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,374)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,375)),"components/Cases":()=>Promise.all([n.e(0),n.e(25)]).then(n.bind(null,320)),"components/Footer":()=>Promise.all([n.e(0),n.e(26)]).then(n.bind(null,270)),"components/LayoutWrap":()=>Promise.all([n.e(0),n.e(1),n.e(17)]).then(n.bind(null,277)),"components/PostMeta":()=>Promise.all([n.e(0),n.e(29)]).then(n.bind(null,299)),"layouts/DirectoryPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,376)),"layouts/FrontmatterKey":()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,377)),"layouts/FrontmatterPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,378)),"layouts/IndexPost":()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,317)),"layouts/Post":()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,379)),DirectoryPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,376)),FrontmatterKey:()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,377)),FrontmatterPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,378)),IndexPost:()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,317)),Post:()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,379))},qa={"v-330a32a2":()=>n.e(37).then(n.bind(null,383)),"v-64f4dafd":()=>n.e(38).then(n.bind(null,384)),"v-8bd632d6":()=>n.e(40).then(n.bind(null,385)),"v-0f4d5d15":()=>n.e(41).then(n.bind(null,386)),"v-2cebe183":()=>n.e(34).then(n.bind(null,387)),"v-7c0c45f9":()=>n.e(39).then(n.bind(null,388)),"v-3eaa044d":()=>n.e(31).then(n.bind(null,389)),"v-353b78e1":()=>n.e(42).then(n.bind(null,390)),"v-3875825f":()=>n.e(43).then(n.bind(null,391)),"v-07ff1843":()=>n.e(44).then(n.bind(null,392)),"v-c6756cce":()=>n.e(46).then(n.bind(null,393)),"v-9504490e":()=>n.e(45).then(n.bind(null,394)),"v-56536559":()=>n.e(19).then(n.bind(null,395)),"v-f58ec8f2":()=>n.e(21).then(n.bind(null,396)),"v-015729b9":()=>n.e(47).then(n.bind(null,397)),"v-57698579":()=>n.e(49).then(n.bind(null,398)),"v-2c605799":()=>n.e(48).then(n.bind(null,399)),"v-9145467a":()=>n.e(50).then(n.bind(null,400)),"v-2cf72b39":()=>n.e(51).then(n.bind(null,401)),"v-11d64359":()=>n.e(52).then(n.bind(null,402)),"v-ab5ba3ce":()=>n.e(54).then(n.bind(null,403)),"v-5d749fce":()=>n.e(53).then(n.bind(null,404)),"v-d0375c8e":()=>n.e(55).then(n.bind(null,405)),"v-10852eea":()=>n.e(56).then(n.bind(null,406)),"v-edd5570e":()=>n.e(57).then(n.bind(null,407)),"v-05df4999":()=>n.e(58).then(n.bind(null,408)),"v-faad828e":()=>n.e(59).then(n.bind(null,409)),"v-0119984e":()=>n.e(60).then(n.bind(null,410)),"v-0df1c3ce":()=>n.e(62).then(n.bind(null,411)),"v-1ac9ef4e":()=>n.e(64).then(n.bind(null,412)),"v-55969f39":()=>n.e(65).then(n.bind(null,413)),"v-7c3d28f9":()=>n.e(61).then(n.bind(null,414)),"v-75d11339":()=>n.e(63).then(n.bind(null,415)),"v-8534b9c2":()=>n.e(66).then(n.bind(null,416)),"v-aeb70fce":()=>n.e(67).then(n.bind(null,417)),"v-009133c8":()=>n.e(68).then(n.bind(null,418)),"v-7a315e41":()=>n.e(69).then(n.bind(null,419)),"v-f611a14e":()=>n.e(70).then(n.bind(null,420)),"v-3acb6e6a":()=>n.e(71).then(n.bind(null,421)),"v-496cb7f9":()=>n.e(72).then(n.bind(null,380)),"v-0b3b65ea":()=>n.e(73).then(n.bind(null,422)),"v-a76bccee":()=>n.e(74).then(n.bind(null,423)),"v-05d01c19":()=>n.e(75).then(n.bind(null,424)),"v-11bf335e":()=>n.e(76).then(n.bind(null,425)),"v-a9236c10":()=>n.e(77).then(n.bind(null,426)),"v-29f9f21c":()=>n.e(78).then(n.bind(null,427)),"v-4bcdac39":()=>n.e(80).then(n.bind(null,428)),"v-287ca6ff":()=>n.e(79).then(n.bind(null,429)),"v-5245a0b2":()=>n.e(81).then(n.bind(null,430))};function Ga(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Za=/-(\w)/g,Xa=Ga(t=>t.replace(Za,(t,e)=>e?e.toUpperCase():"")),Ya=/\B([A-Z])/g,Ja=Ga(t=>t.replace(Ya,"-$1").toLowerCase()),Qa=Ga(t=>t.charAt(0).toUpperCase()+t.slice(1));function tc(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Qa(Xa(e))):t(Qa(e))||t(Ja(e))}const ec=Object.assign({},Va,qa),nc=t=>ec[t],rc=t=>qa[t],oc=t=>Va[t],ic=t=>Vn.component(t);function ac(t){return tc(rc,t)}function cc(t){return tc(oc,t)}function lc(t){return tc(nc,t)}function sc(t){return tc(ic,t)}function pc(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!sc(t)&&lc(t)){const e=await lc(t)();Vn.component(t,e.default)}}))}function uc(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var dc=n(91),gc=n.n(dc),hc=n(92),mc=n.n(hc),fc={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}="${mc()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=bc(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=yc(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return gc()([{name:"description",content:this.$description}],t,this.siteMeta,wc)},updateCanonicalLink(){vc(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",bc(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){yc(null,this.currentMetaTags),vc()}};function vc(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function bc(t=""){return t?``:""}function yc(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 wc(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var kc=n(93),_c={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(kc)()((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),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},xc=n(22),Dc=n.n(xc),Bc={mounted(){Dc.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Vn.component(t.name)||Dc.a.start(),n()}),this.$router.afterEach(()=>{Dc.a.done(),this.isSidebarOpen=!1})}},Pc={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)}}},Kc=(n(240),n(7)),Sc=Object(Kc.a)(Pc,(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,Tc=(n(241),{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(Sc));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=(n(242),Object.assign||function(t){for(var e=1;e1&&void 0!==arguments[1]?arguments[1]:{},r=window.Promise||function(t){function e(){}t(e,e)},o=function(t){var e=t.target;e!==B?-1!==y.indexOf(e)&&m({target:e}):h()},i=function(){if(!k&&D.original){var t=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(_-t)>x.scrollOffset&&setTimeout(h,150)}},a=function(t){var e=t.key||t.keyCode;"Escape"!==e&&"Esc"!==e&&27!==e||h()},c=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t;if(t.background&&(B.style.background=t.background),t.container&&t.container instanceof Object&&(e.container=Cc({},x.container,t.container)),t.template){var n=Ec(t.template)?t.template:document.querySelector(t.template);e.template=n}return x=Cc({},x,e),y.forEach((function(t){t.dispatchEvent(Mc("medium-zoom:update",{detail:{zoom:P}}))})),P},l=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return t(Cc({},x,e))},s=function(){for(var t=arguments.length,e=Array(t),n=0;n0?e.reduce((function(t,e){return[].concat(t,Fc(e))}),[]):y;return r.forEach((function(t){t.classList.remove("medium-zoom-image"),t.dispatchEvent(Mc("medium-zoom:detach",{detail:{zoom:P}}))})),y=y.filter((function(t){return-1===r.indexOf(t)})),P},u=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return y.forEach((function(r){r.addEventListener("medium-zoom:"+t,e,n)})),w.push({type:"medium-zoom:"+t,listener:e,options:n}),P},d=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return y.forEach((function(r){r.removeEventListener("medium-zoom:"+t,e,n)})),w=w.filter((function(n){return!(n.type==="medium-zoom:"+t&&n.listener.toString()===e.toString())})),P},g=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target,n=function(){var t={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},e=void 0,n=void 0;if(x.container)if(x.container instanceof Object)e=(t=Cc({},t,x.container)).width-t.left-t.right-2*x.margin,n=t.height-t.top-t.bottom-2*x.margin;else{var r=(Ec(x.container)?x.container:document.querySelector(x.container)).getBoundingClientRect(),o=r.width,i=r.height,a=r.left,c=r.top;t=Cc({},t,{width:o,height:i,left:a,top:c})}e=e||t.width-2*x.margin,n=n||t.height-2*x.margin;var l=D.zoomedHd||D.original,s=Ac(l)?e:l.naturalWidth||e,p=Ac(l)?n:l.naturalHeight||n,u=l.getBoundingClientRect(),d=u.top,g=u.left,h=u.width,m=u.height,f=Math.min(Math.max(h,s),e)/h,v=Math.min(Math.max(m,p),n)/m,b=Math.min(f,v),y="scale("+b+") translate3d("+((e-h)/2-g+x.margin+t.left)/b+"px, "+((n-m)/2-d+x.margin+t.top)/b+"px, 0)";D.zoomed.style.transform=y,D.zoomedHd&&(D.zoomedHd.style.transform=y)};return new r((function(t){if(e&&-1===y.indexOf(e))t(P);else{if(D.zoomed)t(P);else{if(e)D.original=e;else{if(!(y.length>0))return void t(P);var r=y;D.original=r[0]}if(D.original.dispatchEvent(Mc("medium-zoom:open",{detail:{zoom:P}})),_=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,k=!0,D.zoomed=jc(D.original),document.body.appendChild(B),x.template){var o=Ec(x.template)?x.template:document.querySelector(x.template);D.template=document.createElement("div"),D.template.appendChild(o.content.cloneNode(!0)),document.body.appendChild(D.template)}if(D.original.parentElement&&"PICTURE"===D.original.parentElement.tagName&&D.original.currentSrc&&(D.zoomed.src=D.original.currentSrc),document.body.appendChild(D.zoomed),window.requestAnimationFrame((function(){document.body.classList.add("medium-zoom--opened")})),D.original.classList.add("medium-zoom-image--hidden"),D.zoomed.classList.add("medium-zoom-image--opened"),D.zoomed.addEventListener("click",h),D.zoomed.addEventListener("transitionend",(function e(){k=!1,D.zoomed.removeEventListener("transitionend",e),D.original.dispatchEvent(Mc("medium-zoom:opened",{detail:{zoom:P}})),t(P)})),D.original.getAttribute("data-zoom-src")){D.zoomedHd=D.zoomed.cloneNode(),D.zoomedHd.removeAttribute("srcset"),D.zoomedHd.removeAttribute("sizes"),D.zoomedHd.removeAttribute("loading"),D.zoomedHd.src=D.zoomed.getAttribute("data-zoom-src"),D.zoomedHd.onerror=function(){clearInterval(i),console.warn("Unable to reach the zoom image target "+D.zoomedHd.src),D.zoomedHd=null,n()};var i=setInterval((function(){D.zoomedHd.complete&&(clearInterval(i),D.zoomedHd.classList.add("medium-zoom-image--opened"),D.zoomedHd.addEventListener("click",h),document.body.appendChild(D.zoomedHd),n())}),10)}else if(D.original.hasAttribute("srcset")){D.zoomedHd=D.zoomed.cloneNode(),D.zoomedHd.removeAttribute("sizes"),D.zoomedHd.removeAttribute("loading");var a=D.zoomedHd.addEventListener("load",(function(){D.zoomedHd.removeEventListener("load",a),D.zoomedHd.classList.add("medium-zoom-image--opened"),D.zoomedHd.addEventListener("click",h),document.body.appendChild(D.zoomedHd),n()}))}else n()}}}))},h=function(){return new r((function(t){if(!k&&D.original){k=!0,document.body.classList.remove("medium-zoom--opened"),D.zoomed.style.transform="",D.zoomedHd&&(D.zoomedHd.style.transform=""),D.template&&(D.template.style.transition="opacity 150ms",D.template.style.opacity=0),D.original.dispatchEvent(Mc("medium-zoom:close",{detail:{zoom:P}})),D.zoomed.addEventListener("transitionend",(function e(){D.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(D.zoomed),D.zoomedHd&&document.body.removeChild(D.zoomedHd),document.body.removeChild(B),D.zoomed.classList.remove("medium-zoom-image--opened"),D.template&&document.body.removeChild(D.template),k=!1,D.zoomed.removeEventListener("transitionend",e),D.original.dispatchEvent(Mc("medium-zoom:closed",{detail:{zoom:P}})),D.original=null,D.zoomed=null,D.zoomedHd=null,D.template=null,t(P)}))}else t(P)}))},m=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target;return D.original?h():g({target:e})},f=function(){return x},v=function(){return y},b=function(){return D.original},y=[],w=[],k=!1,_=0,x=n,D={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(e)?x=e:(e||"string"==typeof e)&&s(e),x=Cc({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},x);var B=$c(x.background);document.addEventListener("click",o),document.addEventListener("keyup",a),document.addEventListener("scroll",i),window.addEventListener("resize",h);var P={open:g,close:h,toggle:m,update:c,clone:l,attach:s,detach:p,on:u,off:d,getOptions:f,getImages:v,getZoomedImage:b};return P},Ic=[fc,_c,Bc,Tc,{data:()=>({zoom:null}),mounted(){this.updateZoom()},updated(){this.updateZoom()},methods:{updateZoom(){setTimeout(()=>{this.zoom&&this.zoom.detach(),this.zoom=Rc(".theme-default-content :not(a) > img",void 0)},1e3)}}}],Nc={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"}}},Lc=Object(Kc.a)(Nc,(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.")}}(Lc,"mixins",Ic);const zc=[{name:"v-330a32a2",path:"/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-330a32a2").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-64f4dafd",path:"/blog/_2024-q4-update/",component:Lc,beforeEnter:(t,e,n)=>{pc("Post","v-64f4dafd").then(n)}},{path:"/blog/_2024-q4-update/index.html",redirect:"/blog/_2024-q4-update/"},{path:"/_blog/2024_q4_update.html",redirect:"/blog/_2024-q4-update/"},{name:"v-8bd632d6",path:"/blog/bdk-cli-basics-multisig-2of3/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-0f4d5d15",path:"/blog/bdk-cli-basics/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-7c0c45f9",path:"/blog/bitcoin-core-rpc-demo/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-3eaa044d",path:"/blog/bdk-rn-making-of/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-c6756cce",path:"/blog/descriptors-in-the-wild/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-9504490e",path:"/blog/descriptor-based-paper-wallet/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-57698579",path:"/blog/2021/01/fee-estimation-for-light-clients-part-3/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-2c605799",path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-9145467a",path:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-0119984e",path:"/blog/2021/03/release-v0.5.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-1ac9ef4e",path:"/blog/2021/07/release-v0.9.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-7c3d28f9",path:"/blog/2021/04/release-v0.6.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-75d11339",path:"/blog/2021/06/release-v0.8.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-8534b9c2",path:"/blog/spending-policy-demo/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-009133c8",path:"/bdk-cli/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-009133c8").then(n)}},{path:"/bdk-cli/index.html",redirect:"/bdk-cli/"},{name:"v-7a315e41",path:"/bdk-cli/compiler/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-a9236c10").then(n)}},{path:"/descriptors/index.html",redirect:"/descriptors/"},{name:"v-29f9f21c",path:"/examples/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-29f9f21c").then(n)}},{path:"/examples/index.html",redirect:"/examples/"},{name:"v-4bcdac39",path:"/getting-started/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-4bcdac39").then(n)}},{path:"/getting-started/index.html",redirect:"/getting-started/"},{path:"/getting-started.html",redirect:"/getting-started/"},{name:"v-287ca6ff",path:"/foundation/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-287ca6ff").then(n)}},{path:"/foundation/index.html",redirect:"/foundation/"},{path:"/foundation.html",redirect:"/foundation/"},{name:"v-5245a0b2",path:"/supporters/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-5245a0b2").then(n)}},{path:"/supporters/index.html",redirect:"/supporters/"},{name:"v-424df898",path:"/blog/",component:Lc,beforeEnter:(t,e,n)=>{pc("IndexPost","v-424df898").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/index.html",redirect:"/blog/"},{name:"v-619df59e",path:"/blog/tags/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-398e8fd4").then(n)},meta:{pid:"tags",id:"project"}},{path:"/blog/tags/project/index.html",redirect:"/blog/tags/project/"},{name:"v-da8c869a",path:"/blog/tags/tutorial/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-c4494744").then(n)},meta:{pid:"tags",id:"architecture"}},{path:"/blog/tags/architecture/index.html",redirect:"/blog/tags/architecture/"},{name:"v-62bbf2ad",path:"/blog/tags/Bitcoin Core/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-4696dfd8").then(n)},meta:{pid:"tags",id:"Wallet"}},{path:"/blog/tags/Wallet/index.html",redirect:"/blog/tags/Wallet/"},{name:"v-876cfade",path:"/blog/tags/BDK-RN/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-3e6950f4",path:"/blog/author/waterst0ne/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-82e16b5c",path:"/blog/author/Rajarshi Maitra/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-37829241",path:"/blog/author/Bitcoin Zavior/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-d2b26530").then(n)},meta:{pid:"author",id:"rorp"}},{path:"/blog/author/rorp/index.html",redirect:"/blog/author/rorp/"},{name:"v-5d54001e",path:"/blog/author/thunderbiscuit/",component:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5d54001e").then(n)},meta:{pid:"author",id:"thunderbiscuit"}},{path:"/blog/author/thunderbiscuit/index.html",redirect:"/blog/author/thunderbiscuit/"},{name:"v-6b564fb4",path:"/blog/author/Gabriele Domenichini/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-624fd61e",path:"/blog/author/Riccardo Casatta/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-ad00c09c",path:"/blog/author/Alekos Filini/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("DirectoryPagination","v-c3507b3a").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/4/index.html",redirect:"/blog/page/4/"},{name:"v-5f2ac9cb",path:"/blog/author/Alekos Filini/page/2/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc}],Uc={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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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/2024_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/2024_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/2024_q4_update.html",relativePath:"_blog/2024_q4_update.md",key:"v-64f4dafd",path:"/blog/_2024-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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{title:"BDK-CLI",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK-CLI"},{property:"og:description",content:"The bdk-clihttps://github.com/bitcoindevkit/bdk-cli repo has an example interactive shell built\nusing the `bdk` library called `bdk-cli` that acts both as a reference implementation of a wallet\nand a tool to quickly experiment with descriptors and transactions."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK-CLI"},{name:"twitter:description",content:"The bdk-clihttps://github.com/bitcoindevkit/bdk-cli repo has an example interactive shell built\nusing the `bdk` library called `bdk-cli` that acts both as a reference implementation of a wallet\nand a tool to quickly experiment with descriptors and transactions."},{name:"twitter:url",content:"https://bitcoindevkit.org/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:"/bdk-cli/",relativePath:"bdk-cli/README.md",key:"v-009133c8",path:"/bdk-cli/",codeSwitcherOptions:{},lastUpdated:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{title:"Bitcoin Dev Kit Foundation",frontmatter:{sidebar:!1,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.html",relativePath:"foundation.md",key:"v-287ca6ff",path:"/foundation/",headers:[{level:2,title:"Board",slug:"board"},{level:2,title:"Operations",slug:"operations"}],codeSwitcherOptions:{},lastUpdated:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{title:"Supporters",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Supporters"},{property:"og:description",content:"The Bitcoin Dev Kit project is proudly supported by:"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/supporters/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Supporters"},{name:"twitter:description",content:"The Bitcoin Dev Kit project is proudly supported by:"},{name:"twitter:url",content:"https://bitcoindevkit.org/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:"/supporters/",relativePath:"supporters/README.md",key:"v-5245a0b2",path:"/supporters/",codeSwitcherOptions:{},lastUpdated:"4/15/2024, 8:13:59 PM",lastUpdatedTimestamp:1713212039e3},{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:"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:"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:"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-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:"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:"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:"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:"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:"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:"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:"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:"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:"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:"Case Studies",link:"/case-studies"},{text:"Foundation",link:"/foundation"},{text:"Blog",link:"/blog/"}],sidebar:{"/_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"]]}],"/tutorials/":[{title:"Tutorials",collapsable:!1,children:["/tutorials/hello-world","/tutorials/Bitcoin_Core_RPC_Demo","/tutorials/compact_filters_demo","/tutorials/descriptors_in_the_wild","/tutorials/hidden-power-of-bitcoin","/tutorials/descriptor_based_paper_wallet","/tutorials/spending_policy_demo","/tutorials/exploring_bdk_rn","/tutorials/using_bdk_with_hardware_wallets","/tutorials/exploring_bdk_flutter","/tutorials/bdk_cli_basics","/tutorials/bdk-cli_basics_multisig_2of3","/tutorials/bdk_with_tor"]}],"/":[{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/","Rust Stable Docs"],["https://bitcoindevkit.org/docs-rs/bdk/nightly/latest/bdk/","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:"/supporters/"},{text:"BDK Foundation",link:"/foundation"}]}],copyright:"Copyright © 2024 BDK Developers"}}},{COLOR_MODES:Wc,STORE_ATTR:Hc,setColorMode:Vc}=n(111),qc=t=>"Enter"===t.code||13===(t.keyCode||t.which),Gc=t=>{const e=t.target.matches("#algolia-search-input")&&qc(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?Wc[1]:Wc[0],e=window.localStorage.getItem(Hc);Vc(Wc.includes(e)?e:t)}n(243);Vn.component("Badge",()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,382))),Vn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,372))),Vn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,373)));n(244);var Zc={props:{color:{required:!1,default:"rgb(66, 185, 131)"}}},Xc=(n(245),Object(Kc.a)(Zc,(function(){return(0,this._self._c)("div",{staticClass:"spinner",style:{background:this.color}})}),[],!1,null,"1bbcb91a",null).exports);const Yc={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(82).then(n.t.bind(null,368,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:Xc}};var Jc=n(94),Qc=n.n(Jc);n(246);Vn.component("CodeSwitcher",()=>n.e(36).then(n.bind(null,381)));var tl={tags:{BDK:{key:"BDK",scope:"tags",path:"/blog/tags/BDK/",pageKeys:["v-64f4dafd","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-64f4dafd"]},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"]},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"]},"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-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-56536559","v-f58ec8f2"]},blockchain:{key:"blockchain",scope:"tags",path:"/blog/tags/blockchain/",pageKeys:["v-353b78e1"]},bindings:{key:"bindings",scope:"tags",path:"/blog/tags/bindings/",pageKeys:["v-3875825f"]},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-c6756cce","v-9504490e","v-56536559","v-f58ec8f2","v-8534b9c2"]},descriptor:{key:"descriptor",scope:"tags",path:"/blog/tags/descriptor/",pageKeys:["v-c6756cce","v-9504490e","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-57698579","v-2c605799"]},"machine learning":{key:"machine learning",scope:"tags",path:"/blog/tags/machine learning/",pageKeys:["v-015729b9","v-57698579","v-2c605799"]},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-0119984e","v-0df1c3ce","v-1ac9ef4e","v-7c3d28f9","v-75d11339"]},"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-0119984e","v-0df1c3ce","v-1ac9ef4e","v-7c3d28f9","v-75d11339"]}},author:{"Steve Myers":{key:"Steve Myers",scope:"author",path:"/blog/author/Steve Myers/",pageKeys:["v-64f4dafd","v-9504490e","v-8534b9c2"]},"Daniela Brozzoni":{key:"Daniela Brozzoni",scope:"author",path:"/blog/author/Daniela Brozzoni/",pageKeys:["v-64f4dafd","v-aeb70fce"]},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"]},"Rajarshi Maitra":{key:"Rajarshi Maitra",scope:"author",path:"/blog/author/Rajarshi Maitra/",pageKeys:["v-7c0c45f9","v-07ff1843","v-ab5ba3ce"]},"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"]},thunderbiscuit:{key:"thunderbiscuit",scope:"author",path:"/blog/author/thunderbiscuit/",pageKeys:["v-3875825f","v-8534b9c2"]},"Gabriele Domenichini":{key:"Gabriele Domenichini",scope:"author",path:"/blog/author/Gabriele Domenichini/",pageKeys:["v-c6756cce"]},"Riccardo Casatta":{key:"Riccardo Casatta",scope:"author",path:"/blog/author/Riccardo Casatta/",pageKeys:["v-9504490e","v-015729b9","v-57698579","v-2c605799"]},"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-0119984e","v-0df1c3ce","v-1ac9ef4e","v-55969f39","v-7c3d28f9","v-75d11339"]},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 el{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:r}=this._metaMap[e];t.push({name:e,pages:n,path:r})}),t}getItemByName(t){return this._metaMap[t]}}var nl={blog:(t,e)=>{const r=n(45);return r(t.frontmatter.date)-r(e.frontmatter.date)>0?-1:1},tags:(t,e)=>{const r=n(45);return r(t.frontmatter.date)-r(e.frontmatter.date)>0?-1:1},author:(t,e)=>{const r=n(45);return r(t.frontmatter.date)-r(e.frontmatter.date)>0?-1:1}},rl={blog:function(t,e,n){return t.pid===n&&t.id===e},tags:function(t,e,n){const r=e;return["tags"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==r):n==r})},author:function(t,e,n){const r=e;return["author","authors"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==r):n==r})}},ol=[{pid:"blog",id:"blog",filter:rl.blog,sorter:nl.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,34]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/BDK/",interval:[0,9]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"project",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/project/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tutorial",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/tutorial/",interval:[0,7]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-cli",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bdk-cli/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"multi-sig",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/multi-sig/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"basics",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/basics/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"novice",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/novice/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"architecture",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/architecture/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Bitcoin Core",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Bitcoin Core/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"RPC",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/RPC/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Wallet",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Wallet/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK-RN",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/BDK-RN/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Development",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Development/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Architecture",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Architecture/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tor",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/tor/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"wallet",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/wallet/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"blockchain",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/blockchain/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bindings",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bindings/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"compact_filters",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/compact_filters/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BIP157",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/BIP157/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Neutrino",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Neutrino/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"guide",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/guide/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"descriptor",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/descriptor/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"paper wallets",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/paper wallets/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bitcoin/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"React Native",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/React Native/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Flutter",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Flutter/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"iOS",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/iOS/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Android",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Android/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"mobile",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/mobile/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-rn",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bdk-rn/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bdk/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"fee",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/fee/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"machine learning",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/machine learning/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"taproot",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/taproot/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"miniscript",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/miniscript/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Hardware Wallets",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Hardware Wallets/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin-cli",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bitcoin-cli/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"getting started",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/getting started/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"rust",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/rust/",interval:[0,9]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"coin selection",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/coin selection/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"development",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/development/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"summer of bitcoin",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/summer of bitcoin/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"security",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/security/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"release",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/release/",interval:[0,8]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Steve Myers",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Steve Myers/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Daniela Brozzoni",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Daniela Brozzoni/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"waterst0ne",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/waterst0ne/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Lloyd Fournier",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Lloyd Fournier/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Rajarshi Maitra",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Rajarshi Maitra/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Bitcoin Zavior",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Bitcoin Zavior/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"rorp",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/rorp/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"thunderbiscuit",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/thunderbiscuit/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Gabriele Domenichini",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Gabriele Domenichini/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Riccardo Casatta",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Riccardo Casatta/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Alekos Filini",filter:rl.author,sorter:nl.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:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Wszdexdrf/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Sandipan Dey",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Sandipan Dey/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"César Alvarez Vallero",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/César Alvarez Vallero/",interval:[0,1]}],prevText:"Prev",nextText:"Next"}],il=n(95);const al=n.n(il)()("plugin-blog:pagination");class cl{constructor(t,e,n){al("pagination",t);const{pages:r,prevText:o,nextText:i}=t,{path:a}=n;this._prevText=o,this._nextText=i;for(let t=0,e=r.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 ll=new class{constructor(t){this.paginations=t}get pages(){return Vn.$vuepress.$get("siteData").pages}getPagination(t,e,n){al("id",e),al("pid",t);const r=this.paginations.filter(n=>n.id===e&&n.pid===t)[0];return new cl(r,this.pages,n)}}(ol);var sl={comment:{enabled:!1,service:""},email:{enabled:!1},feed:{rss:!1,atom:!1,json:!1}},pl=[({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",Gc),document.addEventListener("keyup",t=>{qc(t)&&Gc(t)})})},{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({Vue:t})=>{t.component("CodeCopy",Sc)},({Vue:t})=>{t.component("Mermaid",Yc)},({Vue:t})=>t.use(Qc.a),{},{},({Vue:t})=>{const e=Object.keys(tl).map(t=>{const e=tl[t],n="$"+t;return{[n](){const{pages:t}=this.$site;return new el(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,ll.getPagination(t,e,this.$route)}}})},({Vue:t})=>{const e={$service:()=>sl};t.mixin({computed:e})}],ul=[];class dl 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(dl.prototype,{getPageAsyncComponent:ac,getLayoutAsyncComponent:cc,getAsyncComponent:lc,getVueComponent:sc});var gl={install(t){const e=new dl;t.$vuepress=e,t.prototype.$vuepress=e}};function hl(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var ml={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,ac(e)),Vn.component(e)?t(e):t("")}},fl={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},vl={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},bl=(n(249),n(250),Object(Kc.a)(vl,(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),yl={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(Wa),Vn.use(gl),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 r=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(r)),i={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),i),{computed:i}}(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 r in t)"/"===r?n=t[r]:0===this.$page.path.indexOf(r)&&(e=t[r]);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,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"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,r)=>{if(hl(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";hl(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";hl(t,o)?r(o):hl(t,n)?r(n):r()}})}(n);const r={};try{await Promise.all(pl.filter(t=>"function"==typeof t).map(e=>e({Vue:Vn,options:r,router:n,siteData:Uc,isServer:t})))}catch(t){console.error(t)}return{app:new Vn(Object.assign(r,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},ul.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file +var r=Object.freeze({}),o=Array.isArray;function i(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 u=Object.prototype.toString;function d(t){return"[object Object]"===u.call(t)}function g(t){return"[object RegExp]"===u.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)||d(t)&&t.toString===u?JSON.stringify(t,null,2):String(t)}function v(t){var e=parseFloat(t);return isNaN(e)?t:e}function b(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(r,1)}}var k=Object.prototype.hasOwnProperty;function _(t,e){return k.call(t,e)}function x(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var D=/-(\w)/g,B=x((function(t){return t.replace(D,(function(t,e){return e?e.toUpperCase():""}))})),P=x((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),K=/\B([A-Z])/g,S=x((function(t){return t.replace(K,"-$1").toLowerCase()}));var T=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>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,r=new Array(n);n--;)r[n]=t[n+e];return r}function O(t,e){for(var n in e)t[n]=e[n];return t}function A(t){for(var e={},n=0;n0,J=Z&&Z.indexOf("edge/")>0;Z&&Z.indexOf("android");var Q=Z&&/iphone|ipad|ipod|ios/.test(Z);Z&&/chrome\/\d+/.test(Z),Z&&/phantomjs/.test(Z);var tt,et=Z&&Z.match(/firefox\/(\d+)/),nt={}.watch,rt=!1;if(G)try{var ot={};Object.defineProperty(ot,"passive",{get:function(){rt=!0}}),window.addEventListener("test-passive",null,ot)}catch(t){}var it=function(){return void 0===tt&&(tt=!G&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=G&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ct(t){return"function"==typeof t&&/native code/.test(t.toString())}var lt,st="undefined"!=typeof Symbol&&ct(Symbol)&&"undefined"!=typeof Reflect&&ct(Reflect.ownKeys);lt="undefined"!=typeof Set&&ct(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 pt=null;function ut(t){void 0===t&&(t=null),t||pt&&pt._scope.off(),pt=t,t&&t._scope.on()}var dt=function(){function t(t,e,n,r,o,i,a,c){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,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}(),gt=function(t){void 0===t&&(t="");var e=new dt;return e.text=t,e.isComment=!0,e};function ht(t){return new dt(void 0,void 0,void 0,String(t))}function mt(t){var e=new dt(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}var ft=0,vt=[],bt=function(){function t(){this._pending=!1,this.id=ft++,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,vt.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,r=e.length;n0&&(Zt((s=t(s,"".concat(n||"","_").concat(r)))[0])&&Zt(u)&&(d[p]=ht(u.text+s[0].text),s.shift()),d.push.apply(d,s)):l(s)?Zt(u)?d[p]=ht(u.text+s):""!==s&&d.push(ht(s)):Zt(s)&&Zt(u)?d[p]=ht(u.text+s.text):(c(e._isVList)&&a(s.tag)&&i(s.key)&&a(n)&&(s.key="__vlist".concat(n,"_").concat(r,"__")),d.push(s)));return d}(t):void 0}function Zt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Xt(t,e){var n,r,i,c,l=null;if(o(t)||"string"==typeof t)for(l=new Array(t.length),n=0,r=t.length;n0,c=e?!!e.$stable:!a,l=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(c&&o&&o!==r&&l===o.$key&&!a&&!o.$hasNormal)return o;for(var s in i={},e)e[s]&&"$"!==s[0]&&(i[s]=me(t,n,s,e[s]))}else i={};for(var p in n)p in i||(i[p]=fe(n,p));return e&&Object.isExtensible(e)&&(e._normalized=i),H(i,"$stable",c),H(i,"$key",l),H(i,"$hasNormal",a),i}function me(t,e,n,r){var i=function(){var e=pt;ut(t);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==typeof n&&!o(n)?[n]:Gt(n))&&n[0];return ut(e),n&&(!i||1===n.length&&i.isComment&&!ge(i))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:i,enumerable:!0,configurable:!0}),i}function fe(t,e){return function(){return t[e]}}function ve(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),be(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||be(t._listenersProxy={},t.$listeners,r,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||we(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:T(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return It(t,e,n)}))}}}function be(t,e,n,r,o){var i=!1;for(var a in e)a in t?e[a]!==n[a]&&(i=!0):(i=!0,ye(t,a,r,o));for(var a in t)a in e||(i=!0,delete t[a]);return i}function ye(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function we(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var ke=null;function _e(t,e){return(t.__esModule||st&&"Module"===t[Symbol.toStringTag])&&(t=t.default),p(t)?e.extend(t):t}function xe(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(ln=function(){return sn.now()})}var pn=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(cn=ln(),on=!0,tn.sort(pn),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Re(un))}}function gn(t,e){if(t){for(var n=Object.create(null),r=st?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(i&&!_(o,"default"))a=!1;else if(""===a||a===S(t)){var l=$n(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,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var c=a.name;c&&!e(c)&&Yn(n,i,r,o)}}}function Yn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,w(n,e)}Vn.prototype._init=function(t){var e=this;e._uid=Wn++,e._isVue=!0,e.__v_skip=!0,e._scope=new Lt(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.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=Tn(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&&Ge(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?he(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,o){return De(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return De(t,e,n,r,o,!0)};var i=n&&n.data;Ot(t,"$attrs",i&&i.attrs||r,null,!0),Ot(t,"$listeners",e._parentListeners||r,null,!0)}(e),Qe(e,"beforeCreate",void 0,!1),function(t){var e=gn(t.$options.inject,t);e&&(Kt(!1),Object.keys(e).forEach((function(n){Ot(t,n,e[n])})),Kt(!0))}(e),Rn(e),function(t){var e=t.$options.provide;if(e){var n=s(e)?e.call(t):e;if(!p(n))return;for(var r=zt(t),o=st?Reflect.ownKeys(n):Object.keys(n),i=0;i1?C(n):n;for(var r=C(arguments,1),o='event handler for "'.concat(t,'"'),i=0,a=n.length;iparseInt(this.max)&&Yn(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)Yn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Xn(t,(function(t){return Zn(e,t)}))})),this.$watch("exclude",(function(e){Xn(t,(function(t){return!Zn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=xe(t),n=e&&e.componentOptions;if(n){var r=Gn(n),o=this.include,i=this.exclude;if(o&&(!r||!Zn(o,r))||i&&r&&Zn(i,r))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,w(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 z}};Object.defineProperty(t,"config",e),t.util={warn:_n,extend:O,mergeOptions:Tn,defineReactive:Ot},t.set=At,t.delete=Et,t.nextTick=Re,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,O(t.options.components,Qn),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=Tn(this.options,t),this}}(t),qn(t),function(t){N.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&d(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:it}),Object.defineProperty(Vn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Vn,"FunctionalRenderContext",{value:hn}),Vn.version="2.7.14";var tr=b("style,class"),er=b("input,textarea,option,select,progress"),nr=b("contenteditable,draggable,spellcheck"),rr=b("events,caret,typing,plaintext-only"),or=b("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"),ir="http://www.w3.org/1999/xlink",ar=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},cr=function(t){return ar(t)?t.slice(6,t.length):""},lr=function(t){return null==t||!1===t};function sr(t){for(var e=t.data,n=t,r=t;a(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=pr(r.data,e));for(;a(n=n.parent);)n&&n.data&&(e=pr(e,n.data));return function(t,e){if(a(t)||a(e))return ur(t,dr(e));return""}(e.staticClass,e.class)}function pr(t,e){return{staticClass:ur(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function ur(t,e){return t?e?t+" "+e:t:e||""}function dr(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?jr(t,e,n):or(e)?lr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return lr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):ar(e)?lr(n)?t.removeAttributeNS(ir,cr(e)):t.setAttributeNS(ir,e,n):jr(t,e,n)}function jr(t,e,n){if(lr(n))t.removeAttribute(e);else{if(X&&!Y&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Mr={create:Fr,update:Fr};function Rr(t,e){var n=e.elm,r=e.data,o=t.data;if(!(i(r.staticClass)&&i(r.class)&&(i(o)||i(o.staticClass)&&i(o.class)))){var c=sr(e),l=n._transitionClasses;a(l)&&(c=ur(c,dr(l))),c!==n._prevClass&&(n.setAttribute("class",c),n._prevClass=c)}}var Ir,Nr={create:Rr,update:Rr};function Lr(t,e,n){var r=Ir;return function o(){var i=e.apply(null,arguments);null!==i&&Wr(t,o,n,r)}}var zr=Ce&&!(et&&Number(et[1])<=53);function Ur(t,e,n,r){if(zr){var o=cn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}Ir.addEventListener(t,e,rt?{capture:n,passive:r}:n)}function Wr(t,e,n,r){(r||Ir).removeEventListener(t,e._wrapper||e,n)}function Hr(t,e){if(!i(t.data.on)||!i(e.data.on)){var n=e.data.on||{},r=t.data.on||{};Ir=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,r,Ur,Wr,Lr,e.context),Ir=void 0}}var Vr,qr={create:Hr,update:Hr,destroy:function(t){return Hr(t,xr)}};function Gr(t,e){if(!i(t.data.domProps)||!i(e.data.domProps)){var n,r,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=O({},s)),l)n in s||(o[n]="");for(n in s){if(r=s[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===l[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=r;var p=i(r)?"":String(r);Zr(o,p)&&(o.value=p)}else if("innerHTML"===n&&mr(o.tagName)&&i(o.innerHTML)){(Vr=Vr||document.createElement("div")).innerHTML="".concat(r,"");for(var u=Vr.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;u.firstChild;)o.appendChild(u.firstChild)}else if(r!==l[n])try{o[n]=r}catch(t){}}}}function Zr(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,r=t._vModifiers;if(a(r)){if(r.number)return v(n)!==v(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Xr={create:Gr,update:Gr},Yr=x((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Jr(t){var e=Qr(t.style);return t.staticStyle?O(t.staticStyle,e):e}function Qr(t){return Array.isArray(t)?A(t):"string"==typeof t?Yr(t):t}var to,eo=/^--/,no=/\s*!important$/,ro=function(t,e,n){if(eo.test(e))t.style.setProperty(e,n);else if(no.test(n))t.style.setProperty(S(e),n.replace(no,""),"important");else{var r=io(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(lo).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 po(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(lo).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")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function uo(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&O(e,go(t.name||"v")),O(e,t),e}return"string"==typeof t?go(t):void 0}}var go=x((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")}})),ho=G&&!Y,mo="transition",fo="transitionend",vo="animation",bo="animationend";ho&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(mo="WebkitTransition",fo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(vo="WebkitAnimation",bo="webkitAnimationEnd"));var yo=G?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function wo(t){yo((function(){yo(t)}))}function ko(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),so(t,e))}function _o(t,e){t._transitionClasses&&w(t._transitionClasses,e),po(t,e)}function xo(t,e,n){var r=Bo(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var c="transition"===o?fo:bo,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,u=i.length):"animation"===e?s>0&&(n="animation",p=s,u=l.length):u=(n=(p=Math.max(a,s))>0?a>s?"transition":"animation":null)?"transition"===n?i.length:l.length:0,{type:n,timeout:p,propCount:u,hasTransform:"transition"===n&&Do.test(r[mo+"Property"])}}function Po(t,e){for(;t.length1}function Ao(t,e){!0!==e.data.show&&So(e)}var Eo=function(t){var e,n,r={},s=t.modules,p=t.nodeOps;for(e=0;eh?w(t,i(n[v+1])?null:n[v+1].elm,n,g,v,r):g>v&&_(e,u,h)}(u,m,v,n,s):a(v)?(a(t.text)&&p.setTextContent(u,""),w(u,null,v,0,v.length-1,n)):a(m)?_(m,0,m.length-1):a(t.text)&&p.setTextContent(u,""):t.text!==e.text&&p.setTextContent(u,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 r=0;r-1,a.selected!==i&&(a.selected=i);else if(j(Ro(a),r))return void(t.selectedIndex!==c&&(t.selectedIndex=c));o||(t.selectedIndex=-1)}}function Mo(t,e){return e.every((function(e){return!j(e,t)}))}function Ro(t){return"_value"in t?t._value:t.value}function Io(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 zo(t){return!t.componentInstance||t.data&&t.data.transition?t:zo(t.componentInstance._vnode)}var Uo={model:Fo,show:{bind:function(t,e,n){var r=e.value,o=(n=zo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,So(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=zo(n)).data&&n.data.transition?(n.data.show=!0,r?So(n,(function(){t.style.display=t.__vOriginalDisplay})):To(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},Wo={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(xe(e.children)):t}function Vo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var r in o)e[B(r)]=o[r];return e}function qo(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Go=function(t){return t.tag||ge(t)},Zo=function(t){return"show"===t.name},Xo={name:"transition",props:Wo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Go)).length){0;var r=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 i=Ho(o);if(!i)return o;if(this._leaving)return qo(t,o);var a="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?a+"comment":a+i.tag:l(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var c=(i.data||(i.data={})).transition=Vo(this),s=this._vnode,p=Ho(s);if(i.data.directives&&i.data.directives.some(Zo)&&(i.data.show=!0),p&&p.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,p)&&!ge(p)&&(!p.componentInstance||!p.componentInstance._vnode.isComment)){var u=p.data.transition=O({},c);if("out-in"===r)return this._leaving=!0,Vt(u,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),qo(t,o);if("in-out"===r){if(ge(i))return s;var d,g=function(){d()};Vt(c,"afterEnter",g),Vt(c,"enterCancelled",g),Vt(u,"delayLeave",(function(t){d=t}))}}return o}}},Yo=O({tag:String,moveClass:String},Wo);function Jo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Qo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ti(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate(".concat(r,"px,").concat(o,"px)"),i.transitionDuration="0s"}}delete Yo.mode;var ei={Transition:Xo,TransitionGroup:{props:Yo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Xe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Vo(this),c=0;c-1?vr[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:vr[t]=/HTMLUnknownElement/.test(e.toString())},O(Vn.options.directives,Uo),O(Vn.options.components,ei),Vn.prototype.__patch__=G?Eo:E,Vn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=gt),Qe(t,"beforeMount"),r=function(){t._update(t._render(),n)},new We(t,r,E,{before:function(){t._isMounted&&!t._isDestroyed&&Qe(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var i=0;i=0&&(e=t.slice(r),t=t.slice(0,r));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?_i(l.path,s,n||o.append):s,u=function(t,e,n){void 0===e&&(e={});var r,o=n||si;try{r=o(t||"")}catch(t){r={}}for(var i in e){var a=e[i];r[i]=Array.isArray(a)?a.map(li):li(a)}return r}(l.query,o.query,r&&r.options.parseQuery),d=o.hash||l.hash;return d&&"#"!==d.charAt(0)&&(d="#"+d),{_normalized:!0,path:p,query:u,hash:d}}var Ui,Wi=function(){},Hi={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,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,c=o.href,l={},s=n.options.linkActiveClass,p=n.options.linkExactActiveClass,u=null==s?"router-link-active":s,d=null==p?"router-link-exact-active":p,g=null==this.activeClass?u:this.activeClass,h=null==this.exactActiveClass?d:this.exactActiveClass,m=a.redirectedFrom?di(null,zi(a.redirectedFrom),null,n):a;l[h]=vi(r,m,this.exactPath),l[g]=this.exact||this.exactPath?l[h]:function(t,e){return 0===t.path.replace(ui,"/").indexOf(e.path.replace(ui,"/"))&&(!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)}(r,m);var f=l[h]?this.ariaCurrentValue:null,v=function(t){Vi(t)&&(e.replace?n.replace(i,Wi):n.push(i,Wi))},b={click:Vi};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 r=0;r-1&&(c.params[d]=n.params[d]);return c.path=Li(p.path,c.params),l(p,c,a)}if(c.path){c.params={};for(var g=0;g-1}function xa(t,e){return _a(t)&&t._isRouter&&(null==e||t.type===e)}function Da(t,e,n){var r=function(o){o>=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function Ba(t){return function(e,n,r){var o=!1,i=0,a=null;Pa(t,(function(t,e,n,c){if("function"==typeof t&&void 0===t.cid){o=!0,i++;var l,s=Ta((function(e){var o;((o=e).__esModule||Sa&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:Ui.extend(e),n.components[c]=e,--i<=0&&r()})),p=Ta((function(t){var e="Failed to resolve async component "+c+": "+t;a||(a=_a(t)?t:new Error(e),r(a))}));try{l=t(s,p)}catch(t){p(t)}if(l)if("function"==typeof l.then)l.then(s,p);else{var u=l.component;u&&"function"==typeof u.then&&u.then(s,p)}}})),o||r()}}function Pa(t,e){return Ka(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Ka(t){return Array.prototype.concat.apply([],t)}var Sa="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ta(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var Ca=function(t,e){this.router=t,this.base=function(t){if(!t)if(qi){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=hi,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Oa(t,e,n,r){var o=Pa(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=Ui.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return Ka(r?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 r,o=this;try{r=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),e&&e(r),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(r)})))}),(function(t){n&&n(t),t&&!o.ready&&(xa(t,va.redirected)&&i===hi||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},Ca.prototype.confirmTransition=function(t,e,n){var r=this,o=this.current;this.pending=t;var i,a,c=function(t){!xa(t)&&_a(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},l=t.matched.length-1,s=o.matched.length-1;if(vi(t,o)&&l===s&&t.matched[l]===o.matched[s])return this.ensureURL(),t.hash&&ia(this.router,o,t,!1),c(((a=wa(i=o,t,va.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var p=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=ha&&n;r&&this.listeners.push(oa());var o=function(){var n=t.current,o=Fa(t.base);t.current===hi&&o===t._startLocation||t.transitionTo(o,(function(t){r&&ia(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 r=this,o=this.current;this.transitionTo(t,(function(t){ma(xi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){fa(xi(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Fa(this.base)!==this.current.fullPath){var e=xi(this.base+this.current.fullPath);t?ma(e):fa(e)}},e.prototype.getCurrentLocation=function(){return Fa(this.base)},e}(Ca);function Fa(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(xi(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var $a=function(t){function e(e,n,r){t.call(this,e,n),r&&function(t){var e=Fa(t);if(!/^\/#/.test(e))return window.location.replace(xi(t+"/#"+e)),!0}(this.base)||ja()}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=ha&&e;n&&this.listeners.push(oa());var r=function(){var e=t.current;ja()&&t.transitionTo(Ma(),(function(r){n&&ia(t.router,r,e,!0),ha||Na(r.fullPath)}))},o=ha?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Ia(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Na(t.fullPath),ia(r.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;Ma()!==e&&(t?Ia(e):Na(e))},e.prototype.getCurrentLocation=function(){return Ma()},e}(Ca);function ja(){var t=Ma();return"/"===t.charAt(0)||(Na("/"+t),!1)}function Ma(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Ra(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Ia(t){ha?ma(Ra(t)):window.location.hash=t}function Na(t){ha?fa(Ra(t)):window.location.replace(Ra(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 r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.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 r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){xa(t,va.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),za=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Xi(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ha&&!1!==t.fallback,this.fallback&&(e="hash"),qi||(e="abstract"),this.mode=e,e){case"history":this.history=new Ea(this,t.base);break;case"hash":this.history=new $a(this,t.base,this.fallback);break;case"abstract":this.history=new La(this,t.base);break;default:0}},Ua={currentRoute:{configurable:!0}};za.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},Ua.currentRoute.get=function(){return this.history&&this.history.current},za.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 $a){var r=function(t){n.setupListeners(),function(t){var r=n.current,o=e.options.scrollBehavior;ha&&o&&"fullPath"in t&&ia(e,t,r,!1)}(t)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},za.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},za.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},za.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},za.prototype.onReady=function(t,e){this.history.onReady(t,e)},za.prototype.onError=function(t){this.history.onError(t)},za.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},za.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},za.prototype.go=function(t){this.history.go(t)},za.prototype.back=function(){this.go(-1)},za.prototype.forward=function(){this.go(1)},za.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]}))}))):[]},za.prototype.resolve=function(t,e,n){var r=zi(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?xi(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},za.prototype.getRoutes=function(){return this.matcher.getRoutes()},za.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},za.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(za.prototype,Ua);var Wa=za;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}za.install=function t(e){if(!t.installed||Ui!==e){t.installed=!0,Ui=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(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,r(this,this)},destroyed:function(){r(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",wi),e.component("RouterLink",Hi);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},za.version="3.6.5",za.isNavigationFailure=xa,za.NavigationFailureType=va,za.START_LOCATION=hi,qi&&window.Vue&&window.Vue.use(za);n(53);n(100),n(46);var Va={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(23)]).then(n.bind(null,318)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(22)]).then(n.bind(null,287)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(32)]).then(n.bind(null,262)),"components/Home":()=>Promise.all([n.e(0),n.e(27)]).then(n.bind(null,319)),"components/NavLink":()=>n.e(35).then(n.bind(null,254)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(20)]).then(n.bind(null,276)),"components/Navbar":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,286)),"components/Page":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,298)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(28)]).then(n.bind(null,288)),"components/PageNav":()=>Promise.all([n.e(0),n.e(24)]).then(n.bind(null,289)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,269)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(33)]).then(n.bind(null,321)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,265)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(30)]).then(n.bind(null,263)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(7)]).then(n.bind(null,256)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,382)),"global-components/CodeBlock":()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,372)),"global-components/CodeGroup":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,373)),"layouts/404":()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,374)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,375)),NotFound:()=>Promise.all([n.e(0),n.e(1),n.e(6)]).then(n.bind(null,374)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(3)]).then(n.bind(null,375)),"components/Cases":()=>Promise.all([n.e(0),n.e(25)]).then(n.bind(null,320)),"components/Footer":()=>Promise.all([n.e(0),n.e(26)]).then(n.bind(null,270)),"components/LayoutWrap":()=>Promise.all([n.e(0),n.e(1),n.e(17)]).then(n.bind(null,277)),"components/PostMeta":()=>Promise.all([n.e(0),n.e(29)]).then(n.bind(null,299)),"layouts/DirectoryPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,376)),"layouts/FrontmatterKey":()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,377)),"layouts/FrontmatterPagination":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,378)),"layouts/IndexPost":()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,317)),"layouts/Post":()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,379)),DirectoryPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(11)]).then(n.bind(null,376)),FrontmatterKey:()=>Promise.all([n.e(0),n.e(1),n.e(5)]).then(n.bind(null,377)),FrontmatterPagination:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(12)]).then(n.bind(null,378)),IndexPost:()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,317)),Post:()=>Promise.all([n.e(0),n.e(1),n.e(4)]).then(n.bind(null,379))},qa={"v-330a32a2":()=>n.e(37).then(n.bind(null,383)),"v-64f4dafd":()=>n.e(38).then(n.bind(null,384)),"v-7c0c45f9":()=>n.e(39).then(n.bind(null,385)),"v-0f4d5d15":()=>n.e(41).then(n.bind(null,386)),"v-8bd632d6":()=>n.e(40).then(n.bind(null,387)),"v-2cebe183":()=>n.e(34).then(n.bind(null,388)),"v-3eaa044d":()=>n.e(31).then(n.bind(null,389)),"v-353b78e1":()=>n.e(42).then(n.bind(null,390)),"v-3875825f":()=>n.e(43).then(n.bind(null,391)),"v-9504490e":()=>n.e(45).then(n.bind(null,392)),"v-07ff1843":()=>n.e(44).then(n.bind(null,393)),"v-c6756cce":()=>n.e(46).then(n.bind(null,394)),"v-56536559":()=>n.e(19).then(n.bind(null,395)),"v-f58ec8f2":()=>n.e(21).then(n.bind(null,396)),"v-015729b9":()=>n.e(47).then(n.bind(null,397)),"v-2c605799":()=>n.e(48).then(n.bind(null,398)),"v-57698579":()=>n.e(49).then(n.bind(null,399)),"v-9145467a":()=>n.e(50).then(n.bind(null,400)),"v-2cf72b39":()=>n.e(51).then(n.bind(null,401)),"v-11d64359":()=>n.e(52).then(n.bind(null,402)),"v-5d749fce":()=>n.e(53).then(n.bind(null,403)),"v-ab5ba3ce":()=>n.e(54).then(n.bind(null,404)),"v-d0375c8e":()=>n.e(55).then(n.bind(null,405)),"v-10852eea":()=>n.e(56).then(n.bind(null,406)),"v-edd5570e":()=>n.e(57).then(n.bind(null,407)),"v-05df4999":()=>n.e(58).then(n.bind(null,408)),"v-faad828e":()=>n.e(59).then(n.bind(null,409)),"v-0df1c3ce":()=>n.e(62).then(n.bind(null,410)),"v-0119984e":()=>n.e(60).then(n.bind(null,411)),"v-7c3d28f9":()=>n.e(61).then(n.bind(null,412)),"v-75d11339":()=>n.e(63).then(n.bind(null,413)),"v-1ac9ef4e":()=>n.e(64).then(n.bind(null,414)),"v-55969f39":()=>n.e(65).then(n.bind(null,415)),"v-8534b9c2":()=>n.e(66).then(n.bind(null,416)),"v-aeb70fce":()=>n.e(67).then(n.bind(null,417)),"v-009133c8":()=>n.e(68).then(n.bind(null,418)),"v-3acb6e6a":()=>n.e(71).then(n.bind(null,419)),"v-7a315e41":()=>n.e(69).then(n.bind(null,420)),"v-f611a14e":()=>n.e(70).then(n.bind(null,421)),"v-496cb7f9":()=>n.e(72).then(n.bind(null,380)),"v-0b3b65ea":()=>n.e(73).then(n.bind(null,422)),"v-a76bccee":()=>n.e(74).then(n.bind(null,423)),"v-05d01c19":()=>n.e(75).then(n.bind(null,424)),"v-a9236c10":()=>n.e(77).then(n.bind(null,425)),"v-11bf335e":()=>n.e(76).then(n.bind(null,426)),"v-29f9f21c":()=>n.e(78).then(n.bind(null,427)),"v-287ca6ff":()=>n.e(79).then(n.bind(null,428)),"v-4bcdac39":()=>n.e(80).then(n.bind(null,429)),"v-5245a0b2":()=>n.e(81).then(n.bind(null,430))};function Ga(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Za=/-(\w)/g,Xa=Ga(t=>t.replace(Za,(t,e)=>e?e.toUpperCase():"")),Ya=/\B([A-Z])/g,Ja=Ga(t=>t.replace(Ya,"-$1").toLowerCase()),Qa=Ga(t=>t.charAt(0).toUpperCase()+t.slice(1));function tc(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Qa(Xa(e))):t(Qa(e))||t(Ja(e))}const ec=Object.assign({},Va,qa),nc=t=>ec[t],rc=t=>qa[t],oc=t=>Va[t],ic=t=>Vn.component(t);function ac(t){return tc(rc,t)}function cc(t){return tc(oc,t)}function lc(t){return tc(nc,t)}function sc(t){return tc(ic,t)}function pc(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!sc(t)&&lc(t)){const e=await lc(t)();Vn.component(t,e.default)}}))}function uc(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var dc=n(91),gc=n.n(dc),hc=n(92),mc=n.n(hc),fc={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}="${mc()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=bc(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=yc(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return gc()([{name:"description",content:this.$description}],t,this.siteMeta,wc)},updateCanonicalLink(){vc(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",bc(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){yc(null,this.currentMetaTags),vc()}};function vc(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function bc(t=""){return t?``:""}function yc(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 wc(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var kc=n(93),_c={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(kc)()((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),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},xc=n(22),Dc=n.n(xc),Bc={mounted(){Dc.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Vn.component(t.name)||Dc.a.start(),n()}),this.$router.afterEach(()=>{Dc.a.done(),this.isSidebarOpen=!1})}},Pc={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)}}},Kc=(n(240),n(7)),Sc=Object(Kc.a)(Pc,(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,Tc=(n(241),{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(Sc));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=(n(242),Object.assign||function(t){for(var e=1;e1&&void 0!==arguments[1]?arguments[1]:{},r=window.Promise||function(t){function e(){}t(e,e)},o=function(t){var e=t.target;e!==B?-1!==y.indexOf(e)&&m({target:e}):h()},i=function(){if(!k&&D.original){var t=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(_-t)>x.scrollOffset&&setTimeout(h,150)}},a=function(t){var e=t.key||t.keyCode;"Escape"!==e&&"Esc"!==e&&27!==e||h()},c=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t;if(t.background&&(B.style.background=t.background),t.container&&t.container instanceof Object&&(e.container=Cc({},x.container,t.container)),t.template){var n=Ac(t.template)?t.template:document.querySelector(t.template);e.template=n}return x=Cc({},x,e),y.forEach((function(t){t.dispatchEvent(Mc("medium-zoom:update",{detail:{zoom:P}}))})),P},l=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return t(Cc({},x,e))},s=function(){for(var t=arguments.length,e=Array(t),n=0;n0?e.reduce((function(t,e){return[].concat(t,Fc(e))}),[]):y;return r.forEach((function(t){t.classList.remove("medium-zoom-image"),t.dispatchEvent(Mc("medium-zoom:detach",{detail:{zoom:P}}))})),y=y.filter((function(t){return-1===r.indexOf(t)})),P},u=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return y.forEach((function(r){r.addEventListener("medium-zoom:"+t,e,n)})),w.push({type:"medium-zoom:"+t,listener:e,options:n}),P},d=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return y.forEach((function(r){r.removeEventListener("medium-zoom:"+t,e,n)})),w=w.filter((function(n){return!(n.type==="medium-zoom:"+t&&n.listener.toString()===e.toString())})),P},g=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target,n=function(){var t={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},e=void 0,n=void 0;if(x.container)if(x.container instanceof Object)e=(t=Cc({},t,x.container)).width-t.left-t.right-2*x.margin,n=t.height-t.top-t.bottom-2*x.margin;else{var r=(Ac(x.container)?x.container:document.querySelector(x.container)).getBoundingClientRect(),o=r.width,i=r.height,a=r.left,c=r.top;t=Cc({},t,{width:o,height:i,left:a,top:c})}e=e||t.width-2*x.margin,n=n||t.height-2*x.margin;var l=D.zoomedHd||D.original,s=Ec(l)?e:l.naturalWidth||e,p=Ec(l)?n:l.naturalHeight||n,u=l.getBoundingClientRect(),d=u.top,g=u.left,h=u.width,m=u.height,f=Math.min(Math.max(h,s),e)/h,v=Math.min(Math.max(m,p),n)/m,b=Math.min(f,v),y="scale("+b+") translate3d("+((e-h)/2-g+x.margin+t.left)/b+"px, "+((n-m)/2-d+x.margin+t.top)/b+"px, 0)";D.zoomed.style.transform=y,D.zoomedHd&&(D.zoomedHd.style.transform=y)};return new r((function(t){if(e&&-1===y.indexOf(e))t(P);else{if(D.zoomed)t(P);else{if(e)D.original=e;else{if(!(y.length>0))return void t(P);var r=y;D.original=r[0]}if(D.original.dispatchEvent(Mc("medium-zoom:open",{detail:{zoom:P}})),_=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,k=!0,D.zoomed=jc(D.original),document.body.appendChild(B),x.template){var o=Ac(x.template)?x.template:document.querySelector(x.template);D.template=document.createElement("div"),D.template.appendChild(o.content.cloneNode(!0)),document.body.appendChild(D.template)}if(D.original.parentElement&&"PICTURE"===D.original.parentElement.tagName&&D.original.currentSrc&&(D.zoomed.src=D.original.currentSrc),document.body.appendChild(D.zoomed),window.requestAnimationFrame((function(){document.body.classList.add("medium-zoom--opened")})),D.original.classList.add("medium-zoom-image--hidden"),D.zoomed.classList.add("medium-zoom-image--opened"),D.zoomed.addEventListener("click",h),D.zoomed.addEventListener("transitionend",(function e(){k=!1,D.zoomed.removeEventListener("transitionend",e),D.original.dispatchEvent(Mc("medium-zoom:opened",{detail:{zoom:P}})),t(P)})),D.original.getAttribute("data-zoom-src")){D.zoomedHd=D.zoomed.cloneNode(),D.zoomedHd.removeAttribute("srcset"),D.zoomedHd.removeAttribute("sizes"),D.zoomedHd.removeAttribute("loading"),D.zoomedHd.src=D.zoomed.getAttribute("data-zoom-src"),D.zoomedHd.onerror=function(){clearInterval(i),console.warn("Unable to reach the zoom image target "+D.zoomedHd.src),D.zoomedHd=null,n()};var i=setInterval((function(){D.zoomedHd.complete&&(clearInterval(i),D.zoomedHd.classList.add("medium-zoom-image--opened"),D.zoomedHd.addEventListener("click",h),document.body.appendChild(D.zoomedHd),n())}),10)}else if(D.original.hasAttribute("srcset")){D.zoomedHd=D.zoomed.cloneNode(),D.zoomedHd.removeAttribute("sizes"),D.zoomedHd.removeAttribute("loading");var a=D.zoomedHd.addEventListener("load",(function(){D.zoomedHd.removeEventListener("load",a),D.zoomedHd.classList.add("medium-zoom-image--opened"),D.zoomedHd.addEventListener("click",h),document.body.appendChild(D.zoomedHd),n()}))}else n()}}}))},h=function(){return new r((function(t){if(!k&&D.original){k=!0,document.body.classList.remove("medium-zoom--opened"),D.zoomed.style.transform="",D.zoomedHd&&(D.zoomedHd.style.transform=""),D.template&&(D.template.style.transition="opacity 150ms",D.template.style.opacity=0),D.original.dispatchEvent(Mc("medium-zoom:close",{detail:{zoom:P}})),D.zoomed.addEventListener("transitionend",(function e(){D.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(D.zoomed),D.zoomedHd&&document.body.removeChild(D.zoomedHd),document.body.removeChild(B),D.zoomed.classList.remove("medium-zoom-image--opened"),D.template&&document.body.removeChild(D.template),k=!1,D.zoomed.removeEventListener("transitionend",e),D.original.dispatchEvent(Mc("medium-zoom:closed",{detail:{zoom:P}})),D.original=null,D.zoomed=null,D.zoomedHd=null,D.template=null,t(P)}))}else t(P)}))},m=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.target;return D.original?h():g({target:e})},f=function(){return x},v=function(){return y},b=function(){return D.original},y=[],w=[],k=!1,_=0,x=n,D={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(e)?x=e:(e||"string"==typeof e)&&s(e),x=Cc({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},x);var B=$c(x.background);document.addEventListener("click",o),document.addEventListener("keyup",a),document.addEventListener("scroll",i),window.addEventListener("resize",h);var P={open:g,close:h,toggle:m,update:c,clone:l,attach:s,detach:p,on:u,off:d,getOptions:f,getImages:v,getZoomedImage:b};return P},Ic=[fc,_c,Bc,Tc,{data:()=>({zoom:null}),mounted(){this.updateZoom()},updated(){this.updateZoom()},methods:{updateZoom(){setTimeout(()=>{this.zoom&&this.zoom.detach(),this.zoom=Rc(".theme-default-content :not(a) > img",void 0)},1e3)}}}],Nc={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"}}},Lc=Object(Kc.a)(Nc,(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.")}}(Lc,"mixins",Ic);const zc=[{name:"v-330a32a2",path:"/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-330a32a2").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-64f4dafd",path:"/blog/_2024-q4-update/",component:Lc,beforeEnter:(t,e,n)=>{pc("Post","v-64f4dafd").then(n)}},{path:"/blog/_2024-q4-update/index.html",redirect:"/blog/_2024-q4-update/"},{path:"/_blog/2024_q4_update.html",redirect:"/blog/_2024-q4-update/"},{name:"v-7c0c45f9",path:"/blog/bitcoin-core-rpc-demo/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-0f4d5d15",path:"/blog/bdk-cli-basics/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-8bd632d6",path:"/blog/bdk-cli-basics-multisig-2of3/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-2cebe183",path:"/blog/bdk-core-pt1/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-9504490e",path:"/blog/descriptor-based-paper-wallet/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-07ff1843",path:"/blog/compact-filters-demo/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-c6756cce",path:"/blog/descriptors-in-the-wild/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-56536559",path:"/blog/exploring-bdk-flutter/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-2c605799",path:"/blog/2021/01/fee-estimation-for-light-clients-part-2/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-0df1c3ce",path:"/blog/2021/05/release-v0.7.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-0119984e",path:"/blog/2021/03/release-v0.5.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-7c3d28f9",path:"/blog/2021/04/release-v0.6.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-75d11339",path:"/blog/2021/06/release-v0.8.0/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-009133c8",path:"/bdk-cli/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-009133c8").then(n)}},{path:"/bdk-cli/index.html",redirect:"/bdk-cli/"},{name:"v-3acb6e6a",path:"/bdk-cli/installation/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-7a315e41",path:"/bdk-cli/compiler/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-496cb7f9",path:"/bdk-cli/interface/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-a9236c10",path:"/descriptors/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-a9236c10").then(n)}},{path:"/descriptors/index.html",redirect:"/descriptors/"},{name:"v-11bf335e",path:"/case-studies/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-11bf335e").then(n)}},{path:"/case-studies/index.html",redirect:"/case-studies/"},{path:"/case-studies.html",redirect:"/case-studies/"},{name:"v-29f9f21c",path:"/examples/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-29f9f21c").then(n)}},{path:"/examples/index.html",redirect:"/examples/"},{name:"v-287ca6ff",path:"/foundation/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-287ca6ff").then(n)}},{path:"/foundation/index.html",redirect:"/foundation/"},{path:"/foundation.html",redirect:"/foundation/"},{name:"v-4bcdac39",path:"/getting-started/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-4bcdac39").then(n)}},{path:"/getting-started/index.html",redirect:"/getting-started/"},{path:"/getting-started.html",redirect:"/getting-started/"},{name:"v-5245a0b2",path:"/supporters/",component:Lc,beforeEnter:(t,e,n)=>{pc("Layout","v-5245a0b2").then(n)}},{path:"/supporters/index.html",redirect:"/supporters/"},{name:"v-424df898",path:"/blog/",component:Lc,beforeEnter:(t,e,n)=>{pc("IndexPost","v-424df898").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/index.html",redirect:"/blog/"},{name:"v-619df59e",path:"/blog/tags/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-398e8fd4").then(n)},meta:{pid:"tags",id:"project"}},{path:"/blog/tags/project/index.html",redirect:"/blog/tags/project/"},{name:"v-da8c869a",path:"/blog/tags/tutorial/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-e646a928",path:"/blog/tags/basics/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-1fb58ffb").then(n)},meta:{pid:"tags",id:"novice"}},{path:"/blog/tags/novice/index.html",redirect:"/blog/tags/novice/"},{name:"v-655ee4a0",path:"/blog/tags/multi-sig/",component:Lc,beforeEnter:(t,e,n)=>{pc("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-c4494744",path:"/blog/tags/architecture/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-1296a8fa").then(n)},meta:{pid:"tags",id:"bindings"}},{path:"/blog/tags/bindings/index.html",redirect:"/blog/tags/bindings/"},{name:"v-a9e0285e",path:"/blog/tags/guide/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-baacba64",path:"/blog/tags/compact_filters/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-4fed1c23").then(n)},meta:{pid:"tags",id:"Neutrino"}},{path:"/blog/tags/Neutrino/index.html",redirect:"/blog/tags/Neutrino/"},{name:"v-915f8322",path:"/blog/tags/bitcoin/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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-82e16b5c",path:"/blog/author/Rajarshi Maitra/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-d2b26530").then(n)},meta:{pid:"author",id:"rorp"}},{path:"/blog/author/rorp/index.html",redirect:"/blog/author/rorp/"},{name:"v-5d54001e",path:"/blog/author/thunderbiscuit/",component:Lc,beforeEnter:(t,e,n)=>{pc("FrontmatterPagination","v-5d54001e").then(n)},meta:{pid:"author",id:"thunderbiscuit"}},{path:"/blog/author/thunderbiscuit/index.html",redirect:"/blog/author/thunderbiscuit/"},{name:"v-624fd61e",path:"/blog/author/Riccardo Casatta/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc,beforeEnter:(t,e,n)=>{pc("DirectoryPagination","v-c3507b3a").then(n)},meta:{pid:"blog",id:"blog"}},{path:"/blog/page/4/index.html",redirect:"/blog/page/4/"},{name:"v-5f2ac9cb",path:"/blog/author/Alekos Filini/page/2/",component:Lc,beforeEnter:(t,e,n)=>{pc("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:Lc}],Uc={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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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/2024_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/2024_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/2024_q4_update.html",relativePath:"_blog/2024_q4_update.md",key:"v-64f4dafd",path:"/blog/_2024-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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{title:"BDK-CLI",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"BDK-CLI"},{property:"og:description",content:"The bdk-clihttps://github.com/bitcoindevkit/bdk-cli repo has an example interactive shell built\nusing the `bdk` library called `bdk-cli` that acts both as a reference implementation of a wallet\nand a tool to quickly experiment with descriptors and transactions."},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/bdk-cli/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"BDK-CLI"},{name:"twitter:description",content:"The bdk-clihttps://github.com/bitcoindevkit/bdk-cli repo has an example interactive shell built\nusing the `bdk` library called `bdk-cli` that acts both as a reference implementation of a wallet\nand a tool to quickly experiment with descriptors and transactions."},{name:"twitter:url",content:"https://bitcoindevkit.org/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:"/bdk-cli/",relativePath:"bdk-cli/README.md",key:"v-009133c8",path:"/bdk-cli/",codeSwitcherOptions:{},lastUpdated:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{title:"Bitcoin Dev Kit Foundation",frontmatter:{sidebar:!1,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.html",relativePath:"foundation.md",key:"v-287ca6ff",path:"/foundation/",headers:[{level:2,title:"Board",slug:"board"},{level:2,title:"Operations",slug:"operations"}],codeSwitcherOptions:{},lastUpdated:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{title:"Supporters",frontmatter:{meta:[{property:"og:site_name",content:"Bitcoin Dev Kit Documentation"},{property:"og:title",content:"Supporters"},{property:"og:description",content:"The Bitcoin Dev Kit project is proudly supported by:"},{property:"og:type",content:"article"},{property:"og:url",content:"https://bitcoindevkit.org/supporters/"},{property:"og:image",content:"https://bitcoindevkit.org/card.png"},{name:"twitter:title",content:"Supporters"},{name:"twitter:description",content:"The Bitcoin Dev Kit project is proudly supported by:"},{name:"twitter:url",content:"https://bitcoindevkit.org/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:"/supporters/",relativePath:"supporters/README.md",key:"v-5245a0b2",path:"/supporters/",codeSwitcherOptions:{},lastUpdated:"4/18/2024, 7:43:52 AM",lastUpdatedTimestamp:1713426232e3},{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:"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:"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:"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:"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:"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:"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:"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:"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:"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:"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:"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:"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:"Case Studies",link:"/case-studies"},{text:"Foundation",link:"/foundation"},{text:"Blog",link:"/blog/"}],sidebar:{"/_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"]]}],"/tutorials/":[{title:"Tutorials",collapsable:!1,children:["/tutorials/hello-world","/tutorials/Bitcoin_Core_RPC_Demo","/tutorials/compact_filters_demo","/tutorials/descriptors_in_the_wild","/tutorials/hidden-power-of-bitcoin","/tutorials/descriptor_based_paper_wallet","/tutorials/spending_policy_demo","/tutorials/exploring_bdk_rn","/tutorials/using_bdk_with_hardware_wallets","/tutorials/exploring_bdk_flutter","/tutorials/bdk_cli_basics","/tutorials/bdk-cli_basics_multisig_2of3","/tutorials/bdk_with_tor"]}],"/":[{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/","Rust Stable Docs"],["https://bitcoindevkit.org/docs-rs/bdk/nightly/latest/bdk/","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:"/supporters/"},{text:"BDK Foundation",link:"/foundation"}]}],copyright:"Copyright © 2024 BDK Developers"}}},{COLOR_MODES:Wc,STORE_ATTR:Hc,setColorMode:Vc}=n(111),qc=t=>"Enter"===t.code||13===(t.keyCode||t.which),Gc=t=>{const e=t.target.matches("#algolia-search-input")&&qc(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?Wc[1]:Wc[0],e=window.localStorage.getItem(Hc);Vc(Wc.includes(e)?e:t)}n(243);Vn.component("Badge",()=>Promise.all([n.e(0),n.e(8)]).then(n.bind(null,382))),Vn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,372))),Vn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,373)));n(244);var Zc={props:{color:{required:!1,default:"rgb(66, 185, 131)"}}},Xc=(n(245),Object(Kc.a)(Zc,(function(){return(0,this._self._c)("div",{staticClass:"spinner",style:{background:this.color}})}),[],!1,null,"1bbcb91a",null).exports);const Yc={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(82).then(n.t.bind(null,368,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:Xc}};var Jc=n(94),Qc=n.n(Jc);n(246);Vn.component("CodeSwitcher",()=>n.e(36).then(n.bind(null,381)));var tl={tags:{BDK:{key:"BDK",scope:"tags",path:"/blog/tags/BDK/",pageKeys:["v-64f4dafd","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-64f4dafd"]},tutorial:{key:"tutorial",scope:"tags",path:"/blog/tags/tutorial/",pageKeys:["v-7c0c45f9","v-8bd632d6","v-353b78e1","v-07ff1843","v-56536559","v-f58ec8f2","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-0f4d5d15","v-8bd632d6","v-07ff1843","v-ab5ba3ce"]},basics:{key:"basics",scope:"tags",path:"/blog/tags/basics/",pageKeys:["v-0f4d5d15"]},novice:{key:"novice",scope:"tags",path:"/blog/tags/novice/",pageKeys:["v-0f4d5d15"]},"multi-sig":{key:"multi-sig",scope:"tags",path:"/blog/tags/multi-sig/",pageKeys:["v-8bd632d6"]},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-56536559","v-f58ec8f2"]},blockchain:{key:"blockchain",scope:"tags",path:"/blog/tags/blockchain/",pageKeys:["v-353b78e1"]},bindings:{key:"bindings",scope:"tags",path:"/blog/tags/bindings/",pageKeys:["v-3875825f"]},guide:{key:"guide",scope:"tags",path:"/blog/tags/guide/",pageKeys:["v-9504490e","v-c6756cce","v-56536559","v-f58ec8f2","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"]},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"]},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"]},"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-0df1c3ce","v-0119984e","v-7c3d28f9","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-edd5570e","v-05df4999","v-faad828e","v-0df1c3ce","v-0119984e","v-7c3d28f9","v-75d11339","v-1ac9ef4e"]}},author:{"Steve Myers":{key:"Steve Myers",scope:"author",path:"/blog/author/Steve Myers/",pageKeys:["v-64f4dafd","v-9504490e","v-8534b9c2"]},"Daniela Brozzoni":{key:"Daniela Brozzoni",scope:"author",path:"/blog/author/Daniela Brozzoni/",pageKeys:["v-64f4dafd","v-aeb70fce"]},"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-0f4d5d15","v-8bd632d6"]},"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"]},thunderbiscuit:{key:"thunderbiscuit",scope:"author",path:"/blog/author/thunderbiscuit/",pageKeys:["v-3875825f","v-8534b9c2"]},"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-0df1c3ce","v-0119984e","v-7c3d28f9","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 el{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:r}=this._metaMap[e];t.push({name:e,pages:n,path:r})}),t}getItemByName(t){return this._metaMap[t]}}var nl={blog:(t,e)=>{const r=n(45);return r(t.frontmatter.date)-r(e.frontmatter.date)>0?-1:1},tags:(t,e)=>{const r=n(45);return r(t.frontmatter.date)-r(e.frontmatter.date)>0?-1:1},author:(t,e)=>{const r=n(45);return r(t.frontmatter.date)-r(e.frontmatter.date)>0?-1:1}},rl={blog:function(t,e,n){return t.pid===n&&t.id===e},tags:function(t,e,n){const r=e;return["tags"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==r):n==r})},author:function(t,e,n){const r=e;return["author","authors"].some(e=>{const n=t.frontmatter[e];return Array.isArray(n)?n.some(t=>t==r):n==r})}},ol=[{pid:"blog",id:"blog",filter:rl.blog,sorter:nl.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,34]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/BDK/",interval:[0,9]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"project",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/project/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tutorial",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/tutorial/",interval:[0,7]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Bitcoin Core",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Bitcoin Core/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"RPC",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/RPC/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Wallet",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Wallet/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-cli",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bdk-cli/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"basics",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/basics/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"novice",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/novice/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"multi-sig",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/multi-sig/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"architecture",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/architecture/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BDK-RN",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/BDK-RN/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Development",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Development/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Architecture",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Architecture/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"tor",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/tor/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"wallet",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/wallet/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"blockchain",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/blockchain/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bindings",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bindings/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"guide",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/guide/",interval:[0,5]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"descriptor",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/descriptor/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"paper wallets",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/paper wallets/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"compact_filters",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/compact_filters/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"BIP157",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/BIP157/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Neutrino",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Neutrino/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bitcoin/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"React Native",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/React Native/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Flutter",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Flutter/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"iOS",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/iOS/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Android",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Android/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"mobile",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/mobile/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk-rn",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bdk-rn/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bdk",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bdk/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"fee",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/fee/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"machine learning",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/machine learning/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"taproot",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/taproot/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"miniscript",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/miniscript/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"Hardware Wallets",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/Hardware Wallets/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"getting started",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/getting started/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"rust",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/rust/",interval:[0,9]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"bitcoin-cli",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/bitcoin-cli/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"coin selection",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/coin selection/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"development",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/development/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"summer of bitcoin",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/summer of bitcoin/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"security",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/security/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"tags",id:"release",filter:rl.tags,sorter:nl.tags,pages:[{path:"/blog/tags/release/",interval:[0,8]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Steve Myers",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Steve Myers/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Daniela Brozzoni",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Daniela Brozzoni/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Rajarshi Maitra",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Rajarshi Maitra/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"waterst0ne",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/waterst0ne/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Lloyd Fournier",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Lloyd Fournier/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Bitcoin Zavior",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Bitcoin Zavior/",interval:[0,3]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"rorp",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/rorp/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"thunderbiscuit",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/thunderbiscuit/",interval:[0,2]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Riccardo Casatta",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Riccardo Casatta/",interval:[0,4]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Gabriele Domenichini",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Gabriele Domenichini/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Alekos Filini",filter:rl.author,sorter:nl.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:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Wszdexdrf/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"Sandipan Dey",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/Sandipan Dey/",interval:[0,1]}],prevText:"Prev",nextText:"Next"},{pid:"author",id:"César Alvarez Vallero",filter:rl.author,sorter:nl.author,pages:[{path:"/blog/author/César Alvarez Vallero/",interval:[0,1]}],prevText:"Prev",nextText:"Next"}],il=n(95);const al=n.n(il)()("plugin-blog:pagination");class cl{constructor(t,e,n){al("pagination",t);const{pages:r,prevText:o,nextText:i}=t,{path:a}=n;this._prevText=o,this._nextText=i;for(let t=0,e=r.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 ll=new class{constructor(t){this.paginations=t}get pages(){return Vn.$vuepress.$get("siteData").pages}getPagination(t,e,n){al("id",e),al("pid",t);const r=this.paginations.filter(n=>n.id===e&&n.pid===t)[0];return new cl(r,this.pages,n)}}(ol);var sl={comment:{enabled:!1,service:""},email:{enabled:!1},feed:{rss:!1,atom:!1,json:!1}},pl=[({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",Gc),document.addEventListener("keyup",t=>{qc(t)&&Gc(t)})})},{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({Vue:t})=>{t.component("CodeCopy",Sc)},({Vue:t})=>{t.component("Mermaid",Yc)},({Vue:t})=>t.use(Qc.a),{},{},({Vue:t})=>{const e=Object.keys(tl).map(t=>{const e=tl[t],n="$"+t;return{[n](){const{pages:t}=this.$site;return new el(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,ll.getPagination(t,e,this.$route)}}})},({Vue:t})=>{const e={$service:()=>sl};t.mixin({computed:e})}],ul=[];class dl 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(dl.prototype,{getPageAsyncComponent:ac,getLayoutAsyncComponent:cc,getAsyncComponent:lc,getVueComponent:sc});var gl={install(t){const e=new dl;t.$vuepress=e,t.prototype.$vuepress=e}};function hl(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var ml={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,ac(e)),Vn.component(e)?t(e):t("")}},fl={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},vl={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},bl=(n(249),n(250),Object(Kc.a)(vl,(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),yl={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(Wa),Vn.use(gl),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 r=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(r)),i={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),i),{computed:i}}(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 r in t)"/"===r?n=t[r]:0===this.$page.path.indexOf(r)&&(e=t[r]);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,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"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,r)=>{if(hl(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";hl(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";hl(t,o)?r(o):hl(t,n)?r(n):r()}})}(n);const r={};try{await Promise.all(pl.filter(t=>"function"==typeof t).map(e=>e({Vue:Vn,options:r,router:n,siteData:Uc,isServer:t})))}catch(t){console.error(t)}return{app:new Vn(Object.assign(r,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},ul.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 fe64453f41..6824a01ef0 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.

- + diff --git a/bdk-cli/concept/index.html b/bdk-cli/concept/index.html index e2ad124371..5c4a7a61cf 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!

    - + diff --git a/bdk-cli/index.html b/bdk-cli/index.html index d3ef26160a..28aba27202 100644 --- a/bdk-cli/index.html +++ b/bdk-cli/index.html @@ -33,7 +33,7 @@ - + @@ -59,7 +59,7 @@ GitHub (opens new window)

    # BDK-CLI

    The bdk-cli (opens new window) repo has an example interactive shell built using the bdk library called bdk-cli that acts both as a reference implementation of a wallet -and a tool to quickly experiment with descriptors and transactions.

    - + diff --git a/bdk-cli/installation/index.html b/bdk-cli/installation/index.html index e8466a55a3..e902af749d 100644 --- a/bdk-cli/installation/index.html +++ b/bdk-cli/installation/index.html @@ -35,7 +35,7 @@ - + @@ -110,7 +110,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
    -
    BDK Foundation
    - + diff --git a/bdk-cli/interface/index.html b/bdk-cli/interface/index.html index 34a35e150b..4bbfb94675 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.

    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.

    BDK Foundation
    - + diff --git a/bdk-cli/introduction/index.html b/bdk-cli/introduction/index.html index 68cc07b4b4..29d44f50cc 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.

    - + diff --git a/bdk-cli/playground/index.html b/bdk-cli/playground/index.html index 2681861e98..3f5382c09f 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

    - + diff --git a/bdk-cli/regtest/index.html b/bdk-cli/regtest/index.html index 1f5193f008..1e17c1dd94 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.

    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.

    BDK Foundation
    - + diff --git a/blog/2020/12/hello-world/index.html b/blog/2020/12/hello-world/index.html index 4fb3bec2c3..04e0cc18b2 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!

    - + diff --git a/blog/2020/12/release-v0.2.0/index.html b/blog/2020/12/release-v0.2.0/index.html index d90147b6a2..54da910fbf 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:

    - + diff --git a/blog/bdk-cli-basics-multisig-2of3/index.html b/blog/bdk-cli-basics-multisig-2of3/index.html index 8837a2204d..0f4dfcc9ba 100644 --- a/blog/bdk-cli-basics-multisig-2of3/index.html +++ b/blog/bdk-cli-basics-multisig-2of3/index.html @@ -30,7 +30,7 @@ - + @@ -126,7 +126,7 @@

    # Step 12: Broadcast Transaction

    ▶️ bdk-cli wallet --wallet wallet_name_msd01 --descriptor $MULTI_DESCRIPTOR_01 broadcast --psbt $SECONDSIG_PSBT

    {
       "txid": "61da2451874a483aa8d1d0787c7680d157639f284840de8885098cac43f6cc2f"
     }
    -

    # Verify Transaction

    Verify transcation in the memory pool on testnet Mempool-testnet! (opens new window)

    - + diff --git a/blog/tags/basics/index.html b/blog/tags/basics/index.html index 576309b446..834f96ce7c 100644 --- a/blog/tags/basics/index.html +++ b/blog/tags/basics/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bdk-cli/index.html b/blog/tags/bdk-cli/index.html index 75146471c5..a16f1be819 100644 --- a/blog/tags/bdk-cli/index.html +++ b/blog/tags/bdk-cli/index.html @@ -25,7 +25,7 @@ - + @@ -114,6 +114,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bdk-rn/index.html b/blog/tags/bdk-rn/index.html index 8111eff0ae..0e5df780a5 100644 --- a/blog/tags/bdk-rn/index.html +++ b/blog/tags/bdk-rn/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bdk/index.html b/blog/tags/bdk/index.html index 2431f2c8f7..0f579e8ed7 100644 --- a/blog/tags/bdk/index.html +++ b/blog/tags/bdk/index.html @@ -25,7 +25,7 @@ - + @@ -169,6 +169,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bindings/index.html b/blog/tags/bindings/index.html index 87165012dd..c2a3d409ba 100644 --- a/blog/tags/bindings/index.html +++ b/blog/tags/bindings/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bitcoin-cli/index.html b/blog/tags/bitcoin-cli/index.html index 1d9973f138..b332eb917d 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 b998e18ebf..6679549f57 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 e9bdab1186..c5a844c85f 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 78b40ce9f7..61858cc82f 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 56f32baf6c..d114f41b9e 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 7d369d5946..b8711e1538 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 f27375bc1a..42d8bf64a9 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 efe8c481d5..3da19990d4 100644 --- a/blog/tags/fee/index.html +++ b/blog/tags/fee/index.html @@ -25,7 +25,7 @@ - + @@ -60,7 +60,7 @@ - Tags: - Fee, Machine learning


    Fee estimation for light-clients (Part 3)

    + Fee, Machine learning


    Fee estimation for light-clients (Part 2)

    By Riccardo Casatta @@ -71,7 +71,7 @@ - Tags: - Fee, Machine learning


    Fee estimation for light-clients (Part 2)

    + Fee, Machine learning


    Fee estimation for light-clients (Part 3)

    By Riccardo Casatta @@ -103,6 +103,6 @@

    BDK Foundation
    - + diff --git a/blog/tags/getting started/index.html b/blog/tags/getting started/index.html index bddf880354..4a25f79fbf 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/guide/index.html b/blog/tags/guide/index.html index 97b4c1fd40..ed4e51bde5 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 8714c29ccd..cca5ff30ea 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 8abb35120f..df3ce6f422 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 8821bf0f7e..4e28e04645 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 cbee634375..69856cd9f2 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 b743526904..8ce84e1707 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 70bb6abe1e..0bb1c5d5e4 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 dcdb1a9786..231487390f 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 3822393fe3..28f968a316 100644 --- a/blog/tags/project/index.html +++ b/blog/tags/project/index.html @@ -25,7 +25,7 @@ - + @@ -81,6 +81,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/release/index.html b/blog/tags/release/index.html index 2833f59f53..f2c12e7869 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 f0e436b304..b403420a65 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 363d3e07e9..5654341b40 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 a692f42648..50b3633532 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 82a90274eb..d8b762572f 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 99495ef607..2a99544f34 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 db08649146..86c0b99089 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 c33a93a6ea..4aebb838a3 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 b4b74e2b95..65afa97eb9 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!

    - + diff --git a/descriptors/index.html b/descriptors/index.html index e24329caca..bc98e7ae3b 100644 --- a/descriptors/index.html +++ b/descriptors/index.html @@ -33,7 +33,7 @@ - + @@ -63,7 +63,7 @@ aims to produce the first "Native Descriptor" Bitcoin library that can be used by developers to build their own "Native Descriptor Wallets" (opens new window).

    # Compatibility Matrix

    Below are some tables to highlight the differences between Bitcoin Core's descriptor support, rust-miniscript's one and BDK's.

    # Key Types

    Key Type BDK rust-miniscript Bitcoin Core
    Hex PublicKey
    WIF PrivateKey
    Extended Keys (xpub/xprv)

    # Script Types (top level)

    Script Type BDK rust-miniscript Bitcoin Core
    pk()
    pkh()
    wpkh()
    sh(wpkh())
    sh()
    wsh()
    sh(wsh())
    combo()
    addr()
    raw()
    Bare scripts

    # Operators

    Operator BDK rust-miniscript Bitcoin Core
    pk()
    pkh()
    older()
    after()
    sha256()
    hash256()
    ripemd160()
    hash160()
    andor()
    and_{v,b,n}()
    or_{b,c,d,i}()
    multi()
    thresh()
    sortedmulti()

    # Modifiers

    Script Type BDK rust-miniscript Bitcoin Core
    a:
    s:
    c:
    t:
    d:
    v:
    j:
    n:
    l:
    u:

    For a more thorough description of these operators and modifiers see Sipa's Miniscript Page (opens new window) and Bitcoin Core's (opens new window).

    # Examples

    Some examples of valid BDK descriptors are:

    Spending Policy Descriptor Address 0 Address 1
    Static P2PKH pkh(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR) mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr
    Static P2PKH, watch-only pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c) mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr
    P2WSH 2-of-2 with one private key wsh(multi(2,tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*,tpubDBYDcH8P2PedrEN3HxWYJJJMZEdgnrqMsjeKpPNzwe7jmGwk5M3HRdSf5vudAXwrJPfUsfvUPFooKWmz79Lh111U51RNotagXiGNeJe3i6t/1/*)) tb1qqsat6c82fvdy73rfzye8f7nwxcz3xny7t56azl73g95mt3tmzvgs9a8vjs tb1q7sgx6gscgtau57jduend6a8l445ahpk3dt3u5zu58rx5qm27lhkqgfdjdr
    P2WSH-P2SH one key + 10 days timelock sh(wsh(and_v(vc:pk_h(tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*),older(1440)))) 2Mtk2nyS98MCi2P7TkoBGLaJviBy956XxB1 2MuEStKzYhqb5HCFgHz9153tZsL5sVqV5xC

    # Implementation Details

    BDK extends the capabilities of rust-miniscript (opens new window) by introducing the concept of an ExtendedDescriptor: it represents a descriptor that contains one or more "derivable keys" like xpubs or xprvs and can be "derived" from a normal Descriptor by deriving every single one of its keys. It is currently called "StringDescriptor" in the code, because it's implemented as a wrapped miniscript::Descriptor<String>.

    ExtendedDescriptors are derived using a single index instead of a full derivation path: this is because normally most of the path is fixed and can be represented right after the xpub/xprv itself, and only the final index changes for each address. This is what's normally called a DescriptorExtendedKey in the codebase, it is represented with a similar syntax to Bitcoin Core's, such as:

    [d34db33f/44'/0'/0']xpub6ERApfZwUNrhL.......rBGRjaDMzQLcgJvLJuZZvRcEL/0/*
    -
    BDK Foundation
    - + diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html index d86af3fcf2..6edd9cdfeb 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html @@ -174,16 +174,16 @@
    Examples
    Errors

    This function will return an error if hardened derivation is attempted.

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the minimum value (in satoshis) at which an output is broadcastable. -Panics if the descriptor wildcard is hardened. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Extract the spending policy
    Run a predicate on every key in the descriptor, returning whether +Panics if the descriptor wildcard is hardened. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Extract the spending policy
    Run a predicate on every key in the descriptor, returning whether the predicate returned true for every key Read more
    Run a predicate on every key in the descriptor, returning whether -the predicate returned true for any key Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more

    Parse an expression tree into a descriptor.

    +the predicate returned true for any key Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more

    Parse an expression tree into a descriptor.

    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Converts this object into an abstract policy.
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Converts a descriptor using abstract keys to one using specific keys.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Converts a descriptor using abstract keys to one using specific keys.

    The associated output type. This must be Self<Q>.

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html index 087efde4bd..ed6e31c2c3 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html @@ -39,7 +39,7 @@
    Errors

    For raw public key and single-path extended keys it will return the key itself. For multipath extended keys it will return a single-path extended key per derivation path.

    -

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Convert self into a Assets struct
    Turn the key into a DescriptorKey within the requested ScriptContext
    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Convert self into a Assets struct
    Turn the key into a DescriptorKey within the requested ScriptContext
    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the sha256 fragment. Read more
    The associated [miniscript::hash256::Hash] for this [MiniscriptKey], used in the hash256 fragment. Read more
    The associated [bitcoin::hashes::ripemd160::Hash] for this [MiniscriptKey] type, used in the ripemd160 fragment. Read more
    The associated [bitcoin::hashes::hash160::Hash] for this [MiniscriptKey] type, used in @@ -48,8 +48,8 @@
    Errors
    by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html index 7d7a89708e..dfa48c6963 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html @@ -9,7 +9,7 @@
    §

    Fingerprint(Fingerprint)

    An extended key fingerprint

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html index df3eda41d2..5eddcc802a 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html @@ -37,7 +37,7 @@

    Implementations§

    Returns whether the Satisfaction is a leaf item

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html index 58a19aaaec..2dc93006ed 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html @@ -53,7 +53,7 @@

    Returns a unique id for the SatisfiableItem

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html index 521d7db730..50df39fc67 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html @@ -11,7 +11,7 @@ by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html index 96d34c21de..e5eb2a88b1 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html @@ -18,7 +18,7 @@ policy tree

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    diff --git a/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html b/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html index 6bd8dd5666..591e677719 100644 --- a/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html +++ b/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html @@ -136,7 +136,7 @@
    Trait Implementations§
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Extract the spending policy
    Run a predicate on every key in the descriptor, returning whether +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Extract the spending policy
    Run a predicate on every key in the descriptor, returning whether the predicate returned true for every key Read more
    Run a predicate on every key in the descriptor, returning whether the predicate returned true for any key Read more

    Parse a Miniscript from string and perform sanity checks See Miniscript::from_str_insane to parse scripts from string that @@ -155,7 +155,7 @@

    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Translates a struct from one generic to another where the translation +operator. Read more

    Serialize this value into the given Serde serializer. Read more

    Translates a struct from one generic to another where the translation for Pk is provided by [Translator]

    The associated output type. This must be Self<Q>.
    Interpret the node as an abstract node.
    Accessor for the number of children this node has.
    Accessor for the nth child of the node, if a child with that index exists.
    Obtains an iterator of all the nodes rooted at the node, in pre-order.
    Obtains a verbose iterator of all the nodes rooted at the DAG, in pre-order. Read more
    Obtains an iterator of all the nodes rooted at the DAG, in post order. Read more

    Eq of Miniscript must depend only on node and not the type information.

    The type information and extra properties are implied by the AST.

    @@ -163,4 +163,4 @@

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html b/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html index b7c80070e6..d0d9ac4854 100644 --- a/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html +++ b/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html @@ -6,12 +6,12 @@

    Variants§

    §

    External

    External keychain, used for deriving recipient addresses.

    §

    Internal

    Internal keychain, used for deriving change addresses.

    Implementations§

    Return KeychainKind as a byte

    -

    Trait Implementations§

    Converts this type into a shared reference of the (usually inferred) input type.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Converts this type into a shared reference of the (usually inferred) input type.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html b/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html index 459dec563c..6cd30d02e3 100644 --- a/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html +++ b/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html @@ -39,7 +39,7 @@
    Errors

    For raw public key and single-path extended keys it will return the key itself. For multipath extended keys it will return a single-path extended key per derivation path.

    -

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Convert self into a Assets struct
    Turn the key into a DescriptorKey within the requested ScriptContext
    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Convert self into a Assets struct
    Turn the key into a DescriptorKey within the requested ScriptContext
    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the sha256 fragment. Read more
    The associated [miniscript::hash256::Hash] for this [MiniscriptKey], used in the hash256 fragment. Read more
    The associated [bitcoin::hashes::ripemd160::Hash] for this [MiniscriptKey] type, used in the ripemd160 fragment. Read more
    The associated [bitcoin::hashes::hash160::Hash] for this [MiniscriptKey] type, used in @@ -48,8 +48,8 @@
    Errors
    by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/struct.LocalOutput.html b/docs-rs/bdk/nightly/latest/bdk/struct.LocalOutput.html index 4b6d906a78..300db08b97 100644 --- a/docs-rs/bdk/nightly/latest/bdk/struct.LocalOutput.html +++ b/docs-rs/bdk/nightly/latest/bdk/struct.LocalOutput.html @@ -13,10 +13,10 @@ §is_spent: bool

    Whether this UTXO is spent or not

    §derivation_index: u32

    The derivation index for the script pubkey in the wallet

    §confirmation_time: ConfirmationTime

    The confirmation time for transaction containing this utxo

    -

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html b/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html index a8c81fad7f..4a85585cd2 100644 --- a/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html +++ b/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html @@ -17,8 +17,8 @@ returned will be 0.

    Return the external descriptor

    Return the internal descriptor, if present

    -

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Serialize this value into the given Serde serializer. Read more
    Converts the given value to a String. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Serialize this value into the given Serde serializer. Read more
    Converts the given value to a String. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Balance.html b/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Balance.html index 5e3c1aaa12..9464de788a 100644 --- a/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Balance.html +++ b/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Balance.html @@ -13,10 +13,10 @@

    This is the balance you can spend right now that shouldn’t get cancelled via another party double spending it.

    Get the whole balance visible to the wallet.

    -

    Trait Implementations§

    The resulting type after applying the + operator.
    Performs the + operation. Read more
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    The resulting type after applying the + operator.
    Performs the + operation. Read more
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk/wallet/struct.ChangeSet.html b/docs-rs/bdk/nightly/latest/bdk/wallet/struct.ChangeSet.html index 9baea2aba8..f91f99faae 100644 --- a/docs-rs/bdk/nightly/latest/bdk/wallet/struct.ChangeSet.html +++ b/docs-rs/bdk/nightly/latest/bdk/wallet/struct.ChangeSet.html @@ -7,10 +7,10 @@

    Fields§

    §chain: ChangeSet

    Changes to the LocalChain.

    §indexed_tx_graph: ChangeSet<ConfirmationTimeHeightAnchor, ChangeSet<KeychainKind>>

    Changes to IndexedTxGraph.

    §network: Option<Network>

    Stores the network type of the wallet.

    -

    Trait Implementations§

    Append another object of the same type onto self.
    Returns whether the structure is considered empty.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Append another object of the same type onto self.
    Returns whether the structure is considered empty.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/enum.ConfirmationTime.html b/docs-rs/bdk/nightly/latest/bdk_chain/enum.ConfirmationTime.html index 0f394d253d..6e520b91fe 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/enum.ConfirmationTime.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/enum.ConfirmationTime.html @@ -14,12 +14,12 @@

    The transaction is unconfirmed

    Implementations§

    Construct an unconfirmed variant using the given last_seen time in unix seconds.

    Returns whether ConfirmationTime is the confirmed variant.

    -

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/index.html b/docs-rs/bdk/nightly/latest/bdk_chain/index.html index a876ce5845..f746884dd0 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/index.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/index.html @@ -14,7 +14,7 @@
  • Data persistence agnostic – bdk_chain does not care where you cache on-chain data, what you cache or how you retrieve it from persistent storage.
  • -

    Re-exports

    pub extern crate serde_crate as serde;
    pub use bitcoin;
    pub use indexed_tx_graph::IndexedTxGraph;
    pub use tx_graph::TxGraph;
    pub use miniscript;

    Modules

    Contains the IndexedTxGraph and associated types. Refer to the +

    Re-exports

    pub extern crate serde_crate as serde;
    pub use bitcoin;
    pub use indexed_tx_graph::IndexedTxGraph;
    pub use tx_graph::TxGraph;
    pub use miniscript;

    Modules

    Contains the IndexedTxGraph and associated types. Refer to the IndexedTxGraph documentation for more.
    Module for keychain related structures.
    The LocalChain is a local implementation of ChainOracle.
    Module for structures that store and traverse transactions.

    Structs

    A reference to a block in the canonical chain.
    An Anchor implementation that also records the exact confirmation height of the transaction.
    An Anchor implementation that also records the exact confirmation time and height of the transaction.
    A TxOut with as much data as we can retrieve about it
    Persist wraps a PersistBackend (B) to create a convenient staging area for changes (C) before they are persisted.
    An iterator for derived script pubkeys.
    An index storing TxOuts that have a script pubkey that matches those in a list.

    Enums

    Represents the observed position of some chain data.
    Block height and timestamp at which a transaction is confirmed.

    Constants

    Maximum BIP32 derivation index.
    How many confirmations are needed f or a coinbase output to be spent.

    Traits

    Trait that “anchors” blockchain data to a specific block of height and hash.
    An Anchor that can be constructed from a given block, block height and transaction position diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/indexed_tx_graph/struct.ChangeSet.html b/docs-rs/bdk/nightly/latest/bdk_chain/indexed_tx_graph/struct.ChangeSet.html index 2832964dc7..105f382d24 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/indexed_tx_graph/struct.ChangeSet.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/indexed_tx_graph/struct.ChangeSet.html @@ -4,10 +4,10 @@ }
    Expand description

    Represents changes to an IndexedTxGraph.

    Fields§

    §graph: ChangeSet<A>

    TxGraph changeset.

    §indexer: IA

    Indexer changeset.

    -

    Trait Implementations§

    Append another object of the same type onto self.
    Returns whether the structure is considered empty.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Append another object of the same type onto self.
    Returns whether the structure is considered empty.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.Balance.html b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.Balance.html index 32d6cc661f..b0261186e3 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.Balance.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.Balance.html @@ -12,10 +12,10 @@

    This is the balance you can spend right now that shouldn’t get cancelled via another party double spending it.

    Get the whole balance visible to the wallet.

    -

    Trait Implementations§

    The resulting type after applying the + operator.
    Performs the + operation. Read more
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    The resulting type after applying the + operator.
    Performs the + operation. Read more
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.ChangeSet.html b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.ChangeSet.html index 601fb1fc6c..7567babf6c 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.ChangeSet.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.ChangeSet.html @@ -7,10 +7,10 @@

    If the keychain already exists, increase the index when the other’s index > self’s index. If the keychain did not exist, append the new keychain.

    Returns whether the changeset are empty.

    -
    Converts this type into a shared reference of the (usually inferred) input type.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used +
    Converts this type into a shared reference of the (usually inferred) input type.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.KeychainTxOutIndex.html b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.KeychainTxOutIndex.html index f5f0504c49..450e823ff6 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.KeychainTxOutIndex.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/struct.KeychainTxOutIndex.html @@ -55,7 +55,7 @@

    Synopsis

    scan of the blockchain during wallet import, it may be uncertain or unknown what the index of the last revealed script pubkey actually is.

    Refer to struct-level docs for more about lookahead.

    -

    Methods that are re-exposed from the internal SpkTxOutIndex.

    +

    Methods that are re-exposed from the internal SpkTxOutIndex.

    Return a reference to the internal SpkTxOutIndex.

    WARNING: The internal index will contain lookahead spks. Refer to struct-level docs for more about lookahead.

    @@ -86,35 +86,34 @@

    Synopsis

    Note that if self has scanned an output with this script pubkey, then this will have no effect.

    This calls SpkTxOutIndex::unmark_used internally.

    -

    Computes total input value going from script pubkeys in the index (sent) and the total output -value going to script pubkeys in the index (received) in tx. For the sent to be computed -correctly, the output being spent must have already been scanned by the index. Calculating -received just uses the [Transaction] outputs directly, so it will be correct even if it has -not been scanned.

    -

    This calls SpkTxOutIndex::sent_and_received internally.

    -

    Computes the net value that this transaction gives to the script pubkeys in the index and +

    Computes the total value transfer effect tx has on the script pubkeys belonging to the +keychains in range. Value is sent when a script pubkey in the range is on an input and +received when it is on an output. For sent to be computed correctly, the output being +spent must have already been scanned by the index. Calculating received just uses the +[Transaction] outputs directly, so it will be correct even if it has not been scanned.

    +

    Computes the net value that this transaction gives to the script pubkeys in the index and takes from the transaction outputs in the index. Shorthand for calling sent_and_received and subtracting sent from received.

    This calls SpkTxOutIndex::net_value internally.

    -

    Return a reference to the internal map of keychain to descriptors.

    -

    Add a keychain to the tracker’s txout_index with a descriptor to derive addresses.

    +

    Return a reference to the internal map of keychain to descriptors.

    +

    Add a keychain to the tracker’s txout_index with a descriptor to derive addresses.

    Adding a keychain means you will be able to derive new script pubkeys under that keychain and the txout index will discover transaction outputs with those script pubkeys.

    Panics

    This will panic if a different descriptor is introduced to the same keychain.

    -

    Get the lookahead setting.

    +

    Get the lookahead setting.

    Refer to new for more information on the lookahead.

    -

    Store lookahead scripts until target_index (inclusive).

    +

    Store lookahead scripts until target_index (inclusive).

    This does not change the global lookahead setting.

    -

    Get an unbounded spk iterator over a given keychain.

    +

    Get an unbounded spk iterator over a given keychain.

    Panics

    This will panic if the given keychain’s descriptor does not exist.

    -

    Get unbounded spk iterators for all keychains.

    -

    Iterate over revealed spks of all keychains.

    -

    Iterate over revealed spks of the given keychain.

    -

    Iterate over revealed, but unused, spks of all keychains.

    -

    Iterate over revealed, but unused, spks of the given keychain.

    -

    Get the next derivation index for keychain. The next index is the index after the last revealed +

    Get unbounded spk iterators for all keychains.

    +

    Iterate over revealed spks of keychains in range

    +

    Iterate over revealed spks of the given keychain.

    +

    Iterate over revealed, but unused, spks of all keychains.

    +

    Iterate over revealed, but unused, spks of the given keychain.

    +

    Get the next derivation index for keychain. The next index is the index after the last revealed derivation index.

    The second field in the returned tuple represents whether the next derivation index is new. There are two scenarios where the next derivation index is reused (not new):

    @@ -125,11 +124,11 @@
    Panics

    Not checking the second field of the tuple may result in address reuse.

    Panics

    Panics if the keychain does not exist.

    -

    Get the last derivation index that is revealed for each keychain.

    +

    Get the last derivation index that is revealed for each keychain.

    Keychains with no revealed indices will not be included in the returned BTreeMap.

    -

    Get the last derivation index revealed for keychain.

    -

    Convenience method to call Self::reveal_to_target on multiple keychains.

    -

    Reveals script pubkeys of the keychain’s descriptor up to and including the +

    Get the last derivation index revealed for keychain.

    +

    Convenience method to call Self::reveal_to_target on multiple keychains.

    +

    Reveals script pubkeys of the keychain’s descriptor up to and including the target_index.

    If the target_index cannot be reached (due to the descriptor having no wildcard and/or the target_index is in the hardened index range), this method will make a best-effort and @@ -139,7 +138,7 @@

    Panics
    pubkeys are revealed, then both of these will be empty.

    Panics

    Panics if keychain does not exist.

    -

    Attempts to reveal the next script pubkey for keychain.

    +

    Attempts to reveal the next script pubkey for keychain.

    Returns the derivation index of the revealed script pubkey, the revealed script pubkey and a super::ChangeSet which represents changes in the last revealed index (if any).

    When a new script cannot be revealed, we return the last revealed script and an empty @@ -150,7 +149,7 @@

    Panics
    Panics

    Panics if the keychain does not exist.

    -

    Gets the next unused script pubkey in the keychain. I.e., the script pubkey with the lowest +

    Gets the next unused script pubkey in the keychain. I.e., the script pubkey with the lowest index that has not been used yet.

    This will derive and reveal a new script pubkey if no more unused script pubkeys exist.

    If the descriptor has no wildcard and already has a used script pubkey or if a descriptor @@ -158,17 +157,14 @@

    Panics
    returned.

    Panics

    Panics if keychain has never been added to the index

    -

    Iterate over all [OutPoint]s that point to TxOuts with script pubkeys derived from +

    Iterate over all [OutPoint]s that have TxOuts with script pubkeys derived from keychain.

    -

    Use keychain_outpoints_in_range to -iterate over a specific derivation range.

    -

    Iterate over [OutPoint]s that point to TxOuts with script pubkeys derived from -keychain in a given derivation range.

    -

    Returns the highest derivation index of the keychain where KeychainTxOutIndex has +

    Iterate over [OutPoint]s that have script pubkeys derived from keychains in range.

    +

    Returns the highest derivation index of the keychain where KeychainTxOutIndex has found a [TxOut] with it’s script pubkey.

    -

    Returns the highest derivation index of each keychain that KeychainTxOutIndex has found +

    Returns the highest derivation index of each keychain that KeychainTxOutIndex has found a [TxOut] with it’s script pubkey.

    -

    Applies the derivation changeset to the KeychainTxOutIndex, extending the number of +

    Applies the derivation changeset to the KeychainTxOutIndex, extending the number of derived scripts per keychain, as specified in the changeset.

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    The resultant “changeset” when new transaction data is indexed.
    Scan and index the given outpoint and txout.
    Scans a transaction for relevant outpoints, which are stored and indexed internally.
    Determines the ChangeSet between self and an empty Indexer.
    Apply changeset to itself.
    Determines whether the transaction should be included in the index.

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/struct.BlockId.html b/docs-rs/bdk/nightly/latest/bdk_chain/struct.BlockId.html index 492e639a21..85e813b6fe 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/struct.BlockId.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/struct.BlockId.html @@ -6,12 +6,12 @@ block and anchor block are the same block.

    Fields§

    §height: u32

    The height of the block.

    §hash: BlockHash

    The hash of the block.

    -

    Trait Implementations§

    Returns the BlockId that the associated blockchain data is “anchored” in.
    Get the upper bound of the chain data’s confirmation height. Read more
    Construct the anchor from a given block, block height and tx_pos within the block.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Returns the BlockId that the associated blockchain data is “anchored” in.
    Get the upper bound of the chain data’s confirmation height. Read more
    Construct the anchor from a given block, block height and tx_pos within the block.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationHeightAnchor.html b/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationHeightAnchor.html index aaad2b5423..3d3b804a3f 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationHeightAnchor.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationHeightAnchor.html @@ -7,12 +7,12 @@

    Fields§

    §confirmation_height: u32

    The exact confirmation height of the transaction.

    It is assumed that this value is never larger than the height of the anchor block.

    §anchor_block: BlockId

    The anchor block.

    -

    Trait Implementations§

    Returns the BlockId that the associated blockchain data is “anchored” in.
    Get the upper bound of the chain data’s confirmation height. Read more
    Construct the anchor from a given block, block height and tx_pos within the block.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Returns the BlockId that the associated blockchain data is “anchored” in.
    Get the upper bound of the chain data’s confirmation height. Read more
    Construct the anchor from a given block, block height and tx_pos within the block.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationTimeHeightAnchor.html b/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationTimeHeightAnchor.html index 40d54fe7ab..3a86a79f7e 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationTimeHeightAnchor.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/struct.ConfirmationTimeHeightAnchor.html @@ -9,12 +9,12 @@

    Fields§

    §confirmation_height: u32

    The confirmation height of the transaction being anchored.

    §confirmation_time: u64

    The confirmation time of the transaction being anchored.

    §anchor_block: BlockId

    The anchor block.

    -

    Trait Implementations§

    Returns the BlockId that the associated blockchain data is “anchored” in.
    Get the upper bound of the chain data’s confirmation height. Read more
    Construct the anchor from a given block, block height and tx_pos within the block.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Returns the BlockId that the associated blockchain data is “anchored” in.
    Get the upper bound of the chain data’s confirmation height. Read more
    Construct the anchor from a given block, block height and tx_pos within the block.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/struct.SpkTxOutIndex.html b/docs-rs/bdk/nightly/latest/bdk_chain/struct.SpkTxOutIndex.html index 4248c2f04f..619a72184e 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/struct.SpkTxOutIndex.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/struct.SpkTxOutIndex.html @@ -10,7 +10,7 @@ in there in the first place. SpkTxOutIndex is intentionally monotone – you cannot delete or modify txouts that have been indexed. To find out which txouts from the index are actually in the chain or unspent, you must use other sources of information like a TxGraph.

    -

    Implementations§

    Scans a transaction’s outputs for matching script pubkeys.

    +

    Implementations§

    Scans a transaction’s outputs for matching script pubkeys.

    Typically, this is used in two situations:

    1. After loading transaction data from the disk, you may scan over all the txouts to restore all @@ -55,15 +55,14 @@
      Example

      Note that if self has scanned an output with this script pubkey then this will have no effect.

    Returns the index associated with the script pubkey.

    -

    Computes total input value going from script pubkeys in the index (sent) and the total output -value going to script pubkeys in the index (received) in tx. For the sent to be computed -correctly, the output being spent must have already been scanned by the index. Calculating -received just uses the [Transaction] outputs directly, so it will be correct even if it has -not been scanned.

    -

    Computes the net value that this transaction gives to the script pubkeys in the index and -takes from the transaction outputs in the index. Shorthand for calling -sent_and_received and subtracting sent from received.

    -

    Whether any of the inputs of this transaction spend a txout tracked or whether any output +

    Computes the total value transfer effect tx has on the script pubkeys in range. Value is +sent when a script pubkey in the range is on an input and received when it is on an +output. For sent to be computed correctly, the output being spent must have already been +scanned by the index. Calculating received just uses the [Transaction] outputs directly, +so it will be correct even if it has not been scanned.

    +

    Computes the net value transfer effect of tx on the script pubkeys in range. Shorthand +for calling sent_and_received and subtracting sent from received.

    +

    Whether any of the inputs of this transaction spend a txout tracked or whether any output matches one of our script pubkeys.

    It is easily possible to misuse this method and get false negatives by calling it before you have scanned the TxOuts the transaction is spending. For example, if you want to filter out diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.ChangeSet.html b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.ChangeSet.html index 2f68ebbd3a..ab5176cc5c 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.ChangeSet.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.ChangeSet.html @@ -23,10 +23,10 @@

    Transform the ChangeSet to have Anchors of another type.

    This takes in a closure of signature FnMut(A) -> A2 which is called for each Anchor to transform it.

    -

    Trait Implementations§

    Append another object of the same type onto self.
    Returns whether the structure is considered empty.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    Append another object of the same type onto self.
    Returns whether the structure is considered empty.
    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +sufficient, and should not be overridden without very good reason. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxAncestors.html b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxAncestors.html index c0c8ba8978..23bab01161 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxAncestors.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxAncestors.html @@ -33,8 +33,8 @@ less or equal to those of another. Read more
    Determines if the elements of this Iterator are lexicographically greater than those of another. Read more
    Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more
    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given comparator function. Read more
    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given key extraction -function. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more
    Adapts the byte iterator to output GF32 field elements instead. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would -happen it returns None. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would +function. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more
    Adapts the byte iterator to output GF32 field elements instead. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would +happen it returns None. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would happen it returns None. Read more
    Adapts the Fe32 iterator to output bytes instead. Read more
    Adapts the Fe32 iterator to encode the field elements into a bech32 address.

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxDescendants.html b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxDescendants.html index 0cbb5973e3..2c8133c45e 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxDescendants.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxDescendants.html @@ -32,8 +32,8 @@ less or equal to those of another. Read more

    Determines if the elements of this Iterator are lexicographically greater than those of another. Read more
    Determines if the elements of this Iterator are lexicographically greater than or equal to those of another. Read more
    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given comparator function. Read more
    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given key extraction -function. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more
    Adapts the byte iterator to output GF32 field elements instead. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would -happen it returns None. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would +function. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more
    Adapts the byte iterator to output GF32 field elements instead. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would +happen it returns None. Read more
    Calculate the sum over the iterator using checked arithmetic. If an over or underflow would happen it returns None. Read more
    Adapts the Fe32 iterator to output bytes instead. Read more
    Adapts the Fe32 iterator to encode the field elements into a bech32 address.

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of diff --git a/docs-rs/bdk/nightly/latest/bdk_file_store/struct.EntryIter.html b/docs-rs/bdk/nightly/latest/bdk_file_store/struct.EntryIter.html index eda9c3b14c..6aa20f5642 100644 --- a/docs-rs/bdk/nightly/latest/bdk_file_store/struct.EntryIter.html +++ b/docs-rs/bdk/nightly/latest/bdk_file_store/struct.EntryIter.html @@ -1,7 +1,7 @@ EntryIter in bdk_file_store - Rust

    pub struct EntryIter<'t, T> { /* private fields */ }
    Expand description

    Iterator over entries in a file store.

    Reads and returns an entry each time next is called. If an error occurs while reading the iterator will yield a Result::Err(_) instead and then None for the next call to next.

    -

    Implementations§

    Trait Implementations§

    Executes the destructor for this type. Read more
    The type of the elements being iterated over.
    Advances the iterator and returns the next value. Read more
    🔬This is a nightly-only experimental API. (iter_next_chunk)
    Advances the iterator and returns an array containing the next N values. Read more
    Returns the bounds on the remaining length of the iterator. Read more
    Consumes the iterator, counting the number of iterations and returning it. Read more
    Consumes the iterator, returning the last element. Read more
    🔬This is a nightly-only experimental API. (iter_advance_by)
    Advances the iterator by n elements. Read more
    Returns the nth element of the iterator. Read more
    Creates an iterator starting at the same point, but stepping by +

    Implementations§

    Trait Implementations§

    Executes the destructor for this type. Read more
    The type of the elements being iterated over.
    Advances the iterator and returns the next value. Read more
    🔬This is a nightly-only experimental API. (iter_next_chunk)
    Advances the iterator and returns an array containing the next N values. Read more
    Returns the bounds on the remaining length of the iterator. Read more
    Consumes the iterator, counting the number of iterations and returning it. Read more
    Consumes the iterator, returning the last element. Read more
    🔬This is a nightly-only experimental API. (iter_advance_by)
    Advances the iterator by n elements. Read more
    Returns the nth element of the iterator. Read more
    Creates an iterator starting at the same point, but stepping by the given amount at each iteration. Read more
    Takes two iterators and creates a new iterator over both in sequence. Read more
    ‘Zips up’ two iterators into a single iterator of pairs. Read more
    🔬This is a nightly-only experimental API. (iter_intersperse)
    Creates a new iterator which places an item generated by separator between adjacent items of the original iterator. Read more
    Takes a closure and creates an iterator which calls that closure on each element. Read more
    Calls a closure on each element of an iterator. Read more
    Creates an iterator which uses a closure to determine if an element diff --git a/docs-rs/bdk/nightly/latest/bdk_file_store/struct.Store.html b/docs-rs/bdk/nightly/latest/bdk_file_store/struct.Store.html index 5199b27a9e..74c349ce05 100644 --- a/docs-rs/bdk/nightly/latest/bdk_file_store/struct.Store.html +++ b/docs-rs/bdk/nightly/latest/bdk_file_store/struct.Store.html @@ -1,6 +1,6 @@ Store in bdk_file_store - Rust

    Struct bdk_file_store::Store

    source ·
    pub struct Store<C> { /* private fields */ }
    Expand description

    Persists an append-only list of changesets (C) to a single file.

    The changesets are the results of altering a tracker implementation (T).

    -

    Implementations§

    Create a new Store file in write-only mode; error if the file exists.

    +

    Implementations§

    Create a new Store file in write-only mode; error if the file exists.

    magic is the prefixed bytes to write to the new file. This will be checked when opening the Store in the future with open.

    Open an existing Store.

    @@ -30,8 +30,8 @@
    Errors
    changeset.

    The truncation is to avoid the possibility of having a valid but inconsistent changeset directly after the appended changeset.

    -

    Trait Implementations§

    Formats the value using the given formatter. Read more
    The error the backend returns when it fails to write.
    The error the backend returns when it fails to load changesets C.
    Writes a changeset to the persistence backend. Read more
    Return the aggregate changeset C from persistence.

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    The error the backend returns when it fails to write.
    The error the backend returns when it fails to load changesets C.
    Writes a changeset to the persistence backend. Read more
    Return the aggregate changeset C from persistence.

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_hwi/index.html b/docs-rs/bdk/nightly/latest/bdk_hwi/index.html index 86da9b7579..e8b9bcec10 100644 --- a/docs-rs/bdk/nightly/latest/bdk_hwi/index.html +++ b/docs-rs/bdk/nightly/latest/bdk_hwi/index.html @@ -1,5 +1,5 @@ bdk_hwi - Rust

    Crate bdk_hwi

    source ·
    Expand description

    HWI Signer

    -

    This crate contains HWISigner, an implementation of a TransactionSigner to be +

    This crate contains HWISigner, an implementation of a TransactionSigner to be used with hardware wallets.

    let mut devices = HWIClient::enumerate()?;
    diff --git a/docs-rs/bdk/nightly/latest/bdk_hwi/struct.HWISigner.html b/docs-rs/bdk/nightly/latest/bdk_hwi/struct.HWISigner.html
    index fb33bf59db..b18d2baff8 100644
    --- a/docs-rs/bdk/nightly/latest/bdk_hwi/struct.HWISigner.html
    +++ b/docs-rs/bdk/nightly/latest/bdk_hwi/struct.HWISigner.html
    @@ -1,7 +1,7 @@
     HWISigner in bdk_hwi - Rust

    Struct bdk_hwi::HWISigner

    source ·
    pub struct HWISigner { /* private fields */ }
    Expand description

    Custom signer for Hardware Wallets

    This ignores sign_options and leaves the decisions up to the hardware wallet.

    Implementations§

    Create a instance from the specified device and chain

    -

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Return the SignerId for this signer Read more
    Return the secret key for the signer Read more
    Sign all the inputs of the psbt

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Return the [SignerId] for this signer Read more
    Return the secret key for the signer Read more
    Sign all the inputs of the psbt

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    diff --git a/docs-rs/bdk/nightly/latest/example_cli/enum.Keychain.html b/docs-rs/bdk/nightly/latest/example_cli/enum.Keychain.html index a4bc3b61ac..9096168f16 100644 --- a/docs-rs/bdk/nightly/latest/example_cli/enum.Keychain.html +++ b/docs-rs/bdk/nightly/latest/example_cli/enum.Keychain.html @@ -1,12 +1,12 @@ Keychain in example_cli - Rust
    pub enum Keychain {
         External,
         Internal,
    -}

    Variants§

    §

    External

    §

    Internal

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +}

    Variants§

    §

    External

    §

    Internal

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used by ==. Read more
    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more
    Compare self to key and return true if they are equal.

    Returns the argument unchanged.

    +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more
    Compare self to key and return true if they are equal.

    Returns the argument unchanged.

    Calls U::from(self).

    That is, this conversion is whatever the implementation of From<T> for U chooses to do.

    -
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file +
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/example_cli/fn.handle_commands.html b/docs-rs/bdk/nightly/latest/example_cli/fn.handle_commands.html index 74aab9d2f0..4e708ea6db 100644 --- a/docs-rs/bdk/nightly/latest/example_cli/fn.handle_commands.html +++ b/docs-rs/bdk/nightly/latest/example_cli/fn.handle_commands.html @@ -1 +1 @@ -handle_commands in example_cli - Rust
    pub fn handle_commands<CS: Subcommand, S: Args, A: Anchor, O: ChainOracle, C>(
        graph: &Mutex<KeychainTxGraph<A>>,
        db: &Mutex<Database<C>>,
        chain: &Mutex<O>,
        keymap: &BTreeMap<DescriptorPublicKey, DescriptorSecretKey>,
        network: Network,
        broadcast: impl FnOnce(S, &Transaction) -> Result<()>,
        cmd: Commands<CS, S>
    ) -> Result<()>where
        O::Error: Error + Send + Sync + 'static,
        C: Default + Append + DeserializeOwned + Serialize + From<KeychainChangeSet<A>>,
    \ No newline at end of file +handle_commands in example_cli - Rust
    pub fn handle_commands<CS: Subcommand, S: Args, A: Anchor, O: ChainOracle, C>(
        graph: &Mutex<KeychainTxGraph<A>>,
        db: &Mutex<Database<C>>,
        chain: &Mutex<O>,
        keymap: &BTreeMap<DescriptorPublicKey, DescriptorSecretKey>,
        network: Network,
        broadcast: impl FnOnce(S, &Transaction) -> Result<()>,
        cmd: Commands<CS, S>
    ) -> Result<()>where
        O::Error: Error + Send + Sync + 'static,
        C: Default + Append + DeserializeOwned + Serialize + From<KeychainChangeSet<A>>,
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/example_cli/fn.init.html b/docs-rs/bdk/nightly/latest/example_cli/fn.init.html index 40e7ae0f23..e5b59aece4 100644 --- a/docs-rs/bdk/nightly/latest/example_cli/fn.init.html +++ b/docs-rs/bdk/nightly/latest/example_cli/fn.init.html @@ -1,3 +1,3 @@ -init in example_cli - Rust

    Function example_cli::init

    source ·
    pub fn init<CS: Subcommand, S: Args, C>(
        db_magic: &[u8],
        db_default_path: &str
    ) -> Result<Init<CS, S, C>>where
        C: Default + Append + Serialize + DeserializeOwned,
    Expand description

    Parses command line arguments and initializes all components, creating +init in example_cli - Rust

    Function example_cli::init

    source ·
    pub fn init<CS: Subcommand, S: Args, C>(
        db_magic: &[u8],
        db_default_path: &str
    ) -> Result<Init<CS, S, C>>where
        C: Default + Append + Serialize + DeserializeOwned,
    Expand description

    Parses command line arguments and initializes all components, creating a file store with the given parameters, or loading one if it exists.

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js b/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js index b008aa7a79..fb042c4512 100644 --- a/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js +++ b/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js @@ -1,4 +1,4 @@ (function() {var implementors = { "bdk":[], -"bdk_hwi":[["impl SignerCommon for HWISigner"]] +"bdk_hwi":[["impl SignerCommon for HWISigner"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js b/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js index ea6c96cd81..68919d45f8 100644 --- a/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js +++ b/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js @@ -1,4 +1,4 @@ (function() {var implementors = { "bdk":[], -"bdk_hwi":[["impl TransactionSigner for HWISigner"]] +"bdk_hwi":[["impl TransactionSigner for HWISigner"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/implementors/bdk_chain/persist/trait.PersistBackend.js b/docs-rs/bdk/nightly/latest/implementors/bdk_chain/persist/trait.PersistBackend.js index ddbe6660df..df7c811209 100644 --- a/docs-rs/bdk/nightly/latest/implementors/bdk_chain/persist/trait.PersistBackend.js +++ b/docs-rs/bdk/nightly/latest/implementors/bdk_chain/persist/trait.PersistBackend.js @@ -1,4 +1,4 @@ (function() {var implementors = { "bdk_chain":[], -"bdk_file_store":[["impl<C> PersistBackend<C> for Store<C>where
        C: Append + Serialize + DeserializeOwned,
    "]] +"bdk_file_store":[["impl<C> PersistBackend<C> for Store<C>where
        C: Append + Serialize + DeserializeOwned,
    "]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/iterator/trait.Iterator.js b/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/iterator/trait.Iterator.js index 7b3defd9e9..b2a56ac33d 100644 --- a/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/iterator/trait.Iterator.js +++ b/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/iterator/trait.Iterator.js @@ -1,5 +1,5 @@ (function() {var implementors = { "bdk_chain":[["impl Iterator for CheckPointIter"],["impl<'g, A, F, O> Iterator for TxAncestors<'g, A, F>where
        F: FnMut(usize, Arc<Transaction>) -> Option<O>,
    "],["impl<'g, A, F, O> Iterator for TxDescendants<'g, A, F>where
        F: FnMut(usize, Txid) -> Option<O>,
    "],["impl<D> Iterator for SpkIterator<D>where
        D: Borrow<Descriptor<DescriptorPublicKey>>,
    "]], "bdk_coin_select":[["impl<'c, 'f, S: Ord + Copy + Display> Iterator for BnbIter<'c, 'f, S>"]], -"bdk_file_store":[["impl<'t, T> Iterator for EntryIter<'t, T>where
        T: DeserializeOwned,
    "]] +"bdk_file_store":[["impl<'t, T> Iterator for EntryIter<'t, T>where
        T: DeserializeOwned,
    "]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js b/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js index 0a01b666dc..c6dc09247f 100644 --- a/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js +++ b/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js @@ -1,5 +1,5 @@ (function() {var implementors = { -"bdk":[["impl<'de> Deserialize<'de> for KeychainKind"],["impl<'de> Deserialize<'de> for LocalOutput"],["impl<'de> Deserialize<'de> for FullyNodedExport"],["impl<'de> Deserialize<'de> for ChangeSet"]], -"bdk_chain":[["impl<'de> Deserialize<'de> for ConfirmationTime"],["impl<'de> Deserialize<'de> for BlockId"],["impl<'de> Deserialize<'de> for ConfirmationHeightAnchor"],["impl<'de> Deserialize<'de> for ConfirmationTimeHeightAnchor"],["impl<'de, A, IA> Deserialize<'de> for ChangeSet<A, IA>where
        A: Ord + Deserialize<'de>,
        IA: Deserialize<'de>,
    "],["impl<'de, K> Deserialize<'de> for ChangeSet<K>where
        K: Ord + Deserialize<'de>,
    "],["impl<'de> Deserialize<'de> for Balance"],["impl<'de, A> Deserialize<'de> for ChangeSet<A>where
        A: Ord + Deserialize<'de>,
    "]], -"example_cli":[["impl<'de> Deserialize<'de> for Keychain"]] +"bdk":[["impl<'de> Deserialize<'de> for KeychainKind"],["impl<'de> Deserialize<'de> for LocalOutput"],["impl<'de> Deserialize<'de> for FullyNodedExport"],["impl<'de> Deserialize<'de> for ChangeSet"]], +"bdk_chain":[["impl<'de> Deserialize<'de> for ConfirmationTime"],["impl<'de> Deserialize<'de> for BlockId"],["impl<'de> Deserialize<'de> for ConfirmationHeightAnchor"],["impl<'de> Deserialize<'de> for ConfirmationTimeHeightAnchor"],["impl<'de, A, IA> Deserialize<'de> for ChangeSet<A, IA>where
        A: Ord + Deserialize<'de>,
        IA: Deserialize<'de>,
    "],["impl<'de, K> Deserialize<'de> for ChangeSet<K>where
        K: Ord + Deserialize<'de>,
    "],["impl<'de> Deserialize<'de> for Balance"],["impl<'de, A> Deserialize<'de> for ChangeSet<A>where
        A: Ord + Deserialize<'de>,
    "]], +"example_cli":[["impl<'de> Deserialize<'de> for Keychain"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js b/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js index 8d0c7bc92b..189fb96b14 100644 --- a/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js +++ b/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js @@ -1,5 +1,5 @@ (function() {var implementors = { -"bdk":[["impl Serialize for PkOrF"],["impl Serialize for SatisfiableItem"],["impl Serialize for Satisfaction"],["impl Serialize for Policy"],["impl Serialize for Condition"],["impl Serialize for KeychainKind"],["impl Serialize for LocalOutput"],["impl Serialize for FullyNodedExport"],["impl Serialize for ChangeSet"]], -"bdk_chain":[["impl Serialize for ConfirmationTime"],["impl Serialize for BlockId"],["impl Serialize for ConfirmationHeightAnchor"],["impl Serialize for ConfirmationTimeHeightAnchor"],["impl<A, IA> Serialize for ChangeSet<A, IA>where
        A: Ord + Serialize,
        IA: Serialize,
    "],["impl<K> Serialize for ChangeSet<K>where
        K: Ord + Serialize,
    "],["impl Serialize for Balance"],["impl<A> Serialize for ChangeSet<A>where
        A: Ord + Serialize,
    "]], -"example_cli":[["impl Serialize for Keychain"]] +"bdk":[["impl Serialize for PkOrF"],["impl Serialize for SatisfiableItem"],["impl Serialize for Satisfaction"],["impl Serialize for Policy"],["impl Serialize for Condition"],["impl Serialize for KeychainKind"],["impl Serialize for LocalOutput"],["impl Serialize for FullyNodedExport"],["impl Serialize for ChangeSet"]], +"bdk_chain":[["impl Serialize for ConfirmationTime"],["impl Serialize for BlockId"],["impl Serialize for ConfirmationHeightAnchor"],["impl Serialize for ConfirmationTimeHeightAnchor"],["impl<A, IA> Serialize for ChangeSet<A, IA>where
        A: Ord + Serialize,
        IA: Serialize,
    "],["impl<K> Serialize for ChangeSet<K>where
        K: Ord + Serialize,
    "],["impl Serialize for Balance"],["impl<A> Serialize for ChangeSet<A>where
        A: Ord + Serialize,
    "]], +"example_cli":[["impl Serialize for Keychain"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/search-index.js b/docs-rs/bdk/nightly/latest/search-index.js index 3d71c3332d..127be3e17b 100644 --- a/docs-rs/bdk/nightly/latest/search-index.js +++ b/docs-rs/bdk/nightly/latest/search-index.js @@ -1,7 +1,7 @@ var searchIndex = JSON.parse('{\ -"bdk":{"doc":"bdk","t":[13,13,2,13,4,13,3,2,2,4,2,3,11,11,11,11,11,11,11,11,11,11,2,11,11,11,11,11,11,11,11,11,12,12,0,14,11,11,11,11,11,11,11,11,11,11,14,11,11,11,11,11,11,11,11,11,11,12,12,0,11,12,11,0,12,11,11,11,2,2,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,12,5,11,11,11,11,0,12,12,12,13,6,4,2,4,6,8,6,8,16,4,3,13,13,2,8,4,13,13,6,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,2,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,10,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,12,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,10,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,5,5,13,13,4,13,13,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,4,13,3,6,13,13,6,13,13,13,13,13,13,13,13,13,13,13,4,3,4,13,13,13,13,13,4,4,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,12,11,11,11,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,3,3,3,3,3,3,3,3,8,6,3,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,8,4,4,4,16,16,8,4,13,8,8,3,8,13,13,13,16,4,6,13,13,13,13,13,16,13,3,13,8,4,13,13,13,3,3,4,3,13,6,13,13,13,5,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,11,5,11,10,11,11,5,10,11,11,12,12,11,11,11,11,11,11,10,12,11,11,11,11,11,10,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,8,10,10,10,4,3,4,3,13,3,13,13,13,13,4,8,13,13,13,4,13,13,13,13,13,4,4,13,13,13,13,13,3,3,13,13,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,0,11,12,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,12,11,12,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,5,12,12,12,12,12,12,12,12,13,13,3,13,8,3,6,4,4,13,3,13,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,5,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,4,13,13,13,4,13,13,13,13,13,13,13,13,4,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,3,6,12,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,13,13,13,13,13,13,13,8,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,3,8,4,4,4,3,3,3,13,4,8,13,11,12,12,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,10,11,11,11,10,11,12,11,12,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,4,4,4,13,3,13,13,4,3,13,13,13,13,13,13,3,8,4,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12],"n":["External","Foreign","HdKeyPaths","Internal","KeychainKind","Local","LocalOutput","SignOptions","TxBuilder","Utxo","Wallet","WeightedUtxo","as_byte","as_ref","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","chain","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","confirmation_time","derivation_index","descriptor","descriptor","deserialize","deserialize","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fragment","from","from","from","from","hash","hash","into","into","into","into","is_spent","keychain","keys","outpoint","outpoint","partial_cmp","psbt","satisfaction_weight","sequence","serialize","serialize","signer","template","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","txout","txout","type_id","type_id","type_id","type_id","utxo","version","vzip","vzip","vzip","vzip","wallet","outpoint","psbt_input","sequence","Bare","DerivedDescriptor","Descriptor","DescriptorError","DescriptorPublicKey","ExtendedDescriptor","ExtractPolicy","HdKeyPaths","IntoWalletDescriptor","Key","Legacy","Miniscript","MultiXPub","Pkh","Policy","ScriptContext","Segwitv0","Sh","Single","TapKeyOrigins","Tr","Wpkh","Wsh","XPub","address","as_enum","as_enum","as_inner","as_node","at_derivation_index","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","branches","build_template","build_template_mall","calc_checksum","check_global_consensus_validity","check_global_consensus_validity","check_global_consensus_validity","check_global_policy_validity","check_global_policy_validity","check_global_validity","check_local_consensus_validity","check_local_consensus_validity","check_local_consensus_validity","check_local_policy_validity","check_local_policy_validity","check_local_policy_validity","check_local_validity","check_pk","check_pk","check_pk","check_terminal_non_malleable","check_terminal_non_malleable","check_terminal_non_malleable","check_witness","check_witness","check_witness","checksum","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","contains_raw_pkh","derive","derived_descriptor","derived_descriptor","desc_type","deserialize","deserialize","dust_value","encode","eq","eq","eq","eq","error","explicit_script","ext","ext_check","extract_policy","extract_policy","extract_policy","find_derivation_index_for_spk","fmt","fmt","fmt","fmt","fmt","fmt","for_each_key","for_each_key","from","from","from","from","from","from","from","from","from","from","from_ast","from_components_unchecked","from_str","from_str","from_str_ext","from_str_insane","from_tree","from_tree","get_nth_child","get_nth_pk","get_satisfaction","get_satisfaction_mall","has_mixed_timelocks","has_repeated_keys","has_wildcard","hash","hash","hash","hash","into","into","into","into","into_inner","into_single_descriptors","into_wallet_descriptor","into_wallet_descriptor","is_deriveable","is_multipath","is_non_malleable","iter","iter_pk","lift","lift","lift_check","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_weight","max_satisfaction_witness_elements","max_weight_to_satisfy","name_str","name_str","name_str","new_bare","new_pk","new_pkh","new_sh","new_sh_sortedmulti","new_sh_with_wpkh","new_sh_with_wsh","new_sh_wpkh","new_sh_wsh","new_sh_wsh_sortedmulti","new_tr","new_wpkh","new_wsh","new_wsh_sortedmulti","node","other_top_level_checks","parse","parse_descriptor","parse_insane","parse_with_ext","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pk_len","pk_len","pk_len","plan","plan_mall","policy","requires_sig","sanity_check","sanity_check","satisfy","satisfy","satisfy_malleable","script_code","script_pubkey","script_size","serialize","serialize","sig_type","sig_type","sig_type","substitute_raw_pkh","template","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string_with_secret","top_level_checks","top_level_type_check","translate_pk","translate_pk","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","ty","type_id","type_id","type_id","type_id","unsigned_script_sig","vzip","vzip","vzip","vzip","within_resource_limits","calc_checksum","calc_checksum_bytes","Base58","Bip32","Error","HardenedDerivationXpub","Hex","InvalidDescriptorCharacter","InvalidDescriptorChecksum","InvalidHdKeyPath","Key","Miniscript","MultiPath","Pk","Policy","borrow","borrow_mut","fmt","fmt","from","from","from","from","from","from","from","from","into","provide","to_string","try_from","try_into","type_id","vzip","AbsoluteTimelock","AddOnLeaf","AddOnPartialComplete","BuildSatisfaction","Complete","Condition","ConditionMap","EcdsaSignature","Fingerprint","FoldedConditionMap","Hash160Preimage","Hash256Preimage","IncompatibleConditions","IndexOutOfRange","MixedTimelockUnits","Multisig","None","None","NotEnoughItemsSelected","Partial","PartialComplete","PkOrF","Policy","PolicyError","Psbt","PsbtTimelocks","Pubkey","RelativeTimelock","Ripemd160Preimage","Satisfaction","SatisfiableItem","SchnorrSignature","Sha256Preimage","Thresh","XOnlyPubkey","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","contribution","csv","default","eq","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","get_condition","hash","hash","id","id","into","into","into","into","into","into","into","is_leaf","is_leaf","is_null","item","partial_cmp","provide","requires_path","satisfaction","serialize","serialize","serialize","serialize","serialize","timelock","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","current_height","input_max_height","psbt","condition","conditions","conditions","items","items","m","m","n","n","sorted","sorted","hash","hash","hash","hash","items","keys","threshold","threshold","value","value","Bip44","Bip44Public","Bip49","Bip49Public","Bip84","Bip84Public","Bip86","Bip86Public","DescriptorTemplate","DescriptorTemplateOut","P2Pkh","P2TR","P2Wpkh","P2Wpkh_P2Sh","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","build","build","build","build","build","build","build","build","build","build","build","build","from","from","from","from","from","from","from","from","from","from","from","from","into","into","into","into","into","into","into","into","into","into","into","into","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","Bip32","DerivableKey","DescriptorKey","DescriptorPublicKey","DescriptorSecretKey","Entropy","Error","ExtScriptContext","ExtendedKey","FullKey","GeneratableDefaultOptions","GeneratableKey","GeneratedKey","IntoDescriptorKey","InvalidChecksum","InvalidNetwork","InvalidScriptContext","Key","KeyError","KeyMap","Legacy","Message","Miniscript","MultiXPrv","MultiXPub","Options","Private","PrivateKeyGenerateOptions","Public","ScriptContext","ScriptContextEnum","Segwitv0","Single","Single","SinglePriv","SinglePub","SinglePubKey","SortedMultiVec","Tap","ValidNetworks","XOnly","XPrv","XPub","any_network","as_enum","at_derivation_index","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build_template","check_global_consensus_validity","check_global_policy_validity","check_global_validity","check_local_consensus_validity","check_local_policy_validity","check_local_validity","check_pk","check_terminal_non_malleable","check_witness","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","compressed","default","deref","derive","deserialize","encode","eq","eq","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","for_each_key","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_public","from_secret","from_str","from_str","from_tree","full_derivation_path","full_derivation_paths","generate","generate_default","generate_with_entropy","generate_with_entropy_default","has_secret","has_wildcard","hash","hash","hash","hash","into","into","into","into","into","into","into","into","into","into","into","into","into_assets","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_extended_key","into_extended_key","into_extended_key","into_key","into_single_keys","into_single_keys","into_xprv","into_xpub","is_deriveable","is_legacy","is_legacy","is_multipath","is_multipath","is_segwit_v0","is_segwit_v0","is_taproot","is_taproot","is_uncompressed","is_x_only_key","k","key","key","lift","mainnet_network","master_fingerprint","max_satisfaction_size","max_satisfaction_size","max_satisfaction_witness_elements","merge_networks","name_str","new","num_der_paths","origin","origin","other_top_level_checks","override_valid_networks","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pk_len","pks","provide","sanity_check","satisfy","script_size","serialize","sig_type","sorted_node","test_networks","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_public","to_string","to_string","to_string","to_string","top_level_checks","top_level_type_check","translate_pk","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","PsbtUtils","fee_amount","fee_rate","get_utxo_for","AddressIndex","AddressInfo","ApplyBlockError","Balance","CannotConnect","ChangeSet","ConfirmationHeightCannotBeGreaterThanTip","Descriptor","Descriptor","Descriptor","InsertTxError","IsDust","LastUnused","Load","Load","LoadError","LoadedGenesisDoesNotMatch","LoadedNetworkDoesNotMatch","MissingGenesis","MissingNetwork","New","NewError","NewOrLoadError","NonEmptyDatabase","NotInitialized","NotInitialized","Peek","UnexpectedConnectedToHash","Update","Wallet","Write","Write","add","add_signer","address","all_unbounded_spk_iters","append","apply_block","apply_block_connected_to","apply_unconfirmed_txs","apply_update","as_ref","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build_fee_bump","build_tx","calculate_fee","calculate_fee_rate","cancel_tx","chain","chain","checkpoints","clone","clone","clone","clone_into","clone_into","clone_into","coin_selection","commit","confirmed","default","default","default","deref","derivation_index","derivation_of_spk","descriptor_checksum","deserialize","deserialize","eq","eq","eq","error","export","finalize_psbt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","get_address","get_balance","get_descriptor_for_keychain","get_internal_address","get_psbt_input","get_signers","get_tx","get_utxo","graph","immature","index","indexed_tx_graph","insert_checkpoint","insert_tx","insert_txout","into","into","into","into","into","into","into","into","into","into","into","is_dust","is_empty","is_mine","keychain","keychains","last_active_indices","latest_checkpoint","list_output","list_unspent","load","local_chain","network","network","new","new_no_persist","new_no_persist_with_genesis_hash","new_or_load","new_or_load_with_genesis_hash","new_with_genesis_hash","next_derivation_index","policies","provide","provide","provide","provide","provide","public_descriptor","secp_ctx","sent_and_received","serialize","serialize","sign","signer","spk_index","staged","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","to_string","total","transactions","trusted_pending","trusted_spendable","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_get_address","try_get_internal_address","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","tx_builder","tx_graph","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unbounded_spk_iter","untrusted_pending","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","wallet_name_from_descriptor","connected_to_hash","expected_hash","tip_height","tx_height","expected","expected","got","got","BnBNoExactMatch","BnBTotalTriesExceeded","BranchAndBoundCoinSelection","Change","CoinSelectionAlgorithm","CoinSelectionResult","DefaultCoinSelectionAlgorithm","Error","Excess","InsufficientFunds","LargestFirstCoinSelection","NoChange","OldestFirstCoinSelection","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","coin_select","coin_select","coin_select","coin_select","decide_change","default","default","default","excess","fee_amount","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","into","into","into","into","into","into","local_selected_amount","new","provide","selected","selected_amount","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","available","needed","amount","change_fee","dust_threshold","fee","remaining_amount","BuildFeeBumpError","ChangePolicyDescriptor","CoinSelection","Conversion","CreateTxError","Descriptor","FeeRateTooLow","FeeRateUnavailable","FeeTooLow","InsufficientFunds","IrreplaceableTransaction","LockTime","MiniscriptPsbt","MiniscriptPsbtError","MissingKeyOrigin","MissingNonWitnessUtxo","NoRecipients","NoUtxosSelected","OutputBelowDustLimit","OutputUpdate","Persist","Policy","Psbt","RbfSequence","RbfSequenceCsv","SpendingPolicyRequired","TransactionConfirmed","TransactionNotFound","UnknownUtxo","UnknownUtxo","UtxoUpdate","Version0","Version1Csv","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","into","into","into","provide","provide","provide","to_owned","to_string","to_string","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","available","csv","needed","rbf","requested","required","required","required","FullyNodedExport","WalletExport","blockheight","borrow","borrow_mut","change_descriptor","descriptor","deserialize","export_wallet","fmt","from","from_str","into","label","serialize","to_string","try_from","try_into","type_id","vzip","All","Dummy","Exclude","External","Fingerprint","Include","InputIndexOutOfRange","InputSigner","InvalidKey","InvalidNonWitnessUtxo","InvalidSighash","Legacy","MiniscriptPsbt","MissingHdKeypath","MissingKey","MissingNonWitnessUtxo","MissingWitnessScript","MissingWitnessUtxo","NonStandardSighash","None","PkHash","Segwitv0","SighashError","SignOptions","SignerCommon","SignerContext","SignerError","SignerId","SignerOrdering","SignerWrapper","SignersContainer","Tap","TapLeavesOptions","TransactionSigner","UserCanceled","add_external","allow_all_sighashes","allow_grinding","as_key_map","assume_height","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","default","default","default","default","deref","descriptor_secret_key","descriptor_secret_key","descriptor_secret_key","descriptor_secret_key","eq","eq","eq","eq","find","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","hash","id","id","id","id","ids","into","into","into","into","into","into","into","into","new","new","partial_cmp","partial_cmp","provide","remove","remove_partial_sigs","remove_taproot_extras","sign_input","sign_input","sign_input","sign_input","sign_transaction","sign_transaction","sign_with_tap_internal_key","signers","tap_leaves_options","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","trust_witness_utxo","try_finalize","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","is_internal_key","AddForeignUtxoError","AddUtxoError","AllowShrinkingError","Bip69Lexicographic","BumpFee","ChangeAllowed","ChangeForbidden","ChangeSpendPolicy","CreateTx","InvalidOutpoint","InvalidTxid","MissingScriptPubKey","MissingUtxo","OnlyChange","Shuffle","TxBuilder","TxBuilderContext","TxOrdering","UnknownUtxo","Untouched","add_data","add_foreign_utxo","add_foreign_utxo_with_sequence","add_global_xpubs","add_recipient","add_unspendable","add_utxo","add_utxos","allow_dust","allow_shrinking","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","change_policy","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","coin_selection","current_height","default","default","default","default","do_not_spend_change","drain_to","drain_wallet","enable_rbf","enable_rbf_with_sequence","eq","eq","fee_absolute","fee_rate","finish","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","hash","hash","include_output_redeem_witness_script","into","into","into","into","into","into","into","into","manually_selected_only","nlocktime","only_spend_change","only_witness_utxo","ordering","partial_cmp","partial_cmp","policy_path","provide","provide","provide","set_recipients","sighash","sort_tx","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unspendable","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","foreign_utxo","input_txid"],"q":["bdk","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::Utxo","","","bdk::descriptor","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::checksum","","bdk::descriptor::error","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::policy","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::policy::BuildSatisfaction","","","bdk::descriptor::policy::Satisfaction","","","","","","","","","","","bdk::descriptor::policy::SatisfiableItem","","","","","","","","","","bdk::descriptor::template","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::keys","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::psbt","","","","bdk::wallet","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::ApplyBlockError","","bdk::wallet::InsertTxError","","bdk::wallet::NewOrLoadError","","","","bdk::wallet::coin_selection","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::coin_selection::Error","","bdk::wallet::coin_selection::Excess","","","","","bdk::wallet::error","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::error::CreateTxError","","","","","","","","bdk::wallet::export","","","","","","","","","","","","","","","","","","","","bdk::wallet::signer","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::signer::SignerContext","bdk::wallet::tx_builder","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::tx_builder::AddForeignUtxoError",""],"d":["External keychain, used for deriving recipient addresses.","A UTXO owned by another wallet.","","Internal keychain, used for deriving change addresses.","Types of keychains","A UTXO owned by the local wallet.","An unspent output owned by a Wallet.","","","An unspent transaction output (UTXO).","","A Utxo with its satisfaction_weight.","Return KeychainKind as a byte","","","","","","","","","","","","","","","","","","","","The confirmation time for transaction containing this utxo","The derivation index for the script pubkey in the wallet","Descriptors","Macro to write full descriptors with code","","","","","","","","","","","Macro to write descriptor fragments with code","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Whether this UTXO is spent or not","Type of keychain","Key formats","Get the location of the UTXO","Reference to a transaction output","","Additional functions on the rust-bitcoin Psbt structure.","The weight of the witness data and scriptSig expressed in …","Get the sequence number if an explicit sequence number has …","","","","","","","","","","","","","","","","","Get the TxOut of the UTXO","Transaction output","","","","","The UTXO","Get the version of BDK at runtime","","","","","Wallet","The location of the output.","The information about the input we require to add it to a …","The nSequence value to set for this input.","A raw scriptpubkey (including pay-to-pubkey) under Legacy …","Alias for a Descriptor that contains extended derived keys","Script descriptor","","The descriptor pubkey, either a single pubkey or an xpub.","Alias for a Descriptor that can contain extended keys …","Trait implemented on Descriptors to add a method to …","Alias for the type of maps that represent derivation paths …","Trait for types which can be converted into an …","The consensus key associated with the type. Must be a …","Legacy ScriptContext To be used as P2SH scripts For …","The top-level miniscript abstract syntax tree (AST).","Multiple extended public keys.","Pay-to-PubKey-Hash","","The ScriptContext for Miniscript. Additional type …","Segwitv0 ScriptContext","Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)","Single public key.","Alias for the type of maps that represent taproot key …","Pay-to-Taproot","Pay-to-Witness-PubKey-Hash","Pay-to-Witness-ScriptHash with Segwitv0 context","Extended public key (xpub).","Computes the Bitcoin address of the descriptor, if one …","","","Get a reference to the inner AstElem representing the root …","","Replaces all wildcards (i.e. /*) in the descriptor with a …","","","","","","","","","Enumerates all child nodes of the current AST node (self) …","Attempt to produce a non-malleable witness template given …","Attempt to produce a malleable witness template given the …","","Depending on script Context, some of the Terminals might …","","","Depending on script Context, some of the script resource …","","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","","","Policy rules at the Miniscript satisfaction time. It is …","","","Check the consensus + policy(if not disabled) rules …","Each context has slightly different rules on what Pks are …","","","Depending on ScriptContext, fragments can be malleable. …","","","Check whether the given satisfaction is valid under the …","","","Descriptor checksum","","","","","","","","","","","","","Whether the given miniscript contains a raw pkh fragment","Deprecated name for Self::at_derivation_index.","Convert all the public keys in the descriptor to …","Convert all the public keys in the descriptor to …","Get the DescriptorType of Descriptor","","","","Encode as a Bitcoin script","","","","","Descriptor errors","Computes the the underlying script before any hashing is …","Additional information helpful for extra analysis.","Check whether the miniscript follows the given Extra …","Extract the spending policy","","","Utility method for deriving the descriptor at each index …","","","","","","","","","","Returns the argument unchanged.","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Add type information(Type and Extdata) to Miniscript based …","Create a new Miniscript from a Terminal node and a Type …","","Parse a Miniscript from string and perform sanity checks …","Attempt to parse an Miniscripts that don’t follow the …","Attempt to parse an insane(scripts don’t clear sanity …","Parse an expression tree into a descriptor.","Parse an expression tree into a Miniscript. As a general …","Returns child node with given index, if any","Returns Option::Some with cloned n’th public key from …","Returns satisfying non-malleable witness and scriptSig to …","Returns a possilbly mallable satisfying non-malleable …","Whether the miniscript contains a combination of timelocks","Whether the miniscript has repeated Pk or Pkh","Whether or not the descriptor has any wildcards i.e. /*.","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Extracts the AstElem representing the root of the …","Get as many descriptors as different paths in this …","Convert to wallet descriptor","","Whether or not the descriptor has any wildcards","Whether this descriptor contains a key that has multiple …","Whether the miniscript is malleable","Creates a new Iter iterator that will iterate over all …","Creates a new PkIter iterator that will iterate over all …","","","Lifting corresponds to conversion of a miniscript into a …","Depending on script context, the size of a satifaction …","","","Maximum size, in bytes, of a satisfying witness. For …","Computes an upper bound on the weight of a satisfying …","Maximum number of witness elements used to satisfy the …","Computes an upper bound on the difference between a …","Local helper function to display error messages with …","","","Create a new bare descriptor from witness script Errors …","Create a new pk descriptor","Create a new PkH descriptor","Create a new sh for a given redeem script Errors when …","Create a new sh sortedmulti descriptor with threshold k …","Create a new sh wrapper for the given wpkh descriptor","Create a new sh wrapper for the given wsh descriptor","Create a new sh wrapped wpkh from Pk. Errors when …","Create a new sh wrapped wsh descriptor with witness script …","Create a new sh wrapped wsh sortedmulti descriptor from …","Create new tr descriptor Errors when miniscript exceeds …","Create a new Wpkh descriptor Will return Err if …","Create a new wsh descriptor from witness script Errors …","Create a new wsh sorted multi descriptor Errors when …","A node in the AST.","Other top level checks that are context specific","Attempt to parse a Script into Miniscript representation.","Parse a descriptor that may contain secret keys","Attempt to parse an insane(scripts don’t clear sanity …","Attempt to parse an miniscript with extra features that …","","","","","Get the len of public key when serialized based on context …","","","Returns a plan if the provided assets are sufficient to …","Returns a plan if the provided assets are sufficient to …","Descriptor policy","Whether all spend paths of miniscript require a signature","Checks whether the descriptor is safe.","Check whether the underlying Miniscript is safe under the …","Attempts to produce a non-malleable satisfying witness and …","Attempt to produce non-malleable satisfying witness for the","Attempt to produce a malleable satisfying witness for the …","Computes the scriptCode of a transaction output.","Computes the scriptpubkey of the descriptor.","Size, in bytes of the script-pubkey. If this Miniscript is …","","","The type of signature required for satisfaction","","","Substitutes raw public keys hashes with the public keys as …","Descriptor templates","","","","","","","Serialize a descriptor to string with its secret keys","Check top level consensus rules.","Check whether the top-level is type B","Converts a descriptor using abstract keys to one using …","Translates a struct from one generic to another where the …","","","","","","","","","The correctness and malleability type information for the …","","","","","Computes the scriptSig that will be in place for an …","","","","","Whether the miniscript can exceed the resource …","Compute the checksum of a descriptor, excludes any …","Compute the checksum bytes of a descriptor, excludes any …","Error during base58 decoding","BIP32 error","Errors related to the parsing and usage of descriptors","The descriptor contains hardened derivation steps on …","Hex decoding error","Invalid byte found in the descriptor checksum","The provided descriptor doesn’t match its checksum","Invalid HD Key path, such as having a wildcard but a …","Error thrown while working with keys","Miniscript error","The descriptor contains multipath keys","Key-related error","Error while extracting and manipulating policies","","","","","","","Returns the argument unchanged.","","","","","","Calls U::from(self).","","","","","","","Absolute timeclock timestamp","Can not add to an item that is Satisfaction::None or …","Can not add to an item that is …","Options to build the satisfaction field in the policy","Can satisfy the policy item","An extra condition that must be satisfied but that is out …","Type for a map of sets of Condition items keyed by each set…","ECDSA Signature for a raw public key","An extended key fingerprint","Type for a map of folded sets of Condition items keyed by …","SHA256 then RIPEMD160 preimage hash","Double SHA256 preimage hash","Incompatible conditions (not currently used)","Index out of range for an item to satisfy a …","Can not merge CSV or timelock values unless both are less …","Multi-signature public keys with threshold count","Cannot satisfy or contribute to the policy item","Don’t generate satisfaction field","Not enough items are selected to satisfy a …","Only a partial satisfaction of some kind of threshold …","Can reach the threshold of some kind of threshold policy","A unique identifier for a key","Descriptor spending policy","Errors that can happen while extracting and manipulating …","Analyze the given PSBT to check for existing signatures","Like Psbt variant and also check for expired timelocks","A legacy public key","Relative timelock locktime","RIPEMD160 preimage hash","Represent if and how much a policy item is satisfied by …","An item that needs to be satisfied","Schnorr Signature for a raw public key","SHA256 preimage hash","Threshold items with threshold count","A x-only public key","","","","","","","","","","","","","","","","","","","","","","","","","","","How the wallet’s descriptor can satisfy this policy node","Optional CheckSequenceVerify condition","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Return the conditions that are set by the spending policy …","","","Returns a unique id for the SatisfiableItem","Identifier for this policy node","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Returns whether the SatisfiableItem is a leaf item","Returns whether the Satisfaction is a leaf item","Returns true if there are no extra conditions to verify","Type of this policy node","","","Return whether or not a specific path in the policy tree …","How much a given PSBT already satisfies this policy node …","","","","","","Optional timelock condition","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Current blockchain height","The highest confirmation height between the inputs CSV …","Given PSBT","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","The items that can be satisfied by the descriptor or are …","The items that can be satisfied by the descriptor","Threshold","Threshold","Total number of items","Total number of items","Whether the items are sorted in lexicographic order (used …","Whether the items are sorted in lexicographic order (used …","The digest value","The digest value","The digest value","The digest value","The policy items","The raw public key or extended key fingerprint","The required threshold count","The required threshold count","The timelock value","The timelock value","BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)","BIP44 public template. Expands to pkh(key/{0,1}/*)","BIP49 template. Expands to …","BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))","BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)","BIP84 public template. Expands to wpkh(key/{0,1}/*)","BIP86 template. Expands to tr(key/86'/{0,1}'/0'/{0,1}/*)","BIP86 public template. Expands to tr(key/{0,1}/*)","Trait for descriptor templates that can be built into a …","Type alias for the return type of DescriptorTemplate, …","P2PKH template. Expands to a descriptor pkh(key)","P2TR template. Expands to a descriptor tr(key)","P2WPKH template. Expands to a descriptor wpkh(key)","P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))","","","","","","","","","","","","","","","","","","","","","","","","","Build the complete descriptor","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","BIP32 error","Trait for keys that can be derived.","Container for public or secret keys","The descriptor pubkey, either a single pubkey or an xpub.","The descriptor secret key, either a single private key or …","Type specifying the amount of entropy required e.g. [u8;32]","Returned error in case of failure","Trait that adds extra useful methods to ScriptContexts","Enum for extended keys that can be either xprv or xpub","A bitcoin public key (compressed or uncompressed).","Trait that allows generating a key with the default options","Trait for keys that can be generated","Output of a GeneratableKey key generation","Trait for objects that can be turned into a public or …","The key has an invalid checksum","The key is not valid for the given network","The key cannot exist in the given script context","The consensus key associated with the type. Must be a …","Errors thrown while working with keys","Alias type for a map of public key to secret key","Legacy scripts","Custom error message","Miniscript error","Multiple extended private keys.","Multiple extended public keys.","Extra options required by the generate_with_entropy","A private extended key, aka an xprv","Options for generating a PrivateKey","A public extended key, aka an xpub","The ScriptContext for Miniscript. Additional type …","Enum representation of the known valid ScriptContexts","Segwitv0 scripts","Single public key.","Single private key.","A descriptor bitcoin::PrivateKey with optional origin …","A descriptor SinglePubKey with optional origin information.","Single public key without any origin or range information.","Contents of a “sortedmulti” descriptor","Taproot scripts","Set of valid networks for a key","An xonly public key.","Extended private key (xpriv).","Extended public key (xpub).","Create a set containing mainnet, testnet, signet, and …","Returns the ScriptContext as a ScriptContextEnum","Replaces any wildcard (i.e. /*) in the key with a …","","","","","","","","","","","","","","","","","","","","","","","","","Attempt to produce a witness template given the assets …","Depending on script Context, some of the Terminals might …","Depending on script Context, some of the script resource …","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","Policy rules at the Miniscript satisfaction time. It is …","Check the consensus + policy(if not disabled) rules …","Each context has slightly different rules on what Pks are …","Depending on ScriptContext, fragments can be malleable. …","Check whether the given satisfaction is valid under the …","","","","","","","","","","","","","","","","","","","","","","","Whether the generated key should be “compressed” or not","","","Deprecated name for Self::at_derivation_index.","","Encode as a Bitcoin script","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create an instance given a public key and a set of valid …","Create an instance given a secret key and a set of valid …","","","Parse an expression tree into a SortedMultiVec","Full path, from the master key","Returns a vector containing the full derivation paths from …","Generate a key given the options with a random entropy","Generate a key with the default options and a random …","Generate a key given the extra options and the entropy","Generate a key with the default options and a given entropy","Return whether or not the key contains the private data","Whether or not the key has a wildcard","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","Turn the key into a DescriptorKey within the requested …","Consume self and turn it into a DescriptorKey by adding …","","","","","","Consume self and turn it into an ExtendedKey","","","Consumes self and returns the key","Get as many keys as derivation paths in this key.","Get as many keys as derivation paths in this key.","Transform the ExtendedKey into an Xpriv for the given …","Transform the ExtendedKey into an Xpub for the given …","Whether or not the key has a wildcard","Returns whether the script context is Legacy","Returns whether the script context is …","Whether or not this key has multiple derivation paths.","Whether or not this key has multiple derivation paths.","Returns whether the script context is Segwitv0","Returns whether the script context is …","Returns whether the script context is Tap, aka Taproot or …","Returns whether the script context is …","","","signatures required","The public key.","The private key.","","Create a set only containing mainnet","The fingerprint of the master key associated with this …","Depending on script context, the size of a satifaction …","Maximum size, in bytes, of a satisfying witness. In …","Maximum number of witness elements used to satisfy the …","Compute the intersection of two sets","Local helper function to display error messages with …","Create a new instance of SortedMultiVec given a list of …","","Origin information (fingerprint and derivation path).","Origin information (fingerprint and derivation path).","Other top level checks that are context specific","Override the computed set of valid networks","","","","","Get the len of public key when serialized based on context …","public keys inside sorted Multi","","utility function to sanity a sorted multi vec","Attempt to produce a satisfying witness for the witness …","Size, in bytes of the script-pubkey. If this Miniscript is …","","The type of signature required for satisfaction","Create Terminal::Multi containing sorted pubkeys","Create a set containing testnet and regtest","","","","","","","","","","Returns the public version of this key.","","","","","Check top level consensus rules.","Check whether the top-level is type B","This will panic if fpk returns an uncompressed key when …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Trait to add functions to extract utxos and calculate fees.","The total transaction fee amount, sum of input amounts …","The transaction’s fee rate. This value will only be …","Get the TxOut for the specified input index, if it doesn’…","The address index selection strategy to use to derived an …","A derived address and the index it was found at. For …","An error that may occur when applying a block to Wallet.","Balance, differentiated into various categories.","Occurs when the update chain cannot connect with original …","The changes made to a wallet by applying an Update.","The error variant that occurs when the caller attempts to …","There was problem with the passed-in descriptor(s).","There was a problem with the passed-in descriptor(s).","There is a problem with the passed-in descriptor.","An error that may occur when inserting a transaction into …","Trait to check if a value is below the dust limit. We are …","Return the address for the current descriptor index if it …","Loading data from the persistence backend failed.","Loading from the persistence backend failed.","The error type when loading a Wallet from persistence.","The loaded genesis hash does not match what was provided.","The loaded network type does not match what was provided.","Data loaded from persistence is missing genesis hash.","Data loaded from persistence is missing network type.","Return a new address after incrementing the current …","The error type when constructing a fresh Wallet.","Error type for when we try load a Wallet from persistence …","Database already has data.","Wallet not initialized, persistence backend is empty.","Wallet is not initialized, persistence backend is empty.","Return the address for a specific descriptor index. Does …","Occurs when the connected_to hash does not match the hash …","An update to Wallet.","A Bitcoin wallet","We were unable to write the wallet’s data to the …","Writing to the persistence backend failed.","","Add an external signer","Address","Get unbounded script pubkey iterators for both Internal …","","Introduces a block of height to the wallet, and tries to …","Applies relevant transactions from block of height to the …","Apply relevant unconfirmed transactions to the wallet.","Applies an update to the wallet and stages the changes …","","","","","","","","","","","","","","","","","","","","","","","","Bump the fee of a transaction previously created with this …","Start building a transaction.","Calculates the fee of a given transaction. Returns 0 if tx …","Calculate the FeeRate for a given transaction.","Informs the wallet that you no longer intend to broadcast …","Update for the wallet’s internal LocalChain.","Changes to the LocalChain.","Get all the checkpoints the wallet is currently storing …","","","","","","","Coin selection","Commits all currently staged changed to the persistence …","Confirmed and immediately spendable balance","","","","","The derivation index of this wallet. It will return None …","Finds how the wallet derived the script pubkey spk.","Return the checksum of the public descriptor associated to …","","","","","","Errors that can be thrown by the Wallet","Wallet export","Finalize a PSBT, i.e., for each input determine if …","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Infallibly return a derived address using the external …","Return the balance, separated into available, …","Returns the descriptor used to create addresses for a …","Infallibly return a derived address using the internal …","get the corresponding PSBT Input for a LocalUtxo","Get the signers","Get a single transaction from the wallet as a CanonicalTx …","Returns the utxo owned by this wallet corresponding to …","Update for the wallet’s internal TxGraph.","All coinbase outputs not yet matured","Child index of this address","Changes to IndexedTxGraph.","Add a new checkpoint to the wallet’s internal view of …","Add a transaction to the wallet’s internal view of the …","Inserts a TxOut at OutPoint into the wallet’s …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Check whether or not a value is below dust limit","","Return whether or not a script is part of this wallet …","Type of keychain","Iterator over all keychains in this wallet","Contains the last active derivation indices per keychain (K…","Returns the latest checkpoint.","List all relevant outputs (includes both spent and …","Return the list of unspent outputs of this wallet","Load Wallet from the given persistence backend.","Get a reference to the inner LocalChain.","Get the Bitcoin network the wallet is using.","Stores the network type of the wallet.","Initialize an empty Wallet.","Creates a wallet that does not persist data.","Creates a wallet that does not persist data, with a custom …","Either loads Wallet from persistence, or initializes it if …","Either loads Wallet from persistence, or initializes it if …","Initialize an empty Wallet with a custom genesis hash.","The index of the next address that you would get if you …","Return the spending policies for the wallet’s descriptor","","","","","","Return the “public” version of the wallet’s …","Return the secp256k1 context used for all signing …","Compute the tx’s sent and received amounts (in satoshis).","","","Sign a transaction with all the wallet’s signers, in the …","Generalized signers","Get a reference to the inner KeychainTxOutIndex.","Returns the changes that will be committed with the next …","","","","","","","","","","","Get the whole balance visible to the wallet.","Iterate over the transactions in the wallet.","Unconfirmed UTXOs generated by a wallet tx","Get sum of trusted_pending and confirmed coins.","","","","","","","","","","","","Return a derived address using the external descriptor, …","Return a derived address using the internal (change) …","","","","","","","","","","","","Transaction builder","Get a reference to the inner TxGraph.","","","","","","","","","","","","Get an unbounded script pubkey iterator for the given …","Unconfirmed UTXOs received from an external wallet","","","","","","","","","","","","Deterministically generate a unique name given the …","Block hash of connected_to.","Expected block hash of connected_to, as derived from block.","The internal chain’s tip height.","The introduced transaction’s confirmation height.","The expected genesis block hash.","The expected network type.","The block hash loaded from persistence.","The network type loaded from persistence.","Branch and bound coin selection tries to avoid needing a …","Branch and bound coin selection possible attempts with …","Branch and bound coin selection","It’s possible to create spendable output from excess …","Trait for generalized coin selection algorithms","Result of a successful coin selection","Default coin selection algorithm used by TxBuilder if not …","Errors that can be thrown by the coin_selection module","Remaining amount after performing coin selection","Wallet’s UTXO set is not enough to cover recipient’s …","Simple and dumb coin selection","It’s not possible to create spendable output from excess …","OldestFirstCoinSelection always picks the utxo with the …","","","","","","","","","","","","","","","","","","","Perform the coin selection","","","","Decide if change can be created","","","","Remaining amount after deducing fees and outgoing outputs","Total fee amount for the selected utxos in satoshis","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","The total value of the inputs selected from the local …","Create new instance with target size for change output","","List of outputs selected for use as inputs","The total value of the inputs selected.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Sats available for spending","Sats needed for some transaction","Effective amount available to create change after …","The calculated fee for the drain TxOut with the selected …","Threshold to consider amount as dust for this particular …","The deducted change output fee","Exceeding amount of current selection over outgoing value …","Error returned from Wallet::build_fee_bump","The change_policy was set but the wallet does not have a …","There was an error with coin selection","Descriptor key conversion error","Error returned from TxBuilder::finish","There was a problem with the descriptors passed in","When bumping a tx the fee rate requested is lower than …","Node doesn’t have data to estimate a fee rate","When bumping a tx the absolute fee requested is lower than …","Wallet’s UTXO set is not enough to cover recipient’s …","Trying to replace a tx that has a sequence >= 0xFFFFFFFE","Requested LockTime is less than is required to spend from …","Miniscript PSBT error","Errors returned by miniscript when updating inconsistent …","In order to use the TxBuilder::add_global_xpubs option …","Missing non_witness_utxo on foreign utxo for given OutPoint","Cannot build a tx without recipients","manually_selected_only option is selected but no utxo has …","Output created is under the dust limit, 546 satoshis","Return error type for …","We were unable to write wallet data to the persistence …","There was a problem while extracting and manipulating …","Partially signed bitcoin transaction error","Cannot enable RBF with a Sequence >= 0xFFFFFFFE","Cannot enable RBF with Sequence given a required OP_CSV","Spending policy is not compatible with this KeychainKind","Happens when trying to bump a transaction that is already …","Thrown when a tx is not found in the internal database","Happens when trying to spend an UTXO that is not in the …","Happens when trying to spend an UTXO that is not in the …","Return error type for PsbtExt::update_input_with_descriptor","Requested invalid transaction version ‘0’","Requested transaction version 1, but at least 2 is needed …","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","Sats available for spending","Required OP_CSV Sequence","Sats needed for some transaction","Given RBF Sequence","Requested LockTime","Required LockTime","Required fee absolute value (satoshi)","Required fee rate","Structure that contains the export of a wallet","Alias for FullyNodedExport","Earliest block to rescan when looking for the wallet’s …","","","Return the internal descriptor, if present","Return the external descriptor","","Export a wallet","","Returns the argument unchanged.","","Calls U::from(self).","Arbitrary label for the wallet","","","","","","","The signer will sign all the leaves it has a key for.","Dummy identifier","The signer won’t sign the specified leaves.","To be used only by external libraries implementing …","The fingerprint of a BIP32 extended key","The signer won’t sign leaves other than the ones …","Input index is out of range","PSBT Input signer","The private key in use has the right fingerprint but …","The non_witness_utxo specified is invalid","Invalid SIGHASH for the signing context in use","Legacy context","Miniscript PSBT error","The fingerprint and derivation path are missing from the …","The private key is missing for the required public key","The non_witness_utxo field of the transaction is required …","The witness_script field of the transaction is required to …","The witness_utxo field of the transaction is required to …","The psbt contains a non-SIGHASH_ALL sighash in one of its …","The signer won’t sign any leaf.","Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA …","Segwit v0 context (BIP 143)","Error while computing the hash to sign","Options for a software signer","Common signer methods","Signing context","Signing error","Identifier of a signer in the SignersContainers. Used as a …","Defines the order in which signers are called","Wrapper to pair a signer with its context","Container for multiple signers","Taproot context (BIP 340)","Customize which taproot script-path leaves the signer …","PSBT signer","The user canceled the operation","Adds an external signer to the container for the specified …","Whether the signer should use the sighash_type set in the …","Whether we should grind ECDSA signature to ensure signing …","Create a map of public keys to secret keys","Whether the wallet should assume a specific height has …","","","","","","","","","","","","","","","","","Build a new signer container from a KeyMap","","","","","","","","","","","","","","","","","","","","","","Return the secret key for the signer","","","","","","","","Finds the signer with lowest ordering for a given id in …","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Return the SignerId for this signer","","","","Returns the list of identifiers of all the signers in the …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Create a wrapped signer from a signer and a context","Default constructor","","","","Removes a signer from the container and returns it","Whether to remove partial signatures from the PSBT inputs …","Whether to remove taproot specific fields from the PSBT on …","Sign a single psbt input","","","","Sign all the inputs of the psbt","","Whether we should try to sign a taproot transaction with …","Returns the list of signers in the container, sorted by …","Specifies which Taproot script-spend leaves we should sign …","","","","","","","","","Whether the signer should trust the witness_utxo, if the …","Whether to try finalizing the PSBT after the inputs are …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Whether the signer can sign for the internal key or not","Error returned from TxBuilder::add_foreign_utxo.","Error returned from TxBuilder::add_utxo and …","Error returned from TxBuilder::allow_shrinking","BIP69 / Lexicographic","Marker type to indicate the TxBuilder is being used to …","Use both change and non-change outputs (default)","Only use non-change outputs (see …","Policy regarding the use of change outputs when creating a …","Marker type to indicate the TxBuilder is being used to …","Requested outpoint doesn’t exist in the tx (vout greater …","Foreign utxo outpoint txid does not match PSBT input txid","Script/PubKey was not in the original transaction","Foreign utxo missing witness_utxo or non_witness_utxo","Only use change outputs (see TxBuilder::only_spend_change)","Randomized (default)","A transaction builder","Context in which the TxBuilder is valid","Ordering of the transaction’s inputs and outputs","Happens when trying to spend an UTXO that is not in the …","Unchanged","Add data as an output, using OP_RETURN","Add a foreign UTXO i.e. a UTXO not owned by this wallet.","Same as add_foreign_utxo but allows to set the nSequence …","Fill-in the PSBT_GLOBAL_XPUB field with the extended keys …","Add a recipient to the internal list","Add a utxo to the internal list of unspendable utxos","Add a utxo to the internal list of utxos that must be spent","Add the list of outpoints to the internal list of UTXOs …","Set whether or not the dust limit is checked.","Explicitly tells the wallet that it is allowed to reduce …","","","","","","","","","","","","","","","","","Set a specific ChangeSpendPolicy. See …","","","","","","","","","","","","","Choose the coin selection algorithm","Set the current blockchain height.","","","","","Do not spend change outputs","Sets the address to drain excess coins to.","Spend all the available inputs. This respects filters like …","Enable signaling RBF","Enable signaling RBF with a specific nSequence value","","","Set an absolute fee The fee_absolute method refers to the …","Set a custom fee rate.","Finish building the transaction.","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Fill-in the psbt::Output::redeem_script and …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Only spend utxos added by add_utxo.","Use a specific nLockTime while creating the transaction","Only spend change outputs","Only Fill-in the psbt::Input::witness_utxo field when …","Choose the ordering for inputs and outputs of the …","","","Set the policy path to use while creating the transaction …","","","","Replace the recipients already added with a new list","Sign with a specific sig hash","Sort transaction inputs and outputs by TxOrdering variant","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Replace the internal list of unspendable utxos with a new …","Build a transaction with a specific version","","","","","","","","","Foreign UTXO outpoint","PSBT input txid"],"i":[1,5,0,1,0,5,0,0,0,0,0,0,1,1,1,3,4,5,1,3,4,5,0,1,3,4,5,1,3,4,5,1,3,3,0,0,1,3,1,3,4,5,1,3,4,5,0,1,3,4,5,1,3,1,3,4,5,3,3,0,5,3,1,0,4,5,1,3,0,0,1,3,4,5,1,3,4,5,1,3,4,5,5,3,1,3,4,5,4,0,1,3,4,5,0,198,198,198,17,0,0,0,0,0,0,0,0,48,0,0,26,17,0,0,0,17,26,0,17,17,17,26,17,35,36,23,23,17,17,35,36,23,17,35,36,23,23,23,23,0,48,35,36,48,36,48,48,35,36,48,35,36,48,48,35,36,48,35,36,48,35,36,0,17,35,36,23,17,35,36,23,17,35,36,23,23,17,17,17,17,17,23,17,23,17,35,36,23,0,17,23,23,199,17,23,17,17,17,35,36,23,23,17,23,17,17,17,17,17,17,17,35,36,23,23,23,17,23,23,23,17,23,23,23,17,17,23,23,17,17,35,36,23,17,35,36,23,23,17,166,62,17,17,23,23,23,17,23,23,48,35,36,23,17,23,17,48,35,36,17,17,17,17,17,17,17,17,17,17,17,17,17,17,23,48,23,17,23,23,17,35,36,23,48,35,36,17,17,0,23,17,23,17,23,23,17,17,23,17,23,48,35,36,23,0,17,35,36,23,17,23,17,48,48,17,23,17,35,36,23,17,35,36,23,23,17,35,36,23,17,17,35,36,23,23,0,0,47,47,0,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,83,77,77,0,84,0,0,83,82,0,83,83,77,77,77,83,84,45,77,84,84,0,0,0,45,45,82,83,83,0,0,83,83,83,82,82,83,84,46,85,77,45,82,83,84,46,85,77,45,82,83,84,46,85,45,82,83,84,46,85,45,46,85,85,82,83,84,46,85,77,82,83,84,46,85,77,77,45,82,83,84,84,46,46,85,77,45,46,82,85,83,46,82,83,84,46,85,77,45,83,84,85,46,85,77,46,46,82,83,84,46,85,85,82,83,84,46,85,45,77,82,83,84,46,85,77,45,82,83,84,46,85,77,45,82,83,84,46,85,77,45,82,83,84,46,85,77,45,200,200,200,201,202,203,202,203,202,203,202,203,202,203,204,205,206,207,208,209,209,208,210,211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,212,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,86,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,75,0,0,0,0,213,213,0,0,110,0,0,0,0,75,75,75,48,0,0,22,75,75,107,26,213,114,0,114,0,0,22,26,107,0,0,0,0,22,0,110,107,26,0,214,26,114,105,112,22,106,75,103,26,107,108,109,110,114,105,112,22,106,75,103,26,107,108,109,110,103,48,48,48,48,48,48,48,48,48,105,22,106,103,26,107,108,109,110,105,22,106,103,26,107,108,109,110,103,26,108,110,106,106,105,26,26,103,22,103,26,107,108,109,110,112,22,106,75,75,103,103,26,26,107,107,108,109,110,103,114,114,114,105,112,22,106,75,75,75,103,26,26,107,108,109,110,112,112,26,107,103,26,26,213,215,213,215,114,26,103,26,108,110,114,105,112,22,106,75,103,26,107,108,109,110,26,87,93,105,105,112,26,107,93,114,105,105,26,107,114,114,26,214,22,26,107,214,22,214,22,26,26,103,108,109,103,0,26,48,103,103,0,48,103,26,108,109,48,112,103,26,108,110,48,103,75,103,103,103,26,48,103,0,105,22,106,103,26,107,108,109,110,107,75,103,26,107,48,48,103,114,105,112,22,106,75,103,26,107,108,109,110,114,105,112,22,106,75,103,26,107,108,109,110,114,105,112,22,106,75,103,26,107,108,109,110,114,105,112,22,106,75,103,26,107,108,109,110,0,216,216,216,0,0,0,0,154,0,153,150,151,152,0,0,149,151,152,0,152,152,151,151,149,0,0,150,151,152,149,154,0,0,150,152,122,123,145,123,128,123,123,123,123,123,122,123,134,128,149,145,150,151,152,153,154,122,123,134,128,149,145,150,151,152,153,154,123,123,123,123,123,134,128,123,122,134,128,122,134,128,0,123,122,122,134,128,145,123,123,123,122,128,122,128,145,0,0,123,122,122,123,134,128,149,145,145,150,150,151,151,152,152,153,153,154,154,122,123,134,128,128,128,149,145,150,151,152,153,154,123,123,123,123,123,123,123,123,134,122,145,128,123,123,123,122,123,134,128,149,145,150,151,152,153,154,217,128,123,145,123,134,123,123,123,123,123,123,128,123,123,123,123,123,123,123,123,150,151,152,153,154,123,123,123,122,128,123,0,123,123,122,134,128,122,145,150,151,152,153,154,122,123,122,122,122,123,134,128,149,145,150,151,152,153,154,123,123,122,123,134,128,149,145,150,151,152,153,154,0,123,122,123,134,128,149,145,150,151,152,153,154,123,122,122,123,134,128,149,145,150,151,152,153,154,0,218,218,219,219,220,221,220,221,174,174,0,175,0,0,0,0,0,174,0,175,0,174,175,173,170,171,172,174,175,173,170,171,172,170,171,172,170,171,172,190,170,171,172,0,170,171,172,173,173,174,174,175,173,170,171,172,174,175,173,170,171,172,174,175,173,170,171,172,173,172,174,173,173,170,171,172,174,174,175,173,170,171,172,174,175,173,170,171,172,174,175,173,170,171,172,174,175,173,170,171,172,222,222,223,224,224,223,224,0,161,161,176,0,161,161,140,161,161,140,161,161,0,161,161,161,161,161,176,161,161,161,161,161,161,140,140,161,140,176,161,161,176,161,140,176,161,140,176,176,176,176,161,161,140,140,176,161,161,161,161,161,161,140,176,161,140,176,161,140,176,176,161,140,176,161,140,176,161,140,176,161,140,176,161,140,225,226,225,226,227,227,228,229,0,0,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,184,179,184,148,179,184,148,0,148,148,148,181,148,148,148,148,148,148,148,184,179,181,148,0,0,0,0,0,0,0,0,181,0,0,148,44,147,147,44,147,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,44,179,181,183,124,44,147,184,179,181,183,124,44,147,184,179,124,124,44,147,184,183,230,183,183,183,179,181,124,184,44,179,148,148,181,183,124,44,147,184,179,179,179,148,148,181,183,124,44,147,184,179,230,183,183,183,44,179,148,181,183,124,44,147,184,183,44,179,124,148,44,147,147,231,183,183,183,125,183,147,44,147,179,181,183,124,44,147,184,148,147,147,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,232,0,0,0,195,0,194,194,0,0,191,191,193,191,194,195,0,0,0,192,195,139,139,139,139,139,139,139,139,139,139,141,138,139,192,191,193,195,194,141,138,139,192,191,193,195,194,139,141,138,139,195,194,141,138,139,195,194,195,194,139,139,141,138,195,194,139,139,139,139,139,195,194,139,139,139,141,138,139,192,192,191,191,193,193,195,194,141,138,139,192,191,193,195,194,195,194,139,141,138,139,192,191,193,195,194,139,139,139,139,139,195,194,139,192,191,193,139,139,195,141,138,139,195,194,192,191,193,141,138,139,192,191,193,195,194,141,138,139,192,191,193,195,194,141,138,139,192,191,193,195,194,139,139,141,138,139,192,191,193,195,194,233,233],"f":[0,0,0,0,0,0,0,0,0,0,0,0,[1,2],[1],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[1,1],[3,3],[4,4],[5,5],[[]],[[]],[[]],[[]],[[1,1],6],0,0,0,0,[[],[[7,[1]]]],[[],[[7,[3]]]],[[1,1],8],[[3,3],8],[[4,4],8],[[5,5],8],[[1,9],10],[[3,9],10],[[4,9],10],[[5,9],10],0,[[]],[[]],[[]],[[]],[1],[3],[[]],[[]],[[]],[[]],0,0,0,[5,11],0,[[1,1],[[12,[6]]]],0,0,[5,[[12,[13]]]],[1,7],[3,7],0,0,[[]],[[]],[[]],[[]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[5,14],0,[[],15],[[],15],[[],15],[[],15],0,[[],16],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[17,18],[[7,[[20,[19]],21]]]],[[],22],[[],22],[23,24],[23,[[25,[23]]]],[[[17,[26]],27],[[7,[[17,[28]],29]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[23,[[31,[23,30]]]],[23,[[33,[32]]]],[23,[[33,[32]]]],0,[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],[24,[[7,[34]]]],[24,[[7,[34]]]],[24,[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],0,[17,17],[35,35],[36,36],[23,23],[[]],[[]],[[]],[[]],[[17,17],6],[[35,35],6],[[36,36],6],[[23,23],6],[23,8],[[[17,[26]],27],[[7,[[17,[28]],29]]]],[[[17,[26]],37,27],[[7,[[17,[38]],29]]]],[[[17,[28]],37],[[7,[[17,[38]],29]]]],[17,39],[[],[[7,[17]]]],[[],[[7,[23]]]],[[[17,[26]]],40],[23,41],[[17,17],8],[[35,35],8],[[36,36],8],[[23,23],8],0,[17,[[7,[41,21]]]],0,[[23,42],[[7,[43]]]],[[44,45,37],[[7,[[12,[46]],47]]]],[[[17,[26]],44,45,37],[[7,[[12,[46]],47]]]],[[[23,[26,48]],44,45,37],[[7,[[12,[46]],47]]]],[[[17,[26]],37,49,[50,[27]]],[[7,[12,29]]]],[[17,9],[[7,[51]]]],[[17,9],[[7,[51]]]],[[35,9],[[7,[51]]]],[[36,9],[[7,[51]]]],[[23,9],[[7,[51]]]],[[23,9],[[7,[51]]]],[17,8],[23,8],[52,17],[[]],[53,17],[54,17],[55,17],[56,17],[57,17],[[]],[[]],[[]],[24,[[7,[23,21]]]],[[24,58,59],23],[16,[[7,[17,21]]]],[16,[[7,[23,21]]]],[[16,42],[[7,[23,21]]]],[16,[[7,[23,21]]]],[60,[[7,[17,21]]]],[60,[[7,[23,21]]]],[[23,61],[[12,[23]]]],[[23,61],12],[17,[[7,[21]]]],[17,[[7,[21]]]],[23,8],[23,8],[[[17,[26]]],8],[17],[35],[36],[23],[[]],[[]],[[]],[[]],[23,24],[[[17,[26]]],[[7,[[31,[[17,[26]],30]],21]]]],[[37,18],[[7,[47]]]],[[62,37,18],[[7,[47]]]],[[[17,[26]]],8],[[[17,[26]]],8],[23,8],[23,63],[23,64],[17,[[7,[65,21]]]],[23,[[7,[65,21]]]],[23,[[7,[66]]]],[23,[[12,[61]]]],[23,[[12,[61]]]],[23,[[12,[61]]]],[23,[[7,[61,21]]]],[17,[[7,[61,21]]]],[23,[[7,[61,21]]]],[17,[[7,[61,21]]]],[[],16],[[],16],[[],16],[[[23,[67]]],[[7,[17,21]]]],[[],17],[[],[[7,[17,21]]]],[[[23,[35]]],[[7,[17,21]]]],[[61,[31,[30]]],[[7,[17,21]]]],[55,17],[57,17],[[],[[7,[17,21]]]],[[[23,[36]]],[[7,[17,21]]]],[[61,[31,[30]]],[[7,[17,21]]]],[[[12,[68]]],[[7,[17,21]]]],[[],[[7,[17,21]]]],[[[23,[36]]],[[7,[17,21]]]],[[61,[31,[30]]],[[7,[17,21]]]],0,[23,[[7,[21]]]],[49,[[7,[23,21]]]],[[37,16],[[7,[21]]]],[49,[[7,[23,21]]]],[[49,42],[[7,[23,21]]]],[[17,17],[[12,[6]]]],[[35,35],[[12,[6]]]],[[36,36],[[12,[6]]]],[[23,23],[[12,[6]]]],[[],61],[[],61],[[],61],[[[17,[28]]],[[7,[69,[17,[28]]]]]],[[[17,[28]]],[[7,[69,[17,[28]]]]]],0,[23,8],[17,[[7,[21]]]],[23,[[7,[43]]]],[[17,70],[[7,[21]]]],[23,[[7,[[31,[[31,[2,30]],30]],21]]]],[23,[[7,[[31,[[31,[2,30]],30]],21]]]],[17,[[7,[41,21]]]],[17,41],[23,61],[17,7],[23,7],[[],71],[[],71],[[],71],[[23,72],23],0,[[]],[[]],[[]],[[]],[[],73],[[],73],[[[17,[26]],72],73],[23,[[7,[21]]]],[23,[[7,[21]]]],[17,[[7,[74]]]],[23,[[7,[74]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],0,[[],15],[[],15],[[],15],[[],15],[17,41],[[]],[[]],[[]],[[]],[23,8],[16,[[7,[73,47]]]],[16,[[7,[47]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[47,9],10],[[47,9],10],[75,47],[76,47],[[]],[77,47],[78,47],[21,47],[79,47],[80,47],[[]],[81],[[],73],[[],7],[[],7],[[],15],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[82,82],[83,83],[84,84],[46,46],[85,85],[45,45],[[]],[[]],[[]],[[]],[[]],[[]],0,0,[[],85],[[82,82],8],[[83,83],8],[[84,84],8],[[46,46],8],[[85,85],8],[[77,77],8],[[82,9],10],[[83,9],10],[[84,9],10],[[46,9],10],[[85,9],10],[[77,9],10],[[77,9],10],[[45,9],10],[[]],[[]],[8,84],[[]],[83,46],[[]],[[]],[[]],[[]],[[46,72],[[7,[85,77]]]],[82],[85],[83,73],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[83,8],[84,8],[85,8],0,[[85,85],[[12,[6]]]],[81],[46,8],0,[82,7],[83,7],[84,7],[46,7],[85,7],0,[[]],[[]],[[]],[[]],[[]],[[]],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[18,[[7,[86,47]]]],[[[88,[[87,[35]]]],18],[[7,[86,47]]]],[[[89,[[87,[36]]]],18],[[7,[86,47]]]],[[[90,[[87,[36]]]],18],[[7,[86,47]]]],[[[92,[[87,[91]]]],18],[[7,[86,47]]]],[[[94,[[93,[35]]]],18],[[7,[86,47]]]],[[[95,[[93,[35]]]],18],[[7,[86,47]]]],[[[96,[[93,[36]]]],18],[[7,[86,47]]]],[[[97,[[93,[36]]]],18],[[7,[86,47]]]],[[[98,[[93,[36]]]],18],[[7,[86,47]]]],[[[99,[[93,[36]]]],18],[[7,[86,47]]]],[[[100,[[93,[91]]]],18],[[7,[86,47]]]],[[[101,[[93,[91]]]],18],[[7,[86,47]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[86,37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],102],[[],22],[[26,27],[[7,[28,29]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[103,[[33,[32]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[[],[[7,[34]]]],[24,[[7,[34]]]],[[],[[7,[34]]]],[[[105,[104,48]]],[[105,[104,48]]]],[22,22],[106,106],[103,103],[26,26],[107,107],[108,108],[109,109],[110,110],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[103,103],6],[[26,26],6],[[108,108],6],[[110,110],6],0,[[],106],[[[105,[48]]]],[[26,27],[[7,[28,29]]]],[[],[[7,[26]]]],[103,41],[[22,22],8],[[103,103],8],[[26,26],8],[[107,107],8],[[108,108],8],[[109,109],8],[[110,110],8],[[[112,[[0,[111,48]]]],9],10],[[22,9],10],[[106,9],10],[[75,9],10],[[75,9],10],[[103,9],[[7,[51]]]],[[103,9],[[7,[51]]]],[[26,9],[[7,[51]]]],[[26,9],[[7,[51]]]],[[107,9],[[7,[51]]]],[[107,9],[[7,[51]]]],[[108,9],[[7,[51]]]],[[109,9],[[7,[51]]]],[[110,9],[[7,[51]]]],[103,8],[[]],[113,[[114,[48]]]],[115,[[114,[48]]]],[[]],[[]],[[]],[[]],[21,75],[76,75],[[]],[[]],[28,26],[[]],[[]],[[]],[[]],[[]],[[26,102],[[112,[48]]]],[[107,102],[[112,[48]]]],[16,[[7,[26]]]],[16,[[7,[107]]]],[60,[[7,[103,21]]]],[26,[[12,[116]]]],[26,[[31,[116,30]]]],[[],[[7,[105]]]],[[],[[7,[105]]]],[[],[[7,[105]]]],[[],[[7,[105]]]],[[[114,[48]]],8],[26,8],[103],[26],[108],[110],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[26,117],[[],[[7,[112,75]]]],[[[12,[118]],116],[[7,[112,75]]]],[105,[[7,[112,75]]]],[[105,[12,[118]],116],[[7,[112,75]]]],[[[112,[48]]],[[7,[[112,[48]],75]]]],[26,[[7,[[112,[48]],75]]]],[107,[[7,[[112,[48]],75]]]],[[],[[7,[114,75]]]],[[[114,[48]]],[[7,[[114,[48]],75]]]],[105,[[7,[114,75]]]],[[[105,[48]]]],[26,[[31,[26,30]]]],[107,[[31,[107,30]]]],[[[114,[48]],18],[[12,[113]]]],[[[114,[48]],18,37],115],[26,8],[[],8],[22,8],[26,8],[107,8],[[],8],[22,8],[[],8],[22,8],[26,8],[26,8],0,0,0,[103,[[7,[65,21]]]],[[],102],[26,119],[23,[[12,[61]]]],[103,61],[103,61],[[102,102],102],[[],16],[[61,[31,[30]]],[[7,[103,21]]]],[26,61],0,0,[23,[[7,[21]]]],[[[112,[48]],102],[[112,[48]]]],[[103,103],[[12,[6]]]],[[26,26],[[12,[6]]]],[[108,108],[[12,[6]]]],[[110,110],[[12,[6]]]],[[],61],0,[81],[103,[[7,[21]]]],[103,[[7,[[31,[[31,[2,30]],30]],21]]]],[103,61],[26,7],[[],71],[103,24],[[],102],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[107,37],[[7,[26,120]]]],[[],73],[[],73],[[],73],[[],73],[23,[[7,[21]]]],[23,[[7,[21]]]],[103,[[7,[103,74]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[],[[12,[40]]]],[[],[[12,[121]]]],[61,[[12,[14]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[122,122],122],[[123,1,124,[126,[125]]]],0,[123,[[72,[1,[0,[127,104]]]]]],[[128,128]],[[123,129,27],[[7,[130]]]],[[123,129,27,131],[[7,[132]]]],[[123,133]],[[123,134],[[7,[130]]]],[123,135],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[123,136],[[7,[[139,[137,138]],140]]]],[123,[[139,[137,141]]]],[[123,142],[[7,[40,143]]]],[[123,142],[[7,[121,143]]]],[[123,142]],0,0,[123,144],[122,122],[134,134],[128,128],[[]],[[]],[[]],0,[123,[[7,[8]]]],0,[[],122],[[],134],[[],128],[145],[[123,1],[[12,[27]]]],[[123,49],12],[[123,1],73],[[],[[7,[122]]]],[[],[[7,[128]]]],[[122,122],8],[[128,128],8],[[145,145],8],0,0,[[123,146,147],[[7,[8,148]]]],[[122,9],[[7,[51]]]],[[122,9],[[7,[51]]]],[[[123,[111]],9],10],[[134,9],10],[[128,9],10],[[149,9],10],[[145,9],10],[[145,9],10],[[150,9],10],[[[150,[111]],9],10],[[[151,[111]],9],10],[[151,9],10],[[[152,[111,111]],9],10],[[152,9],10],[[153,9],10],[[153,9],10],[[154,9],10],[[154,9],10],[[]],[[]],[[]],[[[157,[155,[156,[1]]]]],128],[[]],[158,128],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[123,149],145],[123,122],[[123,1],62],[[123,149],145],[[123,3,[12,[159]],8],[[7,[160,161]]]],[[123,1],[[126,[44]]]],[[123,136],[[12,[[162,[[126,[142]],155]]]]]],[[123,11],[[12,[3]]]],0,0,0,0,[[123,131],[[7,[8,163]]]],[[123,142,164],[[7,[8,153]]]],[[123,11,14]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[49,8],[128,8],[[123,49],8],0,[123,72],0,[123,165],[123,127],[123,127],[[166,[12,[166]]],[[7,[123,151]]]],[123,167],[123,18],0,[[166,[12,[166]],18],[[7,[123,150]]]],[[166,[12,[166]],18],[[7,[123,47]]]],[[166,[12,[166]],18,168],[[7,[123,47]]]],[[166,[12,[166]],18],[[7,[123,152]]]],[[166,[12,[166]],18,168],[[7,[123,152]]]],[[166,[12,[166]],18,168],[[7,[123,150]]]],[[123,1],27],[[123,1],[[7,[[12,[46]],47]]]],[81],[81],[81],[81],[81],[[123,1],[[12,[62]]]],[123,37],[[123,142]],[122,7],[128,7],[[123,146,147],[[7,[8,148]]]],0,[123,169],[123,128],[[]],[[]],[[]],[[],73],[[],73],[[],73],[[],73],[[],73],[[],73],[[],73],[122,40],[123,127],0,[122,40],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[123,149],[[7,[145]]]],[[123,149],[[7,[145]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],0,[123,135],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[123,1],[[0,[127,104]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[12,18,37],[[7,[73,47]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[170,170],[171,171],[172,172],[[]],[[]],[[]],[[[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[170,[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[171,[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[172,[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[40,121,49],175],[[],170],[[],171],[[],172],0,0,[[174,9],10],[[174,9],10],[[175,9],10],[[173,9],10],[[170,9],10],[[171,9],10],[[172,9],10],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[173,40],[40,172],[81],0,[173,40],[[]],[[]],[[]],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[176,176],[[]],[[176,9],10],[[176,9],10],[[[161,[111]],9],10],[[161,9],10],[[140,9],10],[[140,9],10],[[]],[174,161],[77,161],[176,161],[[]],[177,161],[47,161],[[]],[[]],[[]],[[]],[81],[81],[81],[[]],[[],73],[[],73],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[178,[[12,[73]]]],[178,73],[[],[[7,[178]]]],[[123,16,8],[[7,[178,16]]]],[[178,9],10],[[]],[16,[[7,[178]]]],[[]],0,[178,7],[178,73],[[],7],[[],7],[[],15],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[44,179,124,[126,[125]]],[[12,[[126,[125]]]]]],0,0,[[44,37],180],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[180,17,37],44],[179,179],[181,181],[[[183,[[0,[104,182,111,104]]]]],[[183,[[0,[104,182,111,104]]]]]],[124,124],[44,44],[147,147],[184,184],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[179,179],6],[[124,124],6],[[],124],[[],44],[[],147],[[],184],[[[183,[[0,[182,111,104]]]]]],[[],[[12,[107]]]],[[[183,[185]]],[[12,[107]]]],[[[183,[[186,[113]]]]],[[12,[107]]]],[[[183,[[187,[113]]]]],[[12,[107]]]],[[179,179],8],[[181,181],8],[[124,124],8],[[184,184],8],[[44,179],[[12,[126]]]],[[179,9],10],[[148,9],10],[[148,9],10],[[181,9],10],[[[183,[[0,[111,182,111,104]]]],9],10],[[124,9],10],[[44,9],10],[[147,9],10],[[184,9],10],[188,179],[119,179],[[]],[189,148],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[179],[37,179],[[[183,[185]],37],179],[[[183,[[186,[113]]]],37],179],[[[183,[[187,[113]]]],37],179],[44,[[31,[179]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[0,[182,111,104]],181],[[183,[[0,[182,111,104]]]]]],[[],44],[[179,179],[[12,[6]]]],[[124,124],[[12,[6]]]],[81],[[44,179,124],[[12,[[126,[125]]]]]],0,0,[[146,61,147,37],[[7,[148]]]],[[[183,[185]],146,61,147,37],[[7,[148]]]],[[[183,[[186,[113]]]],146,61,147,37],[[7,[148]]]],[[[183,[[187,[113]]]],146,61,147,37],[[7,[148]]]],[[146,147,37],[[7,[148]]]],[[146,147,37],[[7,[148]]]],0,[44,[[31,[126]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],73],0,0,[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[[139,[190,141]]],[[139,[190,141]]]],[[139,11,160,61],[[7,[139,191]]]],[[139,11,160,61,13],[[7,[139,191]]]],[139,139],[[[139,[190,141]],41,40],[[139,[190,141]]]],[[139,11],139],[[139,11],[[7,[139,192]]]],[139,[[7,[139,192]]]],[[139,8],139],[[[139,[137,138]],41],[[7,[[139,[137,138]],193]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[139,194],139],[141,141],[138,138],[[[139,[104]]],[[139,[104]]]],[195,195],[194,194],[[]],[[]],[[]],[[]],[[]],[[195,195],6],[[194,194],6],[[139,190],[[139,[190]]]],[[139,27],139],[[],141],[[],138],[[],195],[[],194],[139,139],[[[139,[190,141]],41],[[139,[190,141]]]],[139,139],[139,139],[[139,13],139],[[195,195],8],[[194,194],8],[[139,40],139],[[139,121],139],[[[139,[190]]],[[7,[146,161]]]],[[141,9],10],[[138,9],10],[[[139,[111,111,111]],9],10],[[192,9],10],[[192,9],10],[[191,9],10],[[191,9],10],[[193,9],10],[[193,9],10],[[195,9],10],[[194,9],10],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[195],[194],[139,139],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[139,139],[[139,196],139],[139,139],[139,139],[[139,195],139],[[195,195],[[12,[6]]]],[[194,194],[[12,[6]]]],[[139,[72,[73,[31,[61]]]],1],139],[81],[81],[81],[[[139,[190,141]],31],[[139,[190,141]]]],[[139,159],139],[[195,142]],[[]],[[]],[[]],[[]],[[]],[[],73],[[],73],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[139,[31,[11]]],139],[[139,197],139],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0],"p":[[4,"KeychainKind"],[15,"u8"],[3,"LocalOutput"],[3,"WeightedUtxo"],[4,"Utxo"],[4,"Ordering"],[4,"Result"],[15,"bool"],[3,"Formatter"],[6,"Result"],[3,"OutPoint"],[4,"Option"],[3,"Sequence"],[3,"TxOut"],[3,"TypeId"],[15,"str"],[4,"Descriptor"],[4,"Network"],[4,"NetworkChecked"],[3,"Address"],[4,"Error"],[4,"ScriptContextEnum"],[3,"Miniscript"],[4,"Terminal"],[4,"Tree"],[4,"DescriptorPublicKey"],[15,"u32"],[3,"DefiniteDescriptorKey"],[4,"ConversionError"],[3,"Global"],[3,"Vec"],[4,"Placeholder"],[3,"Satisfaction"],[4,"ScriptContextError"],[4,"Legacy"],[4,"Segwitv0"],[3,"Secp256k1"],[3,"PublicKey"],[4,"DescriptorType"],[15,"u64"],[3,"ScriptBuf"],[3,"ExtParams"],[4,"AnalysisError"],[3,"SignersContainer"],[4,"BuildSatisfaction"],[3,"Policy"],[4,"Error"],[8,"ScriptContext"],[3,"Script"],[3,"Range"],[3,"Error"],[3,"Tr"],[3,"Sh"],[3,"Bare"],[3,"Wpkh"],[3,"Pkh"],[3,"Wsh"],[3,"Type"],[3,"ExtData"],[3,"Tree"],[15,"usize"],[6,"ExtendedDescriptor"],[3,"Iter"],[3,"PkIter"],[4,"Policy"],[4,"LiftError"],[4,"BareCtx"],[4,"TapTree"],[3,"Plan"],[3,"TxIn"],[4,"SigType"],[3,"BTreeMap"],[3,"String"],[4,"TranslateErr"],[4,"KeyError"],[4,"Error"],[4,"PolicyError"],[4,"HexToBytesError"],[4,"Error"],[4,"Error"],[3,"Demand"],[4,"PkOrF"],[4,"SatisfiableItem"],[4,"Satisfaction"],[3,"Condition"],[6,"DescriptorTemplateOut"],[8,"IntoDescriptorKey"],[3,"P2Pkh"],[3,"P2Wpkh_P2Sh"],[3,"P2Wpkh"],[4,"Tap"],[3,"P2TR"],[8,"DerivableKey"],[3,"Bip44"],[3,"Bip44Public"],[3,"Bip49"],[3,"Bip49Public"],[3,"Bip84"],[3,"Bip84Public"],[3,"Bip86"],[3,"Bip86Public"],[6,"ValidNetworks"],[3,"SortedMultiVec"],[8,"Clone"],[3,"GeneratedKey"],[3,"PrivateKeyGenerateOptions"],[4,"DescriptorSecretKey"],[3,"SinglePub"],[3,"SinglePriv"],[4,"SinglePubKey"],[8,"Debug"],[4,"DescriptorKey"],[3,"Xpriv"],[4,"ExtendedKey"],[3,"Xpub"],[3,"DerivationPath"],[3,"Assets"],[6,"KeySource"],[3,"Fingerprint"],[3,"DescriptorKeyParseError"],[3,"FeeRate"],[3,"Balance"],[3,"Wallet"],[3,"SignerOrdering"],[8,"TransactionSigner"],[3,"Arc"],[8,"Iterator"],[3,"ChangeSet"],[3,"Block"],[3,"CannotConnectError"],[3,"BlockId"],[4,"ApplyHeaderError"],[8,"IntoIterator"],[3,"Update"],[3,"TxGraph"],[3,"Txid"],[6,"DefaultCoinSelectionAlgorithm"],[3,"BumpFee"],[3,"TxBuilder"],[4,"BuildFeeBumpError"],[3,"CreateTx"],[3,"Transaction"],[4,"CalculateFeeError"],[3,"CheckPointIter"],[3,"AddressInfo"],[3,"Psbt"],[3,"SignOptions"],[4,"SignerError"],[4,"AddressIndex"],[4,"NewError"],[4,"LoadError"],[4,"NewOrLoadError"],[4,"InsertTxError"],[4,"ApplyBlockError"],[3,"ConfirmationTimeHeightAnchor"],[3,"ChangeSet"],[3,"ChangeSet"],[6,"ChangeSet"],[3,"PsbtSighashType"],[3,"Input"],[4,"CreateTxError"],[3,"CanonicalTx"],[3,"AlterCheckPointError"],[4,"ConfirmationTime"],[3,"CheckPoint"],[8,"IntoWalletDescriptor"],[3,"LocalChain"],[3,"BlockHash"],[3,"KeychainTxOutIndex"],[3,"LargestFirstCoinSelection"],[3,"OldestFirstCoinSelection"],[3,"BranchAndBoundCoinSelection"],[3,"CoinSelectionResult"],[4,"Error"],[4,"Excess"],[4,"MiniscriptPsbtError"],[4,"Error"],[3,"FullyNodedExport"],[4,"SignerId"],[6,"KeyMap"],[4,"SignerContext"],[8,"Sized"],[3,"SignerWrapper"],[4,"TapLeavesOptions"],[3,"PrivateKey"],[3,"DescriptorMultiXKey"],[3,"DescriptorXKey"],[3,"Hash"],[4,"Error"],[8,"CoinSelectionAlgorithm"],[4,"AddForeignUtxoError"],[4,"AddUtxoError"],[4,"AllowShrinkingError"],[4,"ChangeSpendPolicy"],[4,"TxOrdering"],[4,"LockTime"],[15,"i32"],[13,"Foreign"],[8,"ExtractPolicy"],[13,"PsbtTimelocks"],[13,"Complete"],[13,"Partial"],[13,"PartialComplete"],[13,"Sha256Preimage"],[13,"Hash256Preimage"],[13,"Ripemd160Preimage"],[13,"Hash160Preimage"],[13,"Thresh"],[13,"Multisig"],[13,"AbsoluteTimelock"],[13,"RelativeTimelock"],[8,"DescriptorTemplate"],[8,"GeneratableKey"],[8,"ExtScriptContext"],[8,"GeneratableDefaultOptions"],[8,"PsbtUtils"],[8,"IsDust"],[13,"UnexpectedConnectedToHash"],[13,"ConfirmationHeightCannotBeGreaterThanTip"],[13,"LoadedGenesisDoesNotMatch"],[13,"LoadedNetworkDoesNotMatch"],[13,"InsufficientFunds"],[13,"Change"],[13,"NoChange"],[13,"InsufficientFunds"],[13,"RbfSequenceCsv"],[13,"LockTime"],[13,"FeeTooLow"],[13,"FeeRateTooLow"],[8,"SignerCommon"],[8,"InputSigner"],[13,"Tap"],[13,"InvalidTxid"]]},\ +"bdk":{"doc":"bdk","t":[13,13,2,13,4,13,3,2,2,4,2,3,11,11,11,11,11,11,11,11,11,11,2,11,11,11,11,11,11,11,11,11,12,12,0,14,11,11,11,11,11,11,11,11,11,11,14,11,11,11,11,11,11,11,11,11,11,12,12,0,11,12,11,0,12,11,11,11,2,2,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,12,5,11,11,11,11,0,12,12,12,13,6,4,2,4,6,8,6,8,16,4,3,13,13,2,8,4,13,13,6,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,2,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,10,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,12,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,10,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,5,5,13,13,4,13,13,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,4,13,3,6,13,13,6,13,13,13,13,13,13,13,13,13,13,13,4,3,4,13,13,13,13,13,4,4,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,12,11,11,11,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,3,3,3,3,3,3,3,3,8,6,3,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,8,4,4,4,16,16,8,4,13,8,8,3,8,13,13,13,16,4,6,13,13,13,13,13,16,13,3,13,8,4,13,13,13,3,3,4,3,13,6,13,13,13,5,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,11,5,11,10,11,11,5,10,11,11,12,12,11,11,11,11,11,11,10,12,11,11,11,11,11,10,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,8,10,10,10,4,3,4,3,13,3,13,13,13,13,4,8,13,13,13,4,13,13,13,13,13,4,4,13,13,13,13,13,3,3,13,13,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,0,11,12,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,12,11,12,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,5,12,12,12,12,12,12,12,12,13,13,3,13,8,3,6,4,4,13,3,13,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,5,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,4,13,13,13,4,13,13,13,13,13,13,13,13,4,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,3,6,12,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,13,13,13,13,13,13,13,8,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,3,8,4,4,4,3,3,3,13,4,8,13,11,12,12,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,10,11,11,11,10,11,12,11,12,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,4,4,4,13,3,13,13,4,3,13,13,13,13,13,13,3,8,4,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12],"n":["External","Foreign","HdKeyPaths","Internal","KeychainKind","Local","LocalOutput","SignOptions","TxBuilder","Utxo","Wallet","WeightedUtxo","as_byte","as_ref","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","chain","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","confirmation_time","derivation_index","descriptor","descriptor","deserialize","deserialize","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fragment","from","from","from","from","hash","hash","into","into","into","into","is_spent","keychain","keys","outpoint","outpoint","partial_cmp","psbt","satisfaction_weight","sequence","serialize","serialize","signer","template","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","txout","txout","type_id","type_id","type_id","type_id","utxo","version","vzip","vzip","vzip","vzip","wallet","outpoint","psbt_input","sequence","Bare","DerivedDescriptor","Descriptor","DescriptorError","DescriptorPublicKey","ExtendedDescriptor","ExtractPolicy","HdKeyPaths","IntoWalletDescriptor","Key","Legacy","Miniscript","MultiXPub","Pkh","Policy","ScriptContext","Segwitv0","Sh","Single","TapKeyOrigins","Tr","Wpkh","Wsh","XPub","address","as_enum","as_enum","as_inner","as_node","at_derivation_index","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","branches","build_template","build_template_mall","calc_checksum","check_global_consensus_validity","check_global_consensus_validity","check_global_consensus_validity","check_global_policy_validity","check_global_policy_validity","check_global_validity","check_local_consensus_validity","check_local_consensus_validity","check_local_consensus_validity","check_local_policy_validity","check_local_policy_validity","check_local_policy_validity","check_local_validity","check_pk","check_pk","check_pk","check_terminal_non_malleable","check_terminal_non_malleable","check_terminal_non_malleable","check_witness","check_witness","check_witness","checksum","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","contains_raw_pkh","derive","derived_descriptor","derived_descriptor","desc_type","deserialize","deserialize","dust_value","encode","eq","eq","eq","eq","error","explicit_script","ext","ext_check","extract_policy","extract_policy","extract_policy","find_derivation_index_for_spk","fmt","fmt","fmt","fmt","fmt","fmt","for_each_key","for_each_key","from","from","from","from","from","from","from","from","from","from","from_ast","from_components_unchecked","from_str","from_str","from_str_ext","from_str_insane","from_tree","from_tree","get_nth_child","get_nth_pk","get_satisfaction","get_satisfaction_mall","has_mixed_timelocks","has_repeated_keys","has_wildcard","hash","hash","hash","hash","into","into","into","into","into_inner","into_single_descriptors","into_wallet_descriptor","into_wallet_descriptor","is_deriveable","is_multipath","is_non_malleable","iter","iter_pk","lift","lift","lift_check","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_weight","max_satisfaction_witness_elements","max_weight_to_satisfy","name_str","name_str","name_str","new_bare","new_pk","new_pkh","new_sh","new_sh_sortedmulti","new_sh_with_wpkh","new_sh_with_wsh","new_sh_wpkh","new_sh_wsh","new_sh_wsh_sortedmulti","new_tr","new_wpkh","new_wsh","new_wsh_sortedmulti","node","other_top_level_checks","parse","parse_descriptor","parse_insane","parse_with_ext","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pk_len","pk_len","pk_len","plan","plan_mall","policy","requires_sig","sanity_check","sanity_check","satisfy","satisfy","satisfy_malleable","script_code","script_pubkey","script_size","serialize","serialize","sig_type","sig_type","sig_type","substitute_raw_pkh","template","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string_with_secret","top_level_checks","top_level_type_check","translate_pk","translate_pk","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","ty","type_id","type_id","type_id","type_id","unsigned_script_sig","vzip","vzip","vzip","vzip","within_resource_limits","calc_checksum","calc_checksum_bytes","Base58","Bip32","Error","HardenedDerivationXpub","Hex","InvalidDescriptorCharacter","InvalidDescriptorChecksum","InvalidHdKeyPath","Key","Miniscript","MultiPath","Pk","Policy","borrow","borrow_mut","fmt","fmt","from","from","from","from","from","from","from","from","into","provide","to_string","try_from","try_into","type_id","vzip","AbsoluteTimelock","AddOnLeaf","AddOnPartialComplete","BuildSatisfaction","Complete","Condition","ConditionMap","EcdsaSignature","Fingerprint","FoldedConditionMap","Hash160Preimage","Hash256Preimage","IncompatibleConditions","IndexOutOfRange","MixedTimelockUnits","Multisig","None","None","NotEnoughItemsSelected","Partial","PartialComplete","PkOrF","Policy","PolicyError","Psbt","PsbtTimelocks","Pubkey","RelativeTimelock","Ripemd160Preimage","Satisfaction","SatisfiableItem","SchnorrSignature","Sha256Preimage","Thresh","XOnlyPubkey","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","contribution","csv","default","eq","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","get_condition","hash","hash","id","id","into","into","into","into","into","into","into","is_leaf","is_leaf","is_null","item","partial_cmp","provide","requires_path","satisfaction","serialize","serialize","serialize","serialize","serialize","timelock","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","current_height","input_max_height","psbt","condition","conditions","conditions","items","items","m","m","n","n","sorted","sorted","hash","hash","hash","hash","items","keys","threshold","threshold","value","value","Bip44","Bip44Public","Bip49","Bip49Public","Bip84","Bip84Public","Bip86","Bip86Public","DescriptorTemplate","DescriptorTemplateOut","P2Pkh","P2TR","P2Wpkh","P2Wpkh_P2Sh","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","build","build","build","build","build","build","build","build","build","build","build","build","from","from","from","from","from","from","from","from","from","from","from","from","into","into","into","into","into","into","into","into","into","into","into","into","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","into_wallet_descriptor","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","Bip32","DerivableKey","DescriptorKey","DescriptorPublicKey","DescriptorSecretKey","Entropy","Error","ExtScriptContext","ExtendedKey","FullKey","GeneratableDefaultOptions","GeneratableKey","GeneratedKey","IntoDescriptorKey","InvalidChecksum","InvalidNetwork","InvalidScriptContext","Key","KeyError","KeyMap","Legacy","Message","Miniscript","MultiXPrv","MultiXPub","Options","Private","PrivateKeyGenerateOptions","Public","ScriptContext","ScriptContextEnum","Segwitv0","Single","Single","SinglePriv","SinglePub","SinglePubKey","SortedMultiVec","Tap","ValidNetworks","XOnly","XPrv","XPub","any_network","as_enum","at_derivation_index","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build_template","check_global_consensus_validity","check_global_policy_validity","check_global_validity","check_local_consensus_validity","check_local_policy_validity","check_local_validity","check_pk","check_terminal_non_malleable","check_witness","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","compressed","default","deref","derive","deserialize","encode","eq","eq","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","for_each_key","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_public","from_secret","from_str","from_str","from_tree","full_derivation_path","full_derivation_paths","generate","generate_default","generate_with_entropy","generate_with_entropy_default","has_secret","has_wildcard","hash","hash","hash","hash","into","into","into","into","into","into","into","into","into","into","into","into","into_assets","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_descriptor_key","into_extended_key","into_extended_key","into_extended_key","into_key","into_single_keys","into_single_keys","into_xprv","into_xpub","is_deriveable","is_legacy","is_legacy","is_multipath","is_multipath","is_segwit_v0","is_segwit_v0","is_taproot","is_taproot","is_uncompressed","is_x_only_key","k","key","key","lift","mainnet_network","master_fingerprint","max_satisfaction_size","max_satisfaction_size","max_satisfaction_witness_elements","merge_networks","name_str","new","num_der_paths","origin","origin","other_top_level_checks","override_valid_networks","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pk_len","pks","provide","sanity_check","satisfy","script_size","serialize","sig_type","sorted_node","test_networks","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_public","to_string","to_string","to_string","to_string","top_level_checks","top_level_type_check","translate_pk","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","PsbtUtils","fee_amount","fee_rate","get_utxo_for","AddressIndex","AddressInfo","ApplyBlockError","Balance","CannotConnect","ChangeSet","ConfirmationHeightCannotBeGreaterThanTip","Descriptor","Descriptor","Descriptor","InsertTxError","IsDust","LastUnused","Load","Load","LoadError","LoadedGenesisDoesNotMatch","LoadedNetworkDoesNotMatch","MissingGenesis","MissingNetwork","New","NewError","NewOrLoadError","NonEmptyDatabase","NotInitialized","NotInitialized","Peek","UnexpectedConnectedToHash","Update","Wallet","Write","Write","add","add_signer","address","all_unbounded_spk_iters","append","apply_block","apply_block_connected_to","apply_unconfirmed_txs","apply_update","as_ref","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build_fee_bump","build_tx","calculate_fee","calculate_fee_rate","cancel_tx","chain","chain","checkpoints","clone","clone","clone","clone_into","clone_into","clone_into","coin_selection","commit","confirmed","default","default","default","deref","derivation_index","derivation_of_spk","descriptor_checksum","deserialize","deserialize","eq","eq","eq","error","export","finalize_psbt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","get_address","get_balance","get_descriptor_for_keychain","get_internal_address","get_psbt_input","get_signers","get_tx","get_utxo","graph","immature","index","indexed_tx_graph","insert_checkpoint","insert_tx","insert_txout","into","into","into","into","into","into","into","into","into","into","into","is_dust","is_empty","is_mine","keychain","keychains","last_active_indices","latest_checkpoint","list_output","list_unspent","load","local_chain","network","network","new","new_no_persist","new_no_persist_with_genesis_hash","new_or_load","new_or_load_with_genesis_hash","new_with_genesis_hash","next_derivation_index","policies","provide","provide","provide","provide","provide","public_descriptor","secp_ctx","sent_and_received","serialize","serialize","sign","signer","spk_index","staged","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","to_string","total","transactions","trusted_pending","trusted_spendable","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_get_address","try_get_internal_address","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","tx_builder","tx_graph","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unbounded_spk_iter","untrusted_pending","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","wallet_name_from_descriptor","connected_to_hash","expected_hash","tip_height","tx_height","expected","expected","got","got","BnBNoExactMatch","BnBTotalTriesExceeded","BranchAndBoundCoinSelection","Change","CoinSelectionAlgorithm","CoinSelectionResult","DefaultCoinSelectionAlgorithm","Error","Excess","InsufficientFunds","LargestFirstCoinSelection","NoChange","OldestFirstCoinSelection","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","coin_select","coin_select","coin_select","coin_select","decide_change","default","default","default","excess","fee_amount","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","into","into","into","into","into","into","local_selected_amount","new","provide","selected","selected_amount","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","available","needed","amount","change_fee","dust_threshold","fee","remaining_amount","BuildFeeBumpError","ChangePolicyDescriptor","CoinSelection","Conversion","CreateTxError","Descriptor","FeeRateTooLow","FeeRateUnavailable","FeeTooLow","InsufficientFunds","IrreplaceableTransaction","LockTime","MiniscriptPsbt","MiniscriptPsbtError","MissingKeyOrigin","MissingNonWitnessUtxo","NoRecipients","NoUtxosSelected","OutputBelowDustLimit","OutputUpdate","Persist","Policy","Psbt","RbfSequence","RbfSequenceCsv","SpendingPolicyRequired","TransactionConfirmed","TransactionNotFound","UnknownUtxo","UnknownUtxo","UtxoUpdate","Version0","Version1Csv","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","into","into","into","provide","provide","provide","to_owned","to_string","to_string","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","available","csv","needed","rbf","requested","required","required","required","FullyNodedExport","WalletExport","blockheight","borrow","borrow_mut","change_descriptor","descriptor","deserialize","export_wallet","fmt","from","from_str","into","label","serialize","to_string","try_from","try_into","type_id","vzip","All","Dummy","Exclude","External","Fingerprint","Include","InputIndexOutOfRange","InputSigner","InvalidKey","InvalidNonWitnessUtxo","InvalidSighash","Legacy","MiniscriptPsbt","MissingHdKeypath","MissingKey","MissingNonWitnessUtxo","MissingWitnessScript","MissingWitnessUtxo","NonStandardSighash","None","PkHash","Segwitv0","SighashError","SignOptions","SignerCommon","SignerContext","SignerError","SignerId","SignerOrdering","SignerWrapper","SignersContainer","Tap","TapLeavesOptions","TransactionSigner","UserCanceled","add_external","allow_all_sighashes","allow_grinding","as_key_map","assume_height","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","default","default","default","default","deref","descriptor_secret_key","descriptor_secret_key","descriptor_secret_key","descriptor_secret_key","eq","eq","eq","eq","find","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","hash","id","id","id","id","ids","into","into","into","into","into","into","into","into","new","new","partial_cmp","partial_cmp","provide","remove","remove_partial_sigs","remove_taproot_extras","sign_input","sign_input","sign_input","sign_input","sign_transaction","sign_transaction","sign_with_tap_internal_key","signers","tap_leaves_options","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","trust_witness_utxo","try_finalize","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","is_internal_key","AddForeignUtxoError","AddUtxoError","AllowShrinkingError","Bip69Lexicographic","BumpFee","ChangeAllowed","ChangeForbidden","ChangeSpendPolicy","CreateTx","InvalidOutpoint","InvalidTxid","MissingScriptPubKey","MissingUtxo","OnlyChange","Shuffle","TxBuilder","TxBuilderContext","TxOrdering","UnknownUtxo","Untouched","add_data","add_foreign_utxo","add_foreign_utxo_with_sequence","add_global_xpubs","add_recipient","add_unspendable","add_utxo","add_utxos","allow_dust","allow_shrinking","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","change_policy","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","coin_selection","current_height","default","default","default","default","do_not_spend_change","drain_to","drain_wallet","enable_rbf","enable_rbf_with_sequence","eq","eq","fee_absolute","fee_rate","finish","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","hash","hash","include_output_redeem_witness_script","into","into","into","into","into","into","into","into","manually_selected_only","nlocktime","only_spend_change","only_witness_utxo","ordering","partial_cmp","partial_cmp","policy_path","provide","provide","provide","set_recipients","sighash","sort_tx","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unspendable","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","foreign_utxo","input_txid"],"q":["bdk","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::Utxo","","","bdk::descriptor","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::checksum","","bdk::descriptor::error","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::policy","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::policy::BuildSatisfaction","","","bdk::descriptor::policy::Satisfaction","","","","","","","","","","","bdk::descriptor::policy::SatisfiableItem","","","","","","","","","","bdk::descriptor::template","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::keys","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::psbt","","","","bdk::wallet","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::ApplyBlockError","","bdk::wallet::InsertTxError","","bdk::wallet::NewOrLoadError","","","","bdk::wallet::coin_selection","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::coin_selection::Error","","bdk::wallet::coin_selection::Excess","","","","","bdk::wallet::error","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::error::CreateTxError","","","","","","","","bdk::wallet::export","","","","","","","","","","","","","","","","","","","","bdk::wallet::signer","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::signer::SignerContext","bdk::wallet::tx_builder","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::tx_builder::AddForeignUtxoError",""],"d":["External keychain, used for deriving recipient addresses.","A UTXO owned by another wallet.","","Internal keychain, used for deriving change addresses.","Types of keychains","A UTXO owned by the local wallet.","An unspent output owned by a Wallet.","","","An unspent transaction output (UTXO).","","A Utxo with its satisfaction_weight.","Return KeychainKind as a byte","","","","","","","","","","","","","","","","","","","","The confirmation time for transaction containing this utxo","The derivation index for the script pubkey in the wallet","Descriptors","Macro to write full descriptors with code","","","","","","","","","","","Macro to write descriptor fragments with code","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Whether this UTXO is spent or not","Type of keychain","Key formats","Get the location of the UTXO","Reference to a transaction output","","Additional functions on the rust-bitcoin Psbt structure.","The weight of the witness data and scriptSig expressed in …","Get the sequence number if an explicit sequence number has …","","","","","","","","","","","","","","","","","Get the TxOut of the UTXO","Transaction output","","","","","The UTXO","Get the version of BDK at runtime","","","","","Wallet","The location of the output.","The information about the input we require to add it to a …","The nSequence value to set for this input.","A raw scriptpubkey (including pay-to-pubkey) under Legacy …","Alias for a Descriptor that contains extended derived keys","Script descriptor","","The descriptor pubkey, either a single pubkey or an xpub.","Alias for a Descriptor that can contain extended keys …","Trait implemented on Descriptors to add a method to …","Alias for the type of maps that represent derivation paths …","Trait for types which can be converted into an …","The consensus key associated with the type. Must be a …","Legacy ScriptContext To be used as P2SH scripts For …","The top-level miniscript abstract syntax tree (AST).","Multiple extended public keys.","Pay-to-PubKey-Hash","","The ScriptContext for Miniscript. Additional type …","Segwitv0 ScriptContext","Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)","Single public key.","Alias for the type of maps that represent taproot key …","Pay-to-Taproot","Pay-to-Witness-PubKey-Hash","Pay-to-Witness-ScriptHash with Segwitv0 context","Extended public key (xpub).","Computes the Bitcoin address of the descriptor, if one …","","","Get a reference to the inner AstElem representing the root …","","Replaces all wildcards (i.e. /*) in the descriptor with a …","","","","","","","","","Enumerates all child nodes of the current AST node (self) …","Attempt to produce a non-malleable witness template given …","Attempt to produce a malleable witness template given the …","","Depending on script Context, some of the Terminals might …","","","Depending on script Context, some of the script resource …","","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","","","Policy rules at the Miniscript satisfaction time. It is …","","","Check the consensus + policy(if not disabled) rules …","Each context has slightly different rules on what Pks are …","","","Depending on ScriptContext, fragments can be malleable. …","","","Check whether the given satisfaction is valid under the …","","","Descriptor checksum","","","","","","","","","","","","","Whether the given miniscript contains a raw pkh fragment","Deprecated name for Self::at_derivation_index.","Convert all the public keys in the descriptor to …","Convert all the public keys in the descriptor to …","Get the DescriptorType of Descriptor","","","","Encode as a Bitcoin script","","","","","Descriptor errors","Computes the the underlying script before any hashing is …","Additional information helpful for extra analysis.","Check whether the miniscript follows the given Extra …","Extract the spending policy","","","Utility method for deriving the descriptor at each index …","","","","","","","","","","","Returns the argument unchanged.","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Add type information(Type and Extdata) to Miniscript based …","Create a new Miniscript from a Terminal node and a Type …","","Parse a Miniscript from string and perform sanity checks …","Attempt to parse an Miniscripts that don’t follow the …","Attempt to parse an insane(scripts don’t clear sanity …","Parse an expression tree into a descriptor.","Parse an expression tree into a Miniscript. As a general …","Returns child node with given index, if any","Returns Option::Some with cloned n’th public key from …","Returns satisfying non-malleable witness and scriptSig to …","Returns a possilbly mallable satisfying non-malleable …","Whether the miniscript contains a combination of timelocks","Whether the miniscript has repeated Pk or Pkh","Whether or not the descriptor has any wildcards i.e. /*.","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Extracts the AstElem representing the root of the …","Get as many descriptors as different paths in this …","Convert to wallet descriptor","","Whether or not the descriptor has any wildcards","Whether this descriptor contains a key that has multiple …","Whether the miniscript is malleable","Creates a new Iter iterator that will iterate over all …","Creates a new PkIter iterator that will iterate over all …","","","Lifting corresponds to conversion of a miniscript into a …","Depending on script context, the size of a satifaction …","","","Maximum size, in bytes, of a satisfying witness. For …","Computes an upper bound on the weight of a satisfying …","Maximum number of witness elements used to satisfy the …","Computes an upper bound on the difference between a …","Local helper function to display error messages with …","","","Create a new bare descriptor from witness script Errors …","Create a new pk descriptor","Create a new PkH descriptor","Create a new sh for a given redeem script Errors when …","Create a new sh sortedmulti descriptor with threshold k …","Create a new sh wrapper for the given wpkh descriptor","Create a new sh wrapper for the given wsh descriptor","Create a new sh wrapped wpkh from Pk. Errors when …","Create a new sh wrapped wsh descriptor with witness script …","Create a new sh wrapped wsh sortedmulti descriptor from …","Create new tr descriptor Errors when miniscript exceeds …","Create a new Wpkh descriptor Will return Err if …","Create a new wsh descriptor from witness script Errors …","Create a new wsh sorted multi descriptor Errors when …","A node in the AST.","Other top level checks that are context specific","Attempt to parse a Script into Miniscript representation.","Parse a descriptor that may contain secret keys","Attempt to parse an insane(scripts don’t clear sanity …","Attempt to parse an miniscript with extra features that …","","","","","Get the len of public key when serialized based on context …","","","Returns a plan if the provided assets are sufficient to …","Returns a plan if the provided assets are sufficient to …","Descriptor policy","Whether all spend paths of miniscript require a signature","Checks whether the descriptor is safe.","Check whether the underlying Miniscript is safe under the …","Attempts to produce a non-malleable satisfying witness and …","Attempt to produce non-malleable satisfying witness for the","Attempt to produce a malleable satisfying witness for the …","Computes the scriptCode of a transaction output.","Computes the scriptpubkey of the descriptor.","Size, in bytes of the script-pubkey. If this Miniscript is …","","","The type of signature required for satisfaction","","","Substitutes raw public keys hashes with the public keys as …","Descriptor templates","","","","","","","Serialize a descriptor to string with its secret keys","Check top level consensus rules.","Check whether the top-level is type B","Converts a descriptor using abstract keys to one using …","Translates a struct from one generic to another where the …","","","","","","","","","The correctness and malleability type information for the …","","","","","Computes the scriptSig that will be in place for an …","","","","","Whether the miniscript can exceed the resource …","Compute the checksum of a descriptor, excludes any …","Compute the checksum bytes of a descriptor, excludes any …","Error during base58 decoding","BIP32 error","Errors related to the parsing and usage of descriptors","The descriptor contains hardened derivation steps on …","Hex decoding error","Invalid byte found in the descriptor checksum","The provided descriptor doesn’t match its checksum","Invalid HD Key path, such as having a wildcard but a …","Error thrown while working with keys","Miniscript error","The descriptor contains multipath keys","Key-related error","Error while extracting and manipulating policies","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self).","","","","","","","Absolute timeclock timestamp","Can not add to an item that is Satisfaction::None or …","Can not add to an item that is …","Options to build the satisfaction field in the policy","Can satisfy the policy item","An extra condition that must be satisfied but that is out …","Type for a map of sets of Condition items keyed by each set…","ECDSA Signature for a raw public key","An extended key fingerprint","Type for a map of folded sets of Condition items keyed by …","SHA256 then RIPEMD160 preimage hash","Double SHA256 preimage hash","Incompatible conditions (not currently used)","Index out of range for an item to satisfy a …","Can not merge CSV or timelock values unless both are less …","Multi-signature public keys with threshold count","Cannot satisfy or contribute to the policy item","Don’t generate satisfaction field","Not enough items are selected to satisfy a …","Only a partial satisfaction of some kind of threshold …","Can reach the threshold of some kind of threshold policy","A unique identifier for a key","Descriptor spending policy","Errors that can happen while extracting and manipulating …","Analyze the given PSBT to check for existing signatures","Like Psbt variant and also check for expired timelocks","A legacy public key","Relative timelock locktime","RIPEMD160 preimage hash","Represent if and how much a policy item is satisfied by …","An item that needs to be satisfied","Schnorr Signature for a raw public key","SHA256 preimage hash","Threshold items with threshold count","A x-only public key","","","","","","","","","","","","","","","","","","","","","","","","","","","How the wallet’s descriptor can satisfy this policy node","Optional CheckSequenceVerify condition","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Return the conditions that are set by the spending policy …","","","Returns a unique id for the SatisfiableItem","Identifier for this policy node","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Returns whether the SatisfiableItem is a leaf item","Returns whether the Satisfaction is a leaf item","Returns true if there are no extra conditions to verify","Type of this policy node","","","Return whether or not a specific path in the policy tree …","How much a given PSBT already satisfies this policy node …","","","","","","Optional timelock condition","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Current blockchain height","The highest confirmation height between the inputs CSV …","Given PSBT","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","The items that can be satisfied by the descriptor or are …","The items that can be satisfied by the descriptor","Threshold","Threshold","Total number of items","Total number of items","Whether the items are sorted in lexicographic order (used …","Whether the items are sorted in lexicographic order (used …","The digest value","The digest value","The digest value","The digest value","The policy items","The raw public key or extended key fingerprint","The required threshold count","The required threshold count","The timelock value","The timelock value","BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)","BIP44 public template. Expands to pkh(key/{0,1}/*)","BIP49 template. Expands to …","BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))","BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)","BIP84 public template. Expands to wpkh(key/{0,1}/*)","BIP86 template. Expands to tr(key/86'/{0,1}'/0'/{0,1}/*)","BIP86 public template. Expands to tr(key/{0,1}/*)","Trait for descriptor templates that can be built into a …","Type alias for the return type of DescriptorTemplate, …","P2PKH template. Expands to a descriptor pkh(key)","P2TR template. Expands to a descriptor tr(key)","P2WPKH template. Expands to a descriptor wpkh(key)","P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))","","","","","","","","","","","","","","","","","","","","","","","","","Build the complete descriptor","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","BIP32 error","Trait for keys that can be derived.","Container for public or secret keys","The descriptor pubkey, either a single pubkey or an xpub.","The descriptor secret key, either a single private key or …","Type specifying the amount of entropy required e.g. [u8;32]","Returned error in case of failure","Trait that adds extra useful methods to ScriptContexts","Enum for extended keys that can be either xprv or xpub","A bitcoin public key (compressed or uncompressed).","Trait that allows generating a key with the default options","Trait for keys that can be generated","Output of a GeneratableKey key generation","Trait for objects that can be turned into a public or …","The key has an invalid checksum","The key is not valid for the given network","The key cannot exist in the given script context","The consensus key associated with the type. Must be a …","Errors thrown while working with keys","Alias type for a map of public key to secret key","Legacy scripts","Custom error message","Miniscript error","Multiple extended private keys.","Multiple extended public keys.","Extra options required by the generate_with_entropy","A private extended key, aka an xprv","Options for generating a PrivateKey","A public extended key, aka an xpub","The ScriptContext for Miniscript. Additional type …","Enum representation of the known valid ScriptContexts","Segwitv0 scripts","Single public key.","Single private key.","A descriptor bitcoin::PrivateKey with optional origin …","A descriptor SinglePubKey with optional origin information.","Single public key without any origin or range information.","Contents of a “sortedmulti” descriptor","Taproot scripts","Set of valid networks for a key","An xonly public key.","Extended private key (xpriv).","Extended public key (xpub).","Create a set containing mainnet, testnet, signet, and …","Returns the ScriptContext as a ScriptContextEnum","Replaces any wildcard (i.e. /*) in the key with a …","","","","","","","","","","","","","","","","","","","","","","","","","Attempt to produce a witness template given the assets …","Depending on script Context, some of the Terminals might …","Depending on script Context, some of the script resource …","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","Policy rules at the Miniscript satisfaction time. It is …","Check the consensus + policy(if not disabled) rules …","Each context has slightly different rules on what Pks are …","Depending on ScriptContext, fragments can be malleable. …","Check whether the given satisfaction is valid under the …","","","","","","","","","","","","","","","","","","","","","","","Whether the generated key should be “compressed” or not","","","Deprecated name for Self::at_derivation_index.","","Encode as a Bitcoin script","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create an instance given a public key and a set of valid …","Create an instance given a secret key and a set of valid …","","","Parse an expression tree into a SortedMultiVec","Full path, from the master key","Returns a vector containing the full derivation paths from …","Generate a key given the options with a random entropy","Generate a key with the default options and a random …","Generate a key given the extra options and the entropy","Generate a key with the default options and a given entropy","Return whether or not the key contains the private data","Whether or not the key has a wildcard","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","Turn the key into a DescriptorKey within the requested …","Consume self and turn it into a DescriptorKey by adding …","","","","","","Consume self and turn it into an ExtendedKey","","","Consumes self and returns the key","Get as many keys as derivation paths in this key.","Get as many keys as derivation paths in this key.","Transform the ExtendedKey into an Xpriv for the given …","Transform the ExtendedKey into an Xpub for the given …","Whether or not the key has a wildcard","Returns whether the script context is Legacy","Returns whether the script context is …","Whether or not this key has multiple derivation paths.","Whether or not this key has multiple derivation paths.","Returns whether the script context is Segwitv0","Returns whether the script context is …","Returns whether the script context is Tap, aka Taproot or …","Returns whether the script context is …","","","signatures required","The public key.","The private key.","","Create a set only containing mainnet","The fingerprint of the master key associated with this …","Depending on script context, the size of a satifaction …","Maximum size, in bytes, of a satisfying witness. In …","Maximum number of witness elements used to satisfy the …","Compute the intersection of two sets","Local helper function to display error messages with …","Create a new instance of SortedMultiVec given a list of …","","Origin information (fingerprint and derivation path).","Origin information (fingerprint and derivation path).","Other top level checks that are context specific","Override the computed set of valid networks","","","","","Get the len of public key when serialized based on context …","public keys inside sorted Multi","","utility function to sanity a sorted multi vec","Attempt to produce a satisfying witness for the witness …","Size, in bytes of the script-pubkey. If this Miniscript is …","","The type of signature required for satisfaction","Create Terminal::Multi containing sorted pubkeys","Create a set containing testnet and regtest","","","","","","","","","","Returns the public version of this key.","","","","","Check top level consensus rules.","Check whether the top-level is type B","This will panic if fpk returns an uncompressed key when …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Trait to add functions to extract utxos and calculate fees.","The total transaction fee amount, sum of input amounts …","The transaction’s fee rate. This value will only be …","Get the TxOut for the specified input index, if it doesn’…","The address index selection strategy to use to derived an …","A derived address and the index it was found at. For …","An error that may occur when applying a block to Wallet.","Balance, differentiated into various categories.","Occurs when the update chain cannot connect with original …","The changes made to a wallet by applying an Update.","The error variant that occurs when the caller attempts to …","There was problem with the passed-in descriptor(s).","There was a problem with the passed-in descriptor(s).","There is a problem with the passed-in descriptor.","An error that may occur when inserting a transaction into …","Trait to check if a value is below the dust limit. We are …","Return the address for the current descriptor index if it …","Loading data from the persistence backend failed.","Loading from the persistence backend failed.","The error type when loading a Wallet from persistence.","The loaded genesis hash does not match what was provided.","The loaded network type does not match what was provided.","Data loaded from persistence is missing genesis hash.","Data loaded from persistence is missing network type.","Return a new address after incrementing the current …","The error type when constructing a fresh Wallet.","Error type for when we try load a Wallet from persistence …","Database already has data.","Wallet not initialized, persistence backend is empty.","Wallet is not initialized, persistence backend is empty.","Return the address for a specific descriptor index. Does …","Occurs when the connected_to hash does not match the hash …","An update to Wallet.","A Bitcoin wallet","We were unable to write the wallet’s data to the …","Writing to the persistence backend failed.","","Add an external signer","Address","Get unbounded script pubkey iterators for both Internal …","","Introduces a block of height to the wallet, and tries to …","Applies relevant transactions from block of height to the …","Apply relevant unconfirmed transactions to the wallet.","Applies an update to the wallet and stages the changes …","","","","","","","","","","","","","","","","","","","","","","","","Bump the fee of a transaction previously created with this …","Start building a transaction.","Calculates the fee of a given transaction. Returns 0 if tx …","Calculate the FeeRate for a given transaction.","Informs the wallet that you no longer intend to broadcast …","Update for the wallet’s internal LocalChain.","Changes to the LocalChain.","Get all the checkpoints the wallet is currently storing …","","","","","","","Coin selection","Commits all currently staged changed to the persistence …","Confirmed and immediately spendable balance","","","","","The derivation index of this wallet. It will return None …","Finds how the wallet derived the script pubkey spk.","Return the checksum of the public descriptor associated to …","","","","","","Errors that can be thrown by the Wallet","Wallet export","Finalize a PSBT, i.e., for each input determine if …","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Infallibly return a derived address using the external …","Return the balance, separated into available, …","Returns the descriptor used to create addresses for a …","Infallibly return a derived address using the internal …","get the corresponding PSBT Input for a LocalUtxo","Get the signers","Get a single transaction from the wallet as a CanonicalTx …","Returns the utxo owned by this wallet corresponding to …","Update for the wallet’s internal TxGraph.","All coinbase outputs not yet matured","Child index of this address","Changes to IndexedTxGraph.","Add a new checkpoint to the wallet’s internal view of …","Add a transaction to the wallet’s internal view of the …","Inserts a TxOut at OutPoint into the wallet’s …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Check whether or not a value is below dust limit","","Return whether or not a script is part of this wallet …","Type of keychain","Iterator over all keychains in this wallet","Contains the last active derivation indices per keychain (K…","Returns the latest checkpoint.","List all relevant outputs (includes both spent and …","Return the list of unspent outputs of this wallet","Load Wallet from the given persistence backend.","Get a reference to the inner LocalChain.","Get the Bitcoin network the wallet is using.","Stores the network type of the wallet.","Initialize an empty Wallet.","Creates a wallet that does not persist data.","Creates a wallet that does not persist data, with a custom …","Either loads Wallet from persistence, or initializes it if …","Either loads Wallet from persistence, or initializes it if …","Initialize an empty Wallet with a custom genesis hash.","The index of the next address that you would get if you …","Return the spending policies for the wallet’s descriptor","","","","","","Return the “public” version of the wallet’s …","Return the secp256k1 context used for all signing …","Compute the tx’s sent and received amounts (in satoshis).","","","Sign a transaction with all the wallet’s signers, in the …","Generalized signers","Get a reference to the inner KeychainTxOutIndex.","Returns the changes that will be committed with the next …","","","","","","","","","","","Get the whole balance visible to the wallet.","Iterate over the transactions in the wallet.","Unconfirmed UTXOs generated by a wallet tx","Get sum of trusted_pending and confirmed coins.","","","","","","","","","","","","Return a derived address using the external descriptor, …","Return a derived address using the internal (change) …","","","","","","","","","","","","Transaction builder","Get a reference to the inner TxGraph.","","","","","","","","","","","","Get an unbounded script pubkey iterator for the given …","Unconfirmed UTXOs received from an external wallet","","","","","","","","","","","","Deterministically generate a unique name given the …","Block hash of connected_to.","Expected block hash of connected_to, as derived from block.","The internal chain’s tip height.","The introduced transaction’s confirmation height.","The expected genesis block hash.","The expected network type.","The block hash loaded from persistence.","The network type loaded from persistence.","Branch and bound coin selection tries to avoid needing a …","Branch and bound coin selection possible attempts with …","Branch and bound coin selection","It’s possible to create spendable output from excess …","Trait for generalized coin selection algorithms","Result of a successful coin selection","Default coin selection algorithm used by TxBuilder if not …","Errors that can be thrown by the coin_selection module","Remaining amount after performing coin selection","Wallet’s UTXO set is not enough to cover recipient’s …","Simple and dumb coin selection","It’s not possible to create spendable output from excess …","OldestFirstCoinSelection always picks the utxo with the …","","","","","","","","","","","","","","","","","","","Perform the coin selection","","","","Decide if change can be created","","","","Remaining amount after deducing fees and outgoing outputs","Total fee amount for the selected utxos in satoshis","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","The total value of the inputs selected from the local …","Create new instance with target size for change output","","List of outputs selected for use as inputs","The total value of the inputs selected.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Sats available for spending","Sats needed for some transaction","Effective amount available to create change after …","The calculated fee for the drain TxOut with the selected …","Threshold to consider amount as dust for this particular …","The deducted change output fee","Exceeding amount of current selection over outgoing value …","Error returned from Wallet::build_fee_bump","The change_policy was set but the wallet does not have a …","There was an error with coin selection","Descriptor key conversion error","Error returned from TxBuilder::finish","There was a problem with the descriptors passed in","When bumping a tx the fee rate requested is lower than …","Node doesn’t have data to estimate a fee rate","When bumping a tx the absolute fee requested is lower than …","Wallet’s UTXO set is not enough to cover recipient’s …","Trying to replace a tx that has a sequence >= 0xFFFFFFFE","Requested LockTime is less than is required to spend from …","Miniscript PSBT error","Errors returned by miniscript when updating inconsistent …","In order to use the TxBuilder::add_global_xpubs option …","Missing non_witness_utxo on foreign utxo for given OutPoint","Cannot build a tx without recipients","manually_selected_only option is selected but no utxo has …","Output created is under the dust limit, 546 satoshis","Return error type for …","We were unable to write wallet data to the persistence …","There was a problem while extracting and manipulating …","Partially signed bitcoin transaction error","Cannot enable RBF with a Sequence >= 0xFFFFFFFE","Cannot enable RBF with Sequence given a required OP_CSV","Spending policy is not compatible with this KeychainKind","Happens when trying to bump a transaction that is already …","Thrown when a tx is not found in the internal database","Happens when trying to spend an UTXO that is not in the …","Happens when trying to spend an UTXO that is not in the …","Return error type for PsbtExt::update_input_with_descriptor","Requested invalid transaction version ‘0’","Requested transaction version 1, but at least 2 is needed …","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","Sats available for spending","Required OP_CSV Sequence","Sats needed for some transaction","Given RBF Sequence","Requested LockTime","Required LockTime","Required fee absolute value (satoshi)","Required fee rate","Structure that contains the export of a wallet","Alias for FullyNodedExport","Earliest block to rescan when looking for the wallet’s …","","","Return the internal descriptor, if present","Return the external descriptor","","Export a wallet","","Returns the argument unchanged.","","Calls U::from(self).","Arbitrary label for the wallet","","","","","","","The signer will sign all the leaves it has a key for.","Dummy identifier","The signer won’t sign the specified leaves.","To be used only by external libraries implementing …","The fingerprint of a BIP32 extended key","The signer won’t sign leaves other than the ones …","Input index is out of range","PSBT Input signer","The private key in use has the right fingerprint but …","The non_witness_utxo specified is invalid","Invalid SIGHASH for the signing context in use","Legacy context","Miniscript PSBT error","The fingerprint and derivation path are missing from the …","The private key is missing for the required public key","The non_witness_utxo field of the transaction is required …","The witness_script field of the transaction is required to …","The witness_utxo field of the transaction is required to …","The psbt contains a non-SIGHASH_ALL sighash in one of its …","The signer won’t sign any leaf.","Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA …","Segwit v0 context (BIP 143)","Error while computing the hash to sign","Options for a software signer","Common signer methods","Signing context","Signing error","Identifier of a signer in the SignersContainers. Used as a …","Defines the order in which signers are called","Wrapper to pair a signer with its context","Container for multiple signers","Taproot context (BIP 340)","Customize which taproot script-path leaves the signer …","PSBT signer","The user canceled the operation","Adds an external signer to the container for the specified …","Whether the signer should use the sighash_type set in the …","Whether we should grind ECDSA signature to ensure signing …","Create a map of public keys to secret keys","Whether the wallet should assume a specific height has …","","","","","","","","","","","","","","","","","Build a new signer container from a KeyMap","","","","","","","","","","","","","","","","","","","","","","Return the secret key for the signer","","","","","","","","Finds the signer with lowest ordering for a given id in …","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Return the SignerId for this signer","","","","Returns the list of identifiers of all the signers in the …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Create a wrapped signer from a signer and a context","Default constructor","","","","Removes a signer from the container and returns it","Whether to remove partial signatures from the PSBT inputs …","Whether to remove taproot specific fields from the PSBT on …","Sign a single psbt input","","","","Sign all the inputs of the psbt","","Whether we should try to sign a taproot transaction with …","Returns the list of signers in the container, sorted by …","Specifies which Taproot script-spend leaves we should sign …","","","","","","","","","Whether the signer should trust the witness_utxo, if the …","Whether to try finalizing the PSBT after the inputs are …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Whether the signer can sign for the internal key or not","Error returned from TxBuilder::add_foreign_utxo.","Error returned from TxBuilder::add_utxo and …","Error returned from TxBuilder::allow_shrinking","BIP69 / Lexicographic","Marker type to indicate the TxBuilder is being used to …","Use both change and non-change outputs (default)","Only use non-change outputs (see …","Policy regarding the use of change outputs when creating a …","Marker type to indicate the TxBuilder is being used to …","Requested outpoint doesn’t exist in the tx (vout greater …","Foreign utxo outpoint txid does not match PSBT input txid","Script/PubKey was not in the original transaction","Foreign utxo missing witness_utxo or non_witness_utxo","Only use change outputs (see TxBuilder::only_spend_change)","Randomized (default)","A transaction builder","Context in which the TxBuilder is valid","Ordering of the transaction’s inputs and outputs","Happens when trying to spend an UTXO that is not in the …","Unchanged","Add data as an output, using OP_RETURN","Add a foreign UTXO i.e. a UTXO not owned by this wallet.","Same as add_foreign_utxo but allows to set the nSequence …","Fill-in the PSBT_GLOBAL_XPUB field with the extended keys …","Add a recipient to the internal list","Add a utxo to the internal list of unspendable utxos","Add a utxo to the internal list of utxos that must be spent","Add the list of outpoints to the internal list of UTXOs …","Set whether or not the dust limit is checked.","Explicitly tells the wallet that it is allowed to reduce …","","","","","","","","","","","","","","","","","Set a specific ChangeSpendPolicy. See …","","","","","","","","","","","","","Choose the coin selection algorithm","Set the current blockchain height.","","","","","Do not spend change outputs","Sets the address to drain excess coins to.","Spend all the available inputs. This respects filters like …","Enable signaling RBF","Enable signaling RBF with a specific nSequence value","","","Set an absolute fee The fee_absolute method refers to the …","Set a custom fee rate.","Finish building the transaction.","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Fill-in the psbt::Output::redeem_script and …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Only spend utxos added by add_utxo.","Use a specific nLockTime while creating the transaction","Only spend change outputs","Only Fill-in the psbt::Input::witness_utxo field when …","Choose the ordering for inputs and outputs of the …","","","Set the policy path to use while creating the transaction …","","","","Replace the recipients already added with a new list","Sign with a specific sig hash","Sort transaction inputs and outputs by TxOrdering variant","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Replace the internal list of unspendable utxos with a new …","Build a transaction with a specific version","","","","","","","","","Foreign UTXO outpoint","PSBT input txid"],"i":[1,5,0,1,0,5,0,0,0,0,0,0,1,1,1,3,4,5,1,3,4,5,0,1,3,4,5,1,3,4,5,1,3,3,0,0,1,3,1,3,4,5,1,3,4,5,0,1,3,4,5,1,3,1,3,4,5,3,3,0,5,3,1,0,4,5,1,3,0,0,1,3,4,5,1,3,4,5,1,3,4,5,5,3,1,3,4,5,4,0,1,3,4,5,0,198,198,198,17,0,0,0,0,0,0,0,0,48,0,0,26,17,0,0,0,17,26,0,17,17,17,26,17,35,36,23,23,17,17,35,36,23,17,35,36,23,23,23,23,0,48,35,36,48,36,48,48,35,36,48,35,36,48,48,35,36,48,35,36,48,35,36,0,17,35,36,23,17,35,36,23,17,35,36,23,23,17,17,17,17,17,23,17,23,17,35,36,23,0,17,23,23,199,17,23,17,17,17,35,36,23,23,17,23,17,17,17,17,17,17,17,35,36,23,23,23,17,23,23,23,17,23,23,23,17,17,23,23,17,17,35,36,23,17,35,36,23,23,17,166,62,17,17,23,23,23,17,23,23,48,35,36,23,17,23,17,48,35,36,17,17,17,17,17,17,17,17,17,17,17,17,17,17,23,48,23,17,23,23,17,35,36,23,48,35,36,17,17,0,23,17,23,17,23,23,17,17,23,17,23,48,35,36,23,0,17,35,36,23,17,23,17,48,48,17,23,17,35,36,23,17,35,36,23,23,17,35,36,23,17,17,35,36,23,23,0,0,47,47,0,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,83,75,75,0,84,0,0,83,82,0,83,83,75,75,75,83,84,45,75,84,84,0,0,0,45,45,82,83,83,0,0,83,83,83,82,82,83,84,46,85,75,45,82,83,84,46,85,75,45,82,83,84,46,85,45,82,83,84,46,85,45,46,85,85,82,83,84,46,85,75,82,83,84,46,85,75,75,45,82,83,84,84,46,46,85,75,45,46,82,85,83,46,82,83,84,46,85,75,45,83,84,85,46,85,75,46,46,82,83,84,46,85,85,82,83,84,46,85,45,75,82,83,84,46,85,75,45,82,83,84,46,85,75,45,82,83,84,46,85,75,45,82,83,84,46,85,75,45,200,200,200,201,202,203,202,203,202,203,202,203,202,203,204,205,206,207,208,209,209,208,210,211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,212,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,86,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,88,89,90,92,94,95,96,97,98,99,100,101,78,0,0,0,0,213,213,0,0,110,0,0,0,0,78,78,78,48,0,0,22,78,78,107,26,213,114,0,114,0,0,22,26,107,0,0,0,0,22,0,110,107,26,0,214,26,114,105,112,22,106,78,103,26,107,108,109,110,114,105,112,22,106,78,103,26,107,108,109,110,103,48,48,48,48,48,48,48,48,48,105,22,106,103,26,107,108,109,110,105,22,106,103,26,107,108,109,110,103,26,108,110,106,106,105,26,26,103,22,103,26,107,108,109,110,112,22,106,78,78,103,103,26,26,107,107,108,109,110,103,114,114,114,105,112,22,106,78,78,78,103,26,26,107,108,109,110,112,112,26,107,103,26,26,213,215,213,215,114,26,103,26,108,110,114,105,112,22,106,78,103,26,107,108,109,110,26,87,93,105,105,112,26,107,93,114,105,105,26,107,114,114,26,214,22,26,107,214,22,214,22,26,26,103,108,109,103,0,26,48,103,103,0,48,103,26,108,109,48,112,103,26,108,110,48,103,78,103,103,103,26,48,103,0,105,22,106,103,26,107,108,109,110,107,78,103,26,107,48,48,103,114,105,112,22,106,78,103,26,107,108,109,110,114,105,112,22,106,78,103,26,107,108,109,110,114,105,112,22,106,78,103,26,107,108,109,110,114,105,112,22,106,78,103,26,107,108,109,110,0,216,216,216,0,0,0,0,154,0,153,150,151,152,0,0,149,151,152,0,152,152,151,151,149,0,0,150,151,152,149,154,0,0,150,152,122,123,145,123,128,123,123,123,123,123,122,123,134,128,149,145,150,151,152,153,154,122,123,134,128,149,145,150,151,152,153,154,123,123,123,123,123,134,128,123,122,134,128,122,134,128,0,123,122,122,134,128,145,123,123,123,122,128,122,128,145,0,0,123,122,122,123,134,128,149,145,145,150,150,151,151,152,152,153,153,154,154,122,123,134,128,128,128,149,145,150,151,152,153,154,123,123,123,123,123,123,123,123,134,122,145,128,123,123,123,122,123,134,128,149,145,150,151,152,153,154,217,128,123,145,123,134,123,123,123,123,123,123,128,123,123,123,123,123,123,123,123,150,151,152,153,154,123,123,123,122,128,123,0,123,123,122,134,128,122,145,150,151,152,153,154,122,123,122,122,122,123,134,128,149,145,150,151,152,153,154,123,123,122,123,134,128,149,145,150,151,152,153,154,0,123,122,123,134,128,149,145,150,151,152,153,154,123,122,122,123,134,128,149,145,150,151,152,153,154,0,218,218,219,219,220,221,220,221,174,174,0,175,0,0,0,0,0,174,0,175,0,174,175,173,170,171,172,174,175,173,170,171,172,170,171,172,170,171,172,190,170,171,172,0,170,171,172,173,173,174,174,175,173,170,171,172,174,175,173,170,171,172,174,175,173,170,171,172,173,172,174,173,173,170,171,172,174,174,175,173,170,171,172,174,175,173,170,171,172,174,175,173,170,171,172,174,175,173,170,171,172,222,222,223,224,224,223,224,0,161,161,176,0,161,161,140,161,161,140,161,161,0,161,161,161,161,161,176,161,161,161,161,161,161,140,140,161,140,176,161,161,176,161,140,176,161,140,176,176,176,176,161,161,140,140,176,161,161,161,161,161,161,140,176,161,140,176,161,140,176,176,161,140,176,161,140,176,161,140,176,161,140,176,161,140,225,226,225,226,227,227,228,229,0,0,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,184,179,184,148,179,184,148,0,148,148,148,181,148,148,148,148,148,148,148,184,179,181,148,0,0,0,0,0,0,0,0,181,0,0,148,44,147,147,44,147,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,44,179,181,183,124,44,147,184,179,181,183,124,44,147,184,179,124,124,44,147,184,183,230,183,183,183,179,181,124,184,44,179,148,148,181,183,124,44,147,184,179,179,179,148,148,181,183,124,44,147,184,179,230,183,183,183,44,179,148,181,183,124,44,147,184,183,44,179,124,148,44,147,147,231,183,183,183,125,183,147,44,147,179,181,183,124,44,147,184,148,147,147,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,179,148,181,183,124,44,147,184,232,0,0,0,195,0,194,194,0,0,191,191,193,191,194,195,0,0,0,192,195,139,139,139,139,139,139,139,139,139,139,141,138,139,192,191,193,195,194,141,138,139,192,191,193,195,194,139,141,138,139,195,194,141,138,139,195,194,195,194,139,139,141,138,195,194,139,139,139,139,139,195,194,139,139,139,141,138,139,192,192,191,191,193,193,195,194,141,138,139,192,191,193,195,194,195,194,139,141,138,139,192,191,193,195,194,139,139,139,139,139,195,194,139,192,191,193,139,139,195,141,138,139,195,194,192,191,193,141,138,139,192,191,193,195,194,141,138,139,192,191,193,195,194,141,138,139,192,191,193,195,194,139,139,141,138,139,192,191,193,195,194,233,233],"f":[0,0,0,0,0,0,0,0,0,0,0,0,[1,2],[1],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[1,1],[3,3],[4,4],[5,5],[[]],[[]],[[]],[[]],[[1,1],6],0,0,0,0,[[],[[7,[1]]]],[[],[[7,[3]]]],[[1,1],8],[[3,3],8],[[4,4],8],[[5,5],8],[[1,9],10],[[3,9],10],[[4,9],10],[[5,9],10],0,[[]],[[]],[[]],[[]],[1],[3],[[]],[[]],[[]],[[]],0,0,0,[5,11],0,[[1,1],[[12,[6]]]],0,0,[5,[[12,[13]]]],[1,7],[3,7],0,0,[[]],[[]],[[]],[[]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[5,14],0,[[],15],[[],15],[[],15],[[],15],0,[[],16],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[17,18],[[7,[[20,[19]],21]]]],[[],22],[[],22],[23,24],[23,[[25,[23]]]],[[[17,[26]],27],[[7,[[17,[28]],29]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[23,[[31,[23,30]]]],[23,[[33,[32]]]],[23,[[33,[32]]]],0,[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],[24,[[7,[34]]]],[24,[[7,[34]]]],[24,[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],[[],[[7,[34]]]],0,[17,17],[35,35],[36,36],[23,23],[[]],[[]],[[]],[[]],[[17,17],6],[[35,35],6],[[36,36],6],[[23,23],6],[23,8],[[[17,[26]],27],[[7,[[17,[28]],29]]]],[[[17,[28]],37],[[7,[[17,[38]],29]]]],[[[17,[26]],37,27],[[7,[[17,[38]],29]]]],[17,39],[[],[[7,[17]]]],[[],[[7,[23]]]],[[[17,[26]]],40],[23,41],[[17,17],8],[[35,35],8],[[36,36],8],[[23,23],8],0,[17,[[7,[41,21]]]],0,[[23,42],[[7,[43]]]],[[44,45,37],[[7,[[12,[46]],47]]]],[[[17,[26]],44,45,37],[[7,[[12,[46]],47]]]],[[[23,[26,48]],44,45,37],[[7,[[12,[46]],47]]]],[[[17,[26]],37,49,[50,[27]]],[[7,[12,29]]]],[[17,9],[[7,[51]]]],[[17,9],[[7,[51]]]],[[35,9],[[7,[51]]]],[[36,9],[[7,[51]]]],[[23,9],[[7,[51]]]],[[23,9],[[7,[51]]]],[17,8],[23,8],[52,17],[53,17],[[]],[54,17],[55,17],[56,17],[57,17],[[]],[[]],[[]],[24,[[7,[23,21]]]],[[24,58,59],23],[16,[[7,[17,21]]]],[16,[[7,[23,21]]]],[[16,42],[[7,[23,21]]]],[16,[[7,[23,21]]]],[60,[[7,[17,21]]]],[60,[[7,[23,21]]]],[[23,61],[[12,[23]]]],[[23,61],12],[17,[[7,[21]]]],[17,[[7,[21]]]],[23,8],[23,8],[[[17,[26]]],8],[17],[35],[36],[23],[[]],[[]],[[]],[[]],[23,24],[[[17,[26]]],[[7,[[31,[[17,[26]],30]],21]]]],[[37,18],[[7,[47]]]],[[62,37,18],[[7,[47]]]],[[[17,[26]]],8],[[[17,[26]]],8],[23,8],[23,63],[23,64],[17,[[7,[65,21]]]],[23,[[7,[65,21]]]],[23,[[7,[66]]]],[23,[[12,[61]]]],[23,[[12,[61]]]],[23,[[12,[61]]]],[23,[[7,[61,21]]]],[17,[[7,[61,21]]]],[23,[[7,[61,21]]]],[17,[[7,[61,21]]]],[[],16],[[],16],[[],16],[[[23,[67]]],[[7,[17,21]]]],[[],17],[[],[[7,[17,21]]]],[[[23,[35]]],[[7,[17,21]]]],[[61,[31,[30]]],[[7,[17,21]]]],[53,17],[57,17],[[],[[7,[17,21]]]],[[[23,[36]]],[[7,[17,21]]]],[[61,[31,[30]]],[[7,[17,21]]]],[[[12,[68]]],[[7,[17,21]]]],[[],[[7,[17,21]]]],[[[23,[36]]],[[7,[17,21]]]],[[61,[31,[30]]],[[7,[17,21]]]],0,[23,[[7,[21]]]],[49,[[7,[23,21]]]],[[37,16],[[7,[21]]]],[49,[[7,[23,21]]]],[[49,42],[[7,[23,21]]]],[[17,17],[[12,[6]]]],[[35,35],[[12,[6]]]],[[36,36],[[12,[6]]]],[[23,23],[[12,[6]]]],[[],61],[[],61],[[],61],[[[17,[28]]],[[7,[69,[17,[28]]]]]],[[[17,[28]]],[[7,[69,[17,[28]]]]]],0,[23,8],[17,[[7,[21]]]],[23,[[7,[43]]]],[[17,70],[[7,[21]]]],[23,[[7,[[31,[[31,[2,30]],30]],21]]]],[23,[[7,[[31,[[31,[2,30]],30]],21]]]],[17,[[7,[41,21]]]],[17,41],[23,61],[17,7],[23,7],[[],71],[[],71],[[],71],[[23,72],23],0,[[]],[[]],[[]],[[]],[[],73],[[],73],[[[17,[26]],72],73],[23,[[7,[21]]]],[23,[[7,[21]]]],[17,[[7,[74]]]],[23,[[7,[74]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],0,[[],15],[[],15],[[],15],[[],15],[17,41],[[]],[[]],[[]],[[]],[23,8],[16,[[7,[73,47]]]],[16,[[7,[47]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[47,9],10],[[47,9],10],[75,47],[76,47],[77,47],[78,47],[79,47],[80,47],[21,47],[[]],[[]],[81],[[],73],[[],7],[[],7],[[],15],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[82,82],[83,83],[84,84],[46,46],[85,85],[45,45],[[]],[[]],[[]],[[]],[[]],[[]],0,0,[[],85],[[82,82],8],[[83,83],8],[[84,84],8],[[46,46],8],[[85,85],8],[[75,75],8],[[82,9],10],[[83,9],10],[[84,9],10],[[46,9],10],[[85,9],10],[[75,9],10],[[75,9],10],[[45,9],10],[[]],[[]],[[]],[8,84],[[]],[83,46],[[]],[[]],[[]],[[46,72],[[7,[85,75]]]],[82],[85],[83,73],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[83,8],[84,8],[85,8],0,[[85,85],[[12,[6]]]],[81],[46,8],0,[82,7],[83,7],[84,7],[46,7],[85,7],0,[[]],[[]],[[]],[[]],[[]],[[]],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[18,[[7,[86,47]]]],[[[88,[[87,[35]]]],18],[[7,[86,47]]]],[[[89,[[87,[36]]]],18],[[7,[86,47]]]],[[[90,[[87,[36]]]],18],[[7,[86,47]]]],[[[92,[[87,[91]]]],18],[[7,[86,47]]]],[[[94,[[93,[35]]]],18],[[7,[86,47]]]],[[[95,[[93,[35]]]],18],[[7,[86,47]]]],[[[96,[[93,[36]]]],18],[[7,[86,47]]]],[[[97,[[93,[36]]]],18],[[7,[86,47]]]],[[[98,[[93,[36]]]],18],[[7,[86,47]]]],[[[99,[[93,[36]]]],18],[[7,[86,47]]]],[[[100,[[93,[91]]]],18],[[7,[86,47]]]],[[[101,[[93,[91]]]],18],[[7,[86,47]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[86,37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[37,18],[[7,[47]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],102],[[],22],[[26,27],[[7,[28,29]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[103,[[33,[32]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[23,[[7,[34]]]],[[],[[7,[34]]]],[24,[[7,[34]]]],[[],[[7,[34]]]],[[[105,[104,48]]],[[105,[104,48]]]],[22,22],[106,106],[103,103],[26,26],[107,107],[108,108],[109,109],[110,110],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[103,103],6],[[26,26],6],[[108,108],6],[[110,110],6],0,[[],106],[[[105,[48]]]],[[26,27],[[7,[28,29]]]],[[],[[7,[26]]]],[103,41],[[22,22],8],[[103,103],8],[[26,26],8],[[107,107],8],[[108,108],8],[[109,109],8],[[110,110],8],[[[112,[[0,[111,48]]]],9],10],[[22,9],10],[[106,9],10],[[78,9],10],[[78,9],10],[[103,9],[[7,[51]]]],[[103,9],[[7,[51]]]],[[26,9],[[7,[51]]]],[[26,9],[[7,[51]]]],[[107,9],[[7,[51]]]],[[107,9],[[7,[51]]]],[[108,9],[[7,[51]]]],[[109,9],[[7,[51]]]],[[110,9],[[7,[51]]]],[103,8],[[]],[113,[[114,[48]]]],[115,[[114,[48]]]],[[]],[[]],[[]],[[]],[21,78],[76,78],[[]],[[]],[28,26],[[]],[[]],[[]],[[]],[[]],[[26,102],[[112,[48]]]],[[107,102],[[112,[48]]]],[16,[[7,[26]]]],[16,[[7,[107]]]],[60,[[7,[103,21]]]],[26,[[12,[116]]]],[26,[[31,[116,30]]]],[[],[[7,[105]]]],[[],[[7,[105]]]],[[],[[7,[105]]]],[[],[[7,[105]]]],[[[114,[48]]],8],[26,8],[103],[26],[108],[110],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[26,117],[[],[[7,[112,78]]]],[[[12,[118]],116],[[7,[112,78]]]],[105,[[7,[112,78]]]],[[105,[12,[118]],116],[[7,[112,78]]]],[[[112,[48]]],[[7,[[112,[48]],78]]]],[26,[[7,[[112,[48]],78]]]],[107,[[7,[[112,[48]],78]]]],[[],[[7,[114,78]]]],[[[114,[48]]],[[7,[[114,[48]],78]]]],[105,[[7,[114,78]]]],[[[105,[48]]]],[26,[[31,[26,30]]]],[107,[[31,[107,30]]]],[[[114,[48]],18],[[12,[113]]]],[[[114,[48]],18,37],115],[26,8],[[],8],[22,8],[26,8],[107,8],[[],8],[22,8],[[],8],[22,8],[26,8],[26,8],0,0,0,[103,[[7,[65,21]]]],[[],102],[26,119],[23,[[12,[61]]]],[103,61],[103,61],[[102,102],102],[[],16],[[61,[31,[30]]],[[7,[103,21]]]],[26,61],0,0,[23,[[7,[21]]]],[[[112,[48]],102],[[112,[48]]]],[[103,103],[[12,[6]]]],[[26,26],[[12,[6]]]],[[108,108],[[12,[6]]]],[[110,110],[[12,[6]]]],[[],61],0,[81],[103,[[7,[21]]]],[103,[[7,[[31,[[31,[2,30]],30]],21]]]],[103,61],[26,7],[[],71],[103,24],[[],102],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[107,37],[[7,[26,120]]]],[[],73],[[],73],[[],73],[[],73],[23,[[7,[21]]]],[23,[[7,[21]]]],[103,[[7,[103,74]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[],[[12,[40]]]],[[],[[12,[121]]]],[61,[[12,[14]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[122,122],122],[[123,1,124,[126,[125]]]],0,[123,[[72,[1,[0,[127,104]]]]]],[[128,128]],[[123,129,27],[[7,[130]]]],[[123,129,27,131],[[7,[132]]]],[[123,133]],[[123,134],[[7,[130]]]],[123,135],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[123,136],[[7,[[139,[137,138]],140]]]],[123,[[139,[137,141]]]],[[123,142],[[7,[40,143]]]],[[123,142],[[7,[121,143]]]],[[123,142]],0,0,[123,144],[122,122],[134,134],[128,128],[[]],[[]],[[]],0,[123,[[7,[8]]]],0,[[],122],[[],134],[[],128],[145],[[123,1],[[12,[27]]]],[[123,49],12],[[123,1],73],[[],[[7,[122]]]],[[],[[7,[128]]]],[[122,122],8],[[128,128],8],[[145,145],8],0,0,[[123,146,147],[[7,[8,148]]]],[[122,9],[[7,[51]]]],[[122,9],[[7,[51]]]],[[[123,[111]],9],10],[[134,9],10],[[128,9],10],[[149,9],10],[[145,9],10],[[145,9],10],[[150,9],10],[[[150,[111]],9],10],[[[151,[111]],9],10],[[151,9],10],[[[152,[111,111]],9],10],[[152,9],10],[[153,9],10],[[153,9],10],[[154,9],10],[[154,9],10],[[]],[[]],[[]],[[[157,[155,[156,[1]]]]],128],[[]],[158,128],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[123,149],145],[123,122],[[123,1],62],[[123,149],145],[[123,3,[12,[159]],8],[[7,[160,161]]]],[[123,1],[[126,[44]]]],[[123,136],[[12,[[162,[[126,[142]],155]]]]]],[[123,11],[[12,[3]]]],0,0,0,0,[[123,131],[[7,[8,163]]]],[[123,142,164],[[7,[8,153]]]],[[123,11,14]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[49,8],[128,8],[[123,49],8],0,[123,72],0,[123,165],[123,127],[123,127],[[166,[12,[166]]],[[7,[123,151]]]],[123,167],[123,18],0,[[166,[12,[166]],18],[[7,[123,150]]]],[[166,[12,[166]],18],[[7,[123,47]]]],[[166,[12,[166]],18,168],[[7,[123,47]]]],[[166,[12,[166]],18],[[7,[123,152]]]],[[166,[12,[166]],18,168],[[7,[123,152]]]],[[166,[12,[166]],18,168],[[7,[123,150]]]],[[123,1],27],[[123,1],[[7,[[12,[46]],47]]]],[81],[81],[81],[81],[81],[[123,1],[[12,[62]]]],[123,37],[[123,142]],[122,7],[128,7],[[123,146,147],[[7,[8,148]]]],0,[123,169],[123,128],[[]],[[]],[[]],[[],73],[[],73],[[],73],[[],73],[[],73],[[],73],[[],73],[122,40],[123,127],0,[122,40],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[123,149],[[7,[145]]]],[[123,149],[[7,[145]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],0,[123,135],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[123,1],[[0,[127,104]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[12,18,37],[[7,[73,47]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[170,170],[171,171],[172,172],[[]],[[]],[[]],[[[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[170,[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[171,[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[172,[31,[4]],[31,[4]],121,40,49],[[7,[173,174]]]],[[40,121,49],175],[[],170],[[],171],[[],172],0,0,[[174,9],10],[[174,9],10],[[175,9],10],[[173,9],10],[[170,9],10],[[171,9],10],[[172,9],10],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[173,40],[40,172],[81],0,[173,40],[[]],[[]],[[]],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[176,176],[[]],[[176,9],10],[[176,9],10],[[[161,[111]],9],10],[[161,9],10],[[140,9],10],[[140,9],10],[[]],[47,161],[174,161],[75,161],[176,161],[[]],[177,161],[[]],[[]],[[]],[[]],[81],[81],[81],[[]],[[],73],[[],73],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[178,[[12,[73]]]],[178,73],[[],[[7,[178]]]],[[123,16,8],[[7,[178,16]]]],[[178,9],10],[[]],[16,[[7,[178]]]],[[]],0,[178,7],[178,73],[[],7],[[],7],[[],15],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[44,179,124,[126,[125]]],[[12,[[126,[125]]]]]],0,0,[[44,37],180],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[180,17,37],44],[179,179],[181,181],[[[183,[[0,[104,182,111,104]]]]],[[183,[[0,[104,182,111,104]]]]]],[124,124],[44,44],[147,147],[184,184],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[179,179],6],[[124,124],6],[[],124],[[],44],[[],147],[[],184],[[[183,[[0,[182,111,104]]]]]],[[],[[12,[107]]]],[[[183,[185]]],[[12,[107]]]],[[[183,[[186,[113]]]]],[[12,[107]]]],[[[183,[[187,[113]]]]],[[12,[107]]]],[[179,179],8],[[181,181],8],[[124,124],8],[[184,184],8],[[44,179],[[12,[126]]]],[[179,9],10],[[148,9],10],[[148,9],10],[[181,9],10],[[[183,[[0,[111,182,111,104]]]],9],10],[[124,9],10],[[44,9],10],[[147,9],10],[[184,9],10],[188,179],[119,179],[[]],[189,148],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[179],[37,179],[[[183,[185]],37],179],[[[183,[[186,[113]]]],37],179],[[[183,[[187,[113]]]],37],179],[44,[[31,[179]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[0,[182,111,104]],181],[[183,[[0,[182,111,104]]]]]],[[],44],[[179,179],[[12,[6]]]],[[124,124],[[12,[6]]]],[81],[[44,179,124],[[12,[[126,[125]]]]]],0,0,[[146,61,147,37],[[7,[148]]]],[[[183,[185]],146,61,147,37],[[7,[148]]]],[[[183,[[186,[113]]]],146,61,147,37],[[7,[148]]]],[[[183,[[187,[113]]]],146,61,147,37],[[7,[148]]]],[[146,147,37],[[7,[148]]]],[[146,147,37],[[7,[148]]]],0,[44,[[31,[126]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],73],0,0,[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[[139,[190,141]]],[[139,[190,141]]]],[[139,11,160,61],[[7,[139,191]]]],[[139,11,160,61,13],[[7,[139,191]]]],[139,139],[[[139,[190,141]],41,40],[[139,[190,141]]]],[[139,11],139],[[139,11],[[7,[139,192]]]],[139,[[7,[139,192]]]],[[139,8],139],[[[139,[137,138]],41],[[7,[[139,[137,138]],193]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[139,194],139],[141,141],[138,138],[[[139,[104]]],[[139,[104]]]],[195,195],[194,194],[[]],[[]],[[]],[[]],[[]],[[195,195],6],[[194,194],6],[[139,190],[[139,[190]]]],[[139,27],139],[[],141],[[],138],[[],195],[[],194],[139,139],[[[139,[190,141]],41],[[139,[190,141]]]],[139,139],[139,139],[[139,13],139],[[195,195],8],[[194,194],8],[[139,40],139],[[139,121],139],[[[139,[190]]],[[7,[146,161]]]],[[141,9],10],[[138,9],10],[[[139,[111,111,111]],9],10],[[192,9],10],[[192,9],10],[[191,9],10],[[191,9],10],[[193,9],10],[[193,9],10],[[195,9],10],[[194,9],10],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[195],[194],[139,139],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[139,139],[[139,196],139],[139,139],[139,139],[[139,195],139],[[195,195],[[12,[6]]]],[[194,194],[[12,[6]]]],[[139,[72,[73,[31,[61]]]],1],139],[81],[81],[81],[[[139,[190,141]],31],[[139,[190,141]]]],[[139,159],139],[[195,142]],[[]],[[]],[[]],[[]],[[]],[[],73],[[],73],[[],73],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[139,[31,[11]]],139],[[139,197],139],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0],"p":[[4,"KeychainKind"],[15,"u8"],[3,"LocalOutput"],[3,"WeightedUtxo"],[4,"Utxo"],[4,"Ordering"],[4,"Result"],[15,"bool"],[3,"Formatter"],[6,"Result"],[3,"OutPoint"],[4,"Option"],[3,"Sequence"],[3,"TxOut"],[3,"TypeId"],[15,"str"],[4,"Descriptor"],[4,"Network"],[4,"NetworkChecked"],[3,"Address"],[4,"Error"],[4,"ScriptContextEnum"],[3,"Miniscript"],[4,"Terminal"],[4,"Tree"],[4,"DescriptorPublicKey"],[15,"u32"],[3,"DefiniteDescriptorKey"],[4,"ConversionError"],[3,"Global"],[3,"Vec"],[4,"Placeholder"],[3,"Satisfaction"],[4,"ScriptContextError"],[4,"Legacy"],[4,"Segwitv0"],[3,"Secp256k1"],[3,"PublicKey"],[4,"DescriptorType"],[15,"u64"],[3,"ScriptBuf"],[3,"ExtParams"],[4,"AnalysisError"],[3,"SignersContainer"],[4,"BuildSatisfaction"],[3,"Policy"],[4,"Error"],[8,"ScriptContext"],[3,"Script"],[3,"Range"],[3,"Error"],[3,"Bare"],[3,"Wpkh"],[3,"Pkh"],[3,"Sh"],[3,"Tr"],[3,"Wsh"],[3,"Type"],[3,"ExtData"],[3,"Tree"],[15,"usize"],[6,"ExtendedDescriptor"],[3,"Iter"],[3,"PkIter"],[4,"Policy"],[4,"LiftError"],[4,"BareCtx"],[4,"TapTree"],[3,"Plan"],[3,"TxIn"],[4,"SigType"],[3,"BTreeMap"],[3,"String"],[4,"TranslateErr"],[4,"PolicyError"],[4,"Error"],[4,"Error"],[4,"KeyError"],[4,"Error"],[4,"HexToBytesError"],[3,"Demand"],[4,"PkOrF"],[4,"SatisfiableItem"],[4,"Satisfaction"],[3,"Condition"],[6,"DescriptorTemplateOut"],[8,"IntoDescriptorKey"],[3,"P2Pkh"],[3,"P2Wpkh_P2Sh"],[3,"P2Wpkh"],[4,"Tap"],[3,"P2TR"],[8,"DerivableKey"],[3,"Bip44"],[3,"Bip44Public"],[3,"Bip49"],[3,"Bip49Public"],[3,"Bip84"],[3,"Bip84Public"],[3,"Bip86"],[3,"Bip86Public"],[6,"ValidNetworks"],[3,"SortedMultiVec"],[8,"Clone"],[3,"GeneratedKey"],[3,"PrivateKeyGenerateOptions"],[4,"DescriptorSecretKey"],[3,"SinglePub"],[3,"SinglePriv"],[4,"SinglePubKey"],[8,"Debug"],[4,"DescriptorKey"],[3,"Xpriv"],[4,"ExtendedKey"],[3,"Xpub"],[3,"DerivationPath"],[3,"Assets"],[6,"KeySource"],[3,"Fingerprint"],[3,"DescriptorKeyParseError"],[3,"FeeRate"],[3,"Balance"],[3,"Wallet"],[3,"SignerOrdering"],[8,"TransactionSigner"],[3,"Arc"],[8,"Iterator"],[3,"ChangeSet"],[3,"Block"],[3,"CannotConnectError"],[3,"BlockId"],[4,"ApplyHeaderError"],[8,"IntoIterator"],[3,"Update"],[3,"TxGraph"],[3,"Txid"],[6,"DefaultCoinSelectionAlgorithm"],[3,"BumpFee"],[3,"TxBuilder"],[4,"BuildFeeBumpError"],[3,"CreateTx"],[3,"Transaction"],[4,"CalculateFeeError"],[3,"CheckPointIter"],[3,"AddressInfo"],[3,"Psbt"],[3,"SignOptions"],[4,"SignerError"],[4,"AddressIndex"],[4,"NewError"],[4,"LoadError"],[4,"NewOrLoadError"],[4,"InsertTxError"],[4,"ApplyBlockError"],[3,"ConfirmationTimeHeightAnchor"],[3,"ChangeSet"],[3,"ChangeSet"],[6,"ChangeSet"],[3,"PsbtSighashType"],[3,"Input"],[4,"CreateTxError"],[3,"CanonicalTx"],[3,"AlterCheckPointError"],[4,"ConfirmationTime"],[3,"CheckPoint"],[8,"IntoWalletDescriptor"],[3,"LocalChain"],[3,"BlockHash"],[3,"KeychainTxOutIndex"],[3,"LargestFirstCoinSelection"],[3,"OldestFirstCoinSelection"],[3,"BranchAndBoundCoinSelection"],[3,"CoinSelectionResult"],[4,"Error"],[4,"Excess"],[4,"MiniscriptPsbtError"],[4,"Error"],[3,"FullyNodedExport"],[4,"SignerId"],[6,"KeyMap"],[4,"SignerContext"],[8,"Sized"],[3,"SignerWrapper"],[4,"TapLeavesOptions"],[3,"PrivateKey"],[3,"DescriptorMultiXKey"],[3,"DescriptorXKey"],[3,"Hash"],[4,"Error"],[8,"CoinSelectionAlgorithm"],[4,"AddForeignUtxoError"],[4,"AddUtxoError"],[4,"AllowShrinkingError"],[4,"ChangeSpendPolicy"],[4,"TxOrdering"],[4,"LockTime"],[15,"i32"],[13,"Foreign"],[8,"ExtractPolicy"],[13,"PsbtTimelocks"],[13,"Complete"],[13,"Partial"],[13,"PartialComplete"],[13,"Sha256Preimage"],[13,"Hash256Preimage"],[13,"Ripemd160Preimage"],[13,"Hash160Preimage"],[13,"Thresh"],[13,"Multisig"],[13,"AbsoluteTimelock"],[13,"RelativeTimelock"],[8,"DescriptorTemplate"],[8,"GeneratableKey"],[8,"ExtScriptContext"],[8,"GeneratableDefaultOptions"],[8,"PsbtUtils"],[8,"IsDust"],[13,"UnexpectedConnectedToHash"],[13,"ConfirmationHeightCannotBeGreaterThanTip"],[13,"LoadedGenesisDoesNotMatch"],[13,"LoadedNetworkDoesNotMatch"],[13,"InsufficientFunds"],[13,"Change"],[13,"NoChange"],[13,"InsufficientFunds"],[13,"RbfSequenceCsv"],[13,"LockTime"],[13,"FeeTooLow"],[13,"FeeRateTooLow"],[8,"SignerCommon"],[8,"InputSigner"],[13,"Tap"],[13,"InvalidTxid"]]},\ "bdk_bitcoind_rpc":{"doc":"This crate is used for emitting blockchain data from the …","t":[8,3,3,2,12,11,11,11,11,11,11,12,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11],"n":["BitcoindRpcErrorExt","BlockEvent","Emitter","bitcoincore_rpc","block","block_hash","block_height","borrow","borrow","borrow_mut","borrow_mut","checkpoint","connected_to","fmt","from","from","into","into","is_not_found_error","mempool","new","next_block","next_header","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip"],"q":["bdk_bitcoind_rpc","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Extends bitcoincore_rpc::Error.","A newly emitted block from Emitter.","The Emitter is used to emit data sourced from …","","Either a full Block or Header of the new block.","The block hash of this new block.","The block height of this new block.","","","","","The checkpoint of the new block.","The BlockId of a previous block that this block connects …","","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Returns whether the error is a “not found” error.","Emit mempool transactions, alongside their first-seen unix …","Construct a new Emitter.","Emit the next block height and block (if any).","Emit the next block height and header (if any).","","","","","","","",""],"i":[0,0,0,0,1,1,1,10,1,10,1,1,1,1,10,1,10,1,19,10,10,10,10,10,1,10,1,10,1,10,1],"f":[0,0,0,0,0,[1,2],[1,3],[[]],[[]],[[]],[[]],0,[1,4],[[[1,[5]],6],7],[[]],[[]],[[]],[[]],[[],8],[[[10,[9]]],[[13,[11,12]]]],[[14,3],[[10,[9]]]],[[[10,[9]]],[[13,[[16,[[1,[15]]]],12]]]],[[[10,[9]]],[[13,[[16,[[1,[17]]]],12]]]],[[],13],[[],13],[[],13],[[],13],[[],18],[[],18],[[]],[[]]],"p":[[3,"BlockEvent"],[3,"BlockHash"],[15,"u32"],[3,"BlockId"],[8,"Debug"],[3,"Formatter"],[6,"Result"],[15,"bool"],[8,"RpcApi"],[3,"Emitter"],[3,"Vec"],[4,"Error"],[4,"Result"],[3,"CheckPoint"],[3,"Block"],[4,"Option"],[3,"Header"],[3,"TypeId"],[8,"BitcoindRpcErrorExt"]]},\ -"bdk_chain":{"doc":"This crate is a collection of core structures for Bitcoin …","t":[8,8,8,17,3,17,8,4,3,4,3,13,13,8,16,3,2,16,3,8,3,3,2,13,13,16,11,10,11,11,11,12,12,10,11,2,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,10,11,11,11,11,11,12,12,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,10,11,12,11,11,11,0,10,0,11,2,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,12,12,12,3,16,3,8,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,10,10,12,10,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,3,4,13,3,6,3,3,13,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,4,3,3,13,13,3,3,3,3,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,12,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Anchor","AnchorFromBlockPosition","Append","BIP32_MAX_INDEX","BlockId","COINBASE_MATURITY","ChainOracle","ChainPosition","ConfirmationHeightAnchor","ConfirmationTime","ConfirmationTimeHeightAnchor","Confirmed","Confirmed","DescriptorExt","Error","FullTxOut","IndexedTxGraph","LoadError","Persist","PersistBackend","SpkIterator","SpkTxOutIndex","TxGraph","Unconfirmed","Unconfirmed","WriteError","all_spks","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","append","apply_changeset","bitcoin","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","chain_position","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cloned","cmp","cmp","cmp","cmp","cmp","cmp","commit","confirmation_height","confirmation_height","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_time","default","default","default","default","descriptor","deserialize","deserialize","deserialize","deserialize","dust_value","eq","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from_block_position","from_block_position","from_block_position","from_block_position","get_chain_tip","hash","hash","hash","hash","hash","hash","height","index_of_spk","index_tx","index_txout","indexed_tx_graph","initial_changeset","insert_spk","into","into","into","into","into","into","into","into","into","into_iter","is_block_in_chain","is_confirmed","is_confirmed","is_confirmed_and_spendable","is_empty","is_mature","is_on_coinbase","is_relevant","is_tx_relevant","is_used","keychain","load_from_persistence","local_chain","mark_used","miniscript","net_value","new","new","new_with_range","next","nth","outpoint","outpoints","outputs_in_range","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","scan","scan_txout","sent_and_received","serialize","serialize","serialize","serialize","spent_by","spk_at_index","stage","stage_and_commit","staged","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","tx_graph","txout","txout","txouts","txouts_in_tx","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unconfirmed","unmark_used","unused_spks","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","write_changes","height","last_seen","time","ChangeSet","ChangeSet","IndexedTxGraph","Indexer","append","apply_block","apply_block_relevant","apply_changeset","apply_changeset","apply_update","batch_insert_relevant","batch_insert_relevant_unconfirmed","batch_insert_unconfirmed","borrow","borrow","borrow_mut","borrow_mut","clone","clone_into","default","default","deserialize","eq","fmt","fmt","from","from","from","from","graph","graph","index","index_tx","index_txout","indexer","initial_changeset","initial_changeset","insert_anchor","insert_seen_at","insert_tx","insert_txout","into","into","is_empty","is_tx_relevant","new","serialize","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","Balance","ChangeSet","KeychainTxOutIndex","add","add_keychain","all_unbounded_spk_iters","append","apply_changeset","apply_changeset","as_inner","as_ref","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","confirmed","default","default","default","deserialize","deserialize","eq","eq","fmt","fmt","fmt","fmt","from","from","from","immature","index_of_spk","index_tx","index_txout","initial_changeset","inner","into","into","into","is_empty","is_tx_relevant","is_used","keychain_outpoints","keychain_outpoints_in_range","keychains","last_revealed_index","last_revealed_indices","last_used_index","last_used_indices","lookahead","lookahead_to_target","mark_used","net_value","new","next_index","next_unused_spk","outpoints","reveal_next_spk","reveal_to_target","reveal_to_target_multi","revealed_keychain_spks","revealed_spks","sent_and_received","serialize","serialize","spk_at_index","to_owned","to_owned","to_owned","to_string","total","trusted_pending","trusted_spendable","try_from","try_from","try_from","try_into","try_into","try_into","txout","txouts","txouts_in_tx","type_id","type_id","type_id","unbounded_spk_iter","unmark_used","untrusted_pending","unused_keychain_spks","unused_spks","vzip","vzip","vzip","AlterCheckPointError","ApplyHeaderError","CannotConnect","CannotConnectError","ChangeSet","CheckPoint","CheckPointIter","InconsistentBlocks","LocalChain","MissingGenesisError","Update","apply_changeset","apply_header","apply_header_connected_to","apply_update","block_id","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","disconnect_from","eq","eq","eq","eq","eq","eq","eq","extend","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from_block_ids","from_blocks","from_changeset","from_genesis_hash","from_header","from_tip","genesis_hash","get","get","get_chain_tip","hash","height","height","initial_changeset","insert_block","into","into","into","into","into","into","into","into","into_iter","into_iter","into_update","introduce_older_blocks","is_block_in_chain","iter","iter_checkpoints","new","next","original_hash","prev","provide","provide","provide","provide","push","range","range","tip","tip","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_include_height","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","update_hash","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","CalculateFeeError","CanonicalTx","ChangeSet","MissingTxOut","NegativeFee","TxAncestors","TxDescendants","TxGraph","TxNode","all_anchors","all_txouts","anchor_heights","anchors","anchors","append","apply_changeset","apply_update","as_ref","balance","batch_insert_unconfirmed","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","calculate_fee","chain_position","checked_sum","checked_sum","checked_sum","checked_sum","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","cmp","default","default","deref","deserialize","direct_conflicts","eq","eq","eq","eq","eq","filter_chain_txouts","filter_chain_unspents","floating_txouts","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","full_txs","get_chain_position","get_chain_spend","get_tx","get_tx_node","get_txout","initial_changeset","insert_anchor","insert_seen_at","insert_tx","insert_txout","into","into","into","into","into","into","into","into_iter","into_iter","is_empty","is_empty","last_seen","last_seen_unconfirmed","list_chain_txs","map_anchors","map_anchors","missing_heights","missing_heights_from","new","next","next","outspends","partial_cmp","partial_cmp","provide","serialize","to_owned","to_owned","to_owned","to_owned","to_string","try_balance","try_filter_chain_txouts","try_filter_chain_unspents","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_get_chain_position","try_get_chain_spend","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_list_chain_txs","tx","tx_node","tx_outputs","tx_spends","txid","txouts","txouts","txs","type_id","type_id","type_id","type_id","type_id","type_id","type_id","update_last_seen_unconfirmed","vzip","vzip","vzip","vzip","vzip","vzip","vzip","walk_ancestors","walk_conflicts","walk_descendants"],"q":["bdk_chain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::ConfirmationTime","","","bdk_chain::indexed_tx_graph","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::keychain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::local_chain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::tx_graph","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Trait that “anchors” blockchain data to a specific …","An Anchor that can be constructed from a given block, …","Trait that makes an object appendable.","Maximum BIP32 derivation index.","A reference to a block in the canonical chain.","How many confirmations are needed f or a coinbase output …","Represents a service that tracks the blockchain.","Represents the observed position of some chain data.","An Anchor implementation that also records the exact …","Block height and timestamp at which a transaction is …","An Anchor implementation that also records the exact …","The chain data is seen as confirmed, and in anchored by A.","The transaction is confirmed","A trait to extend the functionality of a miniscript …","Error type.","A TxOut with as much data as we can retrieve about it","","The error the backend returns when it fails to load …","Persist wraps a PersistBackend (B) to create a convenient …","A persistence backend for Persist.","An iterator for derived script pubkeys.","An index storing TxOuts that have a script pubkey that …","","The chain data is not confirmed and last seen in the …","The transaction is unconfirmed","The error the backend returns when it fails to write.","The script pubkeys that are being tracked by the index.","Returns the BlockId that the associated blockchain data is …","","","","The anchor block.","The anchor block.","Append another object of the same type onto self.","","","","","","","","","","","","","","","","","","","","","The position of the transaction in outpoint in the overall …","","","","","","","","","","","","","","","","","Maps a ChainPosition<&A> into a ChainPosition<A> by …","","","","","","","Commit the staged changes to the underlying persistence …","The exact confirmation height of the transaction.","The confirmation height of the transaction being anchored.","Get the upper bound of the chain data’s confirmation …","Get the upper bound of the chain data’s confirmation …","Determines the upper bound of the confirmation height.","","","The confirmation time of the transaction being anchored.","","","","","Get a reference to the internal descriptor.","","","","","Returns the minimum value (in satoshis) at which an output …","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Construct the anchor from a given block, block height and …","","","","Get the best chain’s chain tip.","","","","","","The hash of the block.","The height of the block.","Returns the index associated with the script pubkey.","","","Contains the IndexedTxGraph and associated types. Refer to …","","Adds a script pubkey to scan for. Returns false and does …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","Determines whether block of BlockId exists as an ancestor …","Returns whether ChainPosition is confirmed or not.","Returns whether ConfirmationTime is the confirmed variant.","Whether the utxo is/was/will be spendable with chain tip.","Returns whether the structure is considered empty.","Whether the txout is considered mature.","Whether this output is on a coinbase transaction.","Whether any of the inputs of this transaction spend a …","","Returns whether the script pubkey at index has been used …","Module for keychain related structures.","Return the aggregate changeset C from persistence.","The LocalChain is a local implementation of ChainOracle.","Marks the script pubkey at index as used even though it …","","Computes the net value that this transaction gives to the …","Create a new Persist from PersistBackend.","Create a new script pubkey iterator from descriptor.","Create a new script pubkey iterator from descriptor and a …","","","The location of the TxOut.","Get a reference to the set of indexed outpoints.","Iterates over all the outputs with script pubkeys in an …","","","","","","","Scans a transaction’s outputs for matching script …","Scan a single TxOut for a matching script pubkey and …","Computes total input value going from script pubkeys in …","","","","","The txid and chain position of the transaction (if any) …","Returns the script that has been inserted at the index.","Stage a changeset to be committed later with commit.","Stages a new changeset and commits it (along with any …","Get the changes that have not been committed yet.","","","","","","","","","","","","","","","","","","","","","","","","","","","Module for structures that store and traverse transactions.","Returns the txout and script pubkey index of the TxOut at …","The TxOut.","Iterate over all known txouts that spend to tracked script …","Finds all txouts on a transaction that has previously been …","","","","","","","","","","Construct an unconfirmed variant using the given last_seen …","Undoes the effect of mark_used. Returns whether the index …","Iterates over all unused script pubkeys in an index range.","","","","","","","","","","Writes a changeset to the persistence backend.","Confirmation height.","The last-seen timestamp in unix seconds.","Confirmation time in unix seconds.","Represents changes to an IndexedTxGraph.","The resultant “changeset” when new transaction data is …","The IndexedTxGraph combines a TxGraph and an Indexer …","Utilities for indexing transaction data.","","Batch insert all transactions of the given block of height.","Batch insert all transactions of the given block of height…","Apply changeset to itself.","Applies the ChangeSet to the IndexedTxGraph.","Apply an update directly.","Batch insert transactions, filtering out those that are …","Batch insert unconfirmed transactions, filtering out those …","Batch insert unconfirmed transactions.","","","","","","","","","","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","Get a reference of the internal transaction graph.","TxGraph changeset.","Transaction index.","Scans a transaction for relevant outpoints, which are …","Scan and index the given outpoint and txout.","Indexer changeset.","Determines the ChangeSet between self and an empty Indexer.","Determines the ChangeSet between self and an empty …","Insert an anchor for a given transaction.","Insert a unix timestamp of when a transaction is seen in …","Insert and index a transaction into the graph.","Insert a floating txout of given outpoint.","Calls U::from(self).","Calls U::from(self).","","Determines whether the transaction should be included in …","Construct a new IndexedTxGraph with a given index.","","","","","","","","","","","Balance, differentiated into various categories.","Represents updates to the derivation index of a …","KeychainTxOutIndex controls how script pubkeys are …","","Add a keychain to the tracker’s txout_index with a …","Get unbounded spk iterators for all keychains.","Append another ChangeSet into self.","","Applies the derivation changeset to the KeychainTxOutIndex…","Get the inner map of the keychain to its new derivation …","","","","","","","","","","","","","","Confirmed and immediately spendable balance","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","All coinbase outputs not yet matured","Returns the keychain and keychain index associated with …","","","","Return a reference to the internal SpkTxOutIndex.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Returns whether the changeset are empty.","","Returns whether the spk under the keychain’s index has …","Iterate over all OutPoints that point to TxOuts with …","Iterate over OutPoints that point to TxOuts with script …","Return a reference to the internal map of keychain to …","Get the last derivation index revealed for keychain.","Get the last derivation index that is revealed for each …","Returns the highest derivation index of the keychain where …","Returns the highest derivation index of each keychain that …","Get the lookahead setting.","Store lookahead scripts until target_index (inclusive).","Marks the script pubkey at index as used even though the …","Computes the net value that this transaction gives to the …","Construct a KeychainTxOutIndex with the given lookahead.","Get the next derivation index for keychain. The next index …","Gets the next unused script pubkey in the keychain. I.e., …","Get a reference to the set of indexed outpoints.","Attempts to reveal the next script pubkey for keychain.","Reveals script pubkeys of the keychain’s descriptor up …","Convenience method to call Self::reveal_to_target on …","Iterate over revealed spks of the given keychain.","Iterate over revealed spks of all keychains.","Computes total input value going from script pubkeys in …","","","Return the script that exists under the given keychain’s …","","","","","Get the whole balance visible to the wallet.","Unconfirmed UTXOs generated by a wallet tx","Get sum of trusted_pending and confirmed coins.","","","","","","","Return the TxOut of outpoint if it has been indexed.","Iterate over known txouts that spend to tracked script …","Finds all txouts on a transaction that has previously been …","","","","Get an unbounded spk iterator over a given keychain.","Undoes the effect of mark_used. Returns whether the index …","Unconfirmed UTXOs received from an external wallet","Iterate over revealed, but unused, spks of the given …","Iterate over revealed, but unused, spks of all keychains.","","","","Represents a failure when trying to insert/remove a …","The error type for LocalChain::apply_header_connected_to.","Occurs when the update cannot connect with the original …","Occurs when an update does not have a common checkpoint …","The ChangeSet represents changes to LocalChain.","A LocalChain checkpoint is used to find the agreement …","Iterates over checkpoints backwards.","Occurs when connected_to block conflicts with either the …","This is a local implementation of ChainOracle.","An error which occurs when a LocalChain is constructed …","Used to update LocalChain.","Apply the given changeset.","Update the chain with a given Header connecting it with …","Update the chain with a given Header at height which you …","Applies the given update to the chain.","Get the BlockId of the checkpoint.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Removes blocks from (and inclusive of) the given block_id.","","","","","","","","Extends the checkpoint linked list by a iterator of block …","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Construct a checkpoint from a list of BlockIds in …","Constructs a LocalChain from a BTreeMap of height to …","Construct a LocalChain from an initial changeset.","Construct LocalChain from genesis hash.","Construct a checkpoint from the given header and block …","Construct a LocalChain from a given checkpoint tip.","Get the genesis hash.","Get checkpoint at height.","Get checkpoint at given height (if it exists).","","Get the block hash of the checkpoint.","Get the height of the checkpoint.","The checkpoint’s height.","Derives an initial ChangeSet, meaning that it can be …","Insert a BlockId.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","Convenience method to convert the CheckPoint into an Update…","Whether the update allows for introducing older blocks.","","Iterate from this checkpoint in descending height.","Iterate over checkpoints in descending height order.","Construct a new base block at the front of a linked list.","","The original checkpoint’s block hash which cannot be …","Get the previous checkpoint in the chain","","","","","Puts another checkpoint onto the linked list representing …","Iterate checkpoints over a height range.","Iterate checkpoints over a height range.","Get the highest checkpoint.","The update chain’s new tip.","","","","","","","","","","","","","","","","","","","","The suggested checkpoint to include to connect the two …","","","","","","","","","","","","","","","","","The attempted update to the original_block hash.","","","","","","","","","Errors returned by TxGraph::calculate_fee.","A transaction that is included in the chain, or is still …","The ChangeSet represents changes to a TxGraph.","Missing TxOut for one or more of the inputs of the tx","When the transaction is invalid according to the graph it …","An iterator that traverses ancestors of a given root …","An iterator that traverses transaction descendants.","A graph of transactions and spends.","A transaction node in the TxGraph.","Get all transaction anchors known by TxGraph.","Iterate over all tx outputs known by TxGraph.","Iterates over the heights of that the new transaction …","The blocks that the transaction is “anchored” in.","Added anchors.","","Applies ChangeSet to TxGraph.","Extends this graph with another so that self becomes the …","","Get the total balance of outpoints that are in chain of …","Batch insert unconfirmed transactions.","","","","","","","","","","","","","","","Calculates the fee of a given transaction. Returns 0 if tx …","How the transaction is observed as (confirmed or …","","","","","","","","","","","","","","","","","","","Given a transaction, return an iterator of txids that …","","","","","","Get a filtered list of outputs from the given outpoints …","Get a filtered list of unspent outputs (UTXOs) from the …","Iterate over floating txouts known by TxGraph.","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Iterate over all full transactions in the graph.","Get the position of the transaction in chain with tip …","Get the txid of the spending transaction and where the …","Get a transaction by txid. This only returns Some for full …","Get a transaction node by txid. This only returns Some for …","Obtains a single tx output (if any) at the specified …","Determines the ChangeSet between self and an empty TxGraph.","Inserts the given anchor into TxGraph.","Inserts the given seen_at for txid into TxGraph.","Inserts the given transaction into TxGraph.","Inserts the given TxOut at OutPoint.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","Whether the graph has any transactions or outputs in it.","","Added last-seen unix timestamps of transactions.","The last-seen unix timestamp of the transaction as …","List graph transactions that are in chain with chain_tip.","Transform the TxGraph to have Anchors of another type.","Transform the ChangeSet to have Anchors of another type.","Find missing block heights of chain.","Returns an iterator for the anchor_heights in this …","Construct a new TxGraph from a list of transactions.","","","The transactions spending from this output.","","","","","","","","","","Get the total balance of outpoints that are in chain of …","Get a filtered list of outputs from the given outpoints …","Get a filtered list of unspent outputs (UTXOs) from the …","","","","","","","","Get the position of the transaction in chain with tip …","Get the txid of the spending transaction and where the …","","","","","","","","List graph transactions that are in chain with chain_tip.","A partial or full representation of the transaction.","The transaction node (as part of the graph).","Returns known outputs of a given txid.","Iterates over the transactions spending from txid.","Txid of the transaction.","Iterates over all outpoints contained within ChangeSet.","Added txouts.","Added transactions.","","","","","","","","Update the last seen time for all unconfirmed transactions.","","","","","","","","Creates an iterator that filters and maps ancestor …","Creates an iterator that both filters and maps conflicting …","Creates an iterator that filters and maps descendants from …"],"i":[0,0,0,0,0,0,0,0,0,0,0,8,9,0,77,0,0,78,0,0,0,0,0,8,9,78,3,17,5,6,7,6,7,40,3,0,3,8,9,5,6,7,10,13,11,3,8,9,5,6,7,10,13,11,10,3,8,9,5,6,7,10,11,3,8,9,5,6,7,10,11,8,8,9,5,6,7,10,13,6,7,17,17,8,6,7,7,3,5,6,7,11,9,5,6,7,79,8,9,5,6,7,10,3,8,9,5,6,7,10,13,3,8,9,9,5,5,5,6,7,10,13,11,80,5,6,7,77,8,9,5,6,7,5,5,3,3,3,0,3,3,3,8,9,5,6,7,10,13,11,11,77,8,9,10,40,10,10,3,3,3,0,78,0,3,0,3,13,11,11,11,11,10,3,3,8,9,5,6,7,10,3,3,3,9,5,6,7,10,3,13,13,13,3,8,9,5,6,7,10,11,3,8,9,5,6,7,10,13,11,3,8,9,5,6,7,10,13,11,0,3,10,3,3,3,8,9,5,6,7,10,13,11,9,3,3,3,8,9,5,6,7,10,13,11,78,81,82,81,0,42,0,0,41,43,43,42,43,43,43,43,43,43,41,43,41,41,41,43,41,41,41,43,41,43,41,41,41,43,41,43,42,42,41,42,43,43,43,43,43,43,41,41,42,43,41,41,43,41,43,41,43,41,43,41,0,0,0,49,50,50,47,50,50,47,47,50,47,49,50,47,49,50,47,49,50,47,49,49,50,47,49,47,49,47,49,50,47,49,49,50,47,49,49,50,50,50,50,50,50,47,49,47,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,47,49,50,50,47,49,49,49,49,49,50,47,49,50,47,49,50,50,50,50,47,49,50,50,49,50,50,50,47,49,0,0,59,0,0,0,0,59,0,0,0,54,54,54,54,61,64,61,60,54,56,62,58,59,64,61,60,54,56,62,58,59,61,60,54,56,62,58,59,61,60,54,56,62,58,59,54,61,60,54,56,62,58,59,61,61,60,54,56,56,62,62,58,58,59,59,64,61,60,54,56,62,58,59,61,54,54,54,61,54,54,61,54,54,61,61,62,54,54,64,61,60,54,56,62,58,59,64,61,61,60,54,61,54,61,64,62,61,56,62,58,59,61,61,54,54,60,61,60,54,56,62,58,59,56,62,58,59,64,61,60,54,56,62,58,59,58,64,61,60,54,56,62,58,59,64,61,60,54,56,62,58,59,62,64,61,60,54,56,62,58,59,0,0,0,68,68,0,0,0,0,44,44,48,71,48,48,44,44,44,44,44,74,75,44,71,72,68,48,74,75,44,71,72,68,48,44,72,74,74,75,75,44,71,72,48,44,71,72,48,71,72,44,48,71,48,44,44,71,72,68,48,44,44,44,44,71,72,68,68,48,74,75,44,71,72,68,48,44,44,44,44,44,44,44,44,44,44,44,74,75,44,71,72,68,48,74,75,44,48,48,71,44,44,48,44,48,44,74,75,44,71,72,68,48,44,71,72,48,68,44,44,44,74,75,44,71,72,68,48,44,44,74,75,44,71,72,68,48,44,71,72,44,44,71,48,48,48,74,75,44,71,72,68,48,44,74,75,44,71,72,68,48,44,44,44],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[[3,[[0,[1,2]]]]],4],[[],5],[5,5],[6,5],[7,5],0,0,[[]],[[[3,[[0,[1,2]]]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[[3,[1]]],[[3,[1]]]],[[[8,[1]]],[[8,[1]]]],[9,9],[5,5],[6,6],[7,7],[[[10,[1]]],[[10,[1]]]],[[[11,[1]]],[[11,[1]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[8,[[8,[1]]]],[[[8,[2]],8],12],[[9,9],12],[[5,5],12],[[6,6],12],[[7,7],12],[[[10,[2]],10],12],[13,[[15,[14]]]],0,0,[[],16],[[],16],[[[8,[17]]],[[14,[16]]]],[6,16],[7,16],0,[[],3],[[],5],[[],6],[[],7],[11],[[],[[15,[9]]]],[[],[[15,[5]]]],[[],[[15,[6]]]],[[],[[15,[7]]]],[[],18],[[[8,[19]],8],20],[[9,9],20],[[5,5],20],[[6,6],20],[[7,7],20],[[[10,[19]],10],20],[[[3,[21]],22],23],[[[8,[21]],22],23],[[9,22],23],[[5,22],23],[[6,22],23],[[7,22],23],[[[10,[21]],22],23],[[[13,[21,21]],22],23],[[]],[[]],[[[8,[7]]],9],[[]],[[],5],[[]],[[],5],[[]],[[]],[[]],[[]],[[]],[[24,5,25]],[[24,5,25],5],[[24,5,25],6],[[24,5,25],7],[[],[[15,[5]]]],[[[8,[26]]]],[9],[5],[6],[7],0,0,[[[3,[[0,[1,2]]]],27],14],[[[3,[[0,[1,2]]]],28]],[[[3,[[0,[1,2]]]],29,30]],0,[[[3,[[0,[1,2]]]]]],[[[3,[[0,[1,2]]]],[0,[1,2]],31],20],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[5,5],[[15,[[14,[20]]]]]],[8,20],[9,20],[[[10,[17]],16],20],[[],20],[[[10,[17]],16],20],0,[[[3,[[0,[1,2]]]],28],20],[[[3,[[0,[1,2]]]],28],20],[[[3,[[0,[1,2]]]]],20],0,[[],[[15,[14]]]],0,[[[3,[[0,[1,2]]]]],20],0,[[[3,[[0,[1,2]]]],28],32],[[],13],[[],11],[[],11],[11,14],[[11,25],14],0,[[[3,[[0,[1,2]]]]],33],[[[3,[[0,[1,2]]]],[34,[[0,[1,2]]]]],35],[[[8,[36]],8],[[14,[12]]]],[[9,9],[[14,[12]]]],[[5,5],[[14,[12]]]],[[6,6],[[14,[12]]]],[[7,7],[[14,[12]]]],[[[10,[36]],10],[[14,[12]]]],[[[3,[[0,[1,2]]]],28],[[33,[[0,[1,2]]]]]],[[[3,[[0,[1,2]]]],29,30],14],[[[3,[[0,[1,2]]]],28]],[9,15],[5,15],[6,15],[7,15],0,[[[3,[[0,[1,2]]]]],[[14,[27]]]],[13],[13,[[15,[14]]]],[13],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],0,[[[3,[[0,[1,2]]]],29],14],0,[[[3,[[0,[1,2]]]]],[[0,[35,37]]]],[[[3,[[0,[1,2]]]],38],35],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[18,9],[[[3,[[0,[1,2]]]]],20],[[[3,[[0,[1,2]]]]],[[0,[35,1]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],15],0,0,0,0,0,0,0,[[[41,[17,40]],[41,[17,40]]]],[[[43,[42]],24,16],41],[[[43,[42]],24,16],41],[[]],[[[43,[17,42]],[41,[17]]]],[[[43,[17,42]],[44,[17]]],[[41,[17]]]],[[[43,[17,42]],45],[[41,[17]]]],[[[43,[17,42]],45],[[41,[17]]]],[[[43,[17,42]],45],[[41,[17]]]],[[]],[[]],[[]],[[]],[[[41,[1,1]]],[[41,[1,1]]]],[[]],[[],[[43,[46]]]],[[],[[41,[46]]]],[[],[[15,[41]]]],[[[41,[19,19]],41],20],[[[43,[21,21]],22],23],[[[41,[21,21]],22],23],[[]],[47,[[41,[47]]]],[48,[[41,[46]]]],[[]],[43,44],0,0,[28],[[29,30]],0,[[]],[[[43,[17,42]]],[[41,[17]]]],[[[43,[17,42]],38,17],[[41,[17]]]],[[[43,[17,42]],38,18],[[41,[17]]]],[[[43,[17,42]],28],[[41,[17]]]],[[[43,[17,42]],29,30],[[41,[17]]]],[[]],[[]],[[[41,[17,40]]],20],[28,20],[[],43],[41,15],[[]],[[],15],[[],15],[[],15],[[],15],[[],39],[[],39],[[]],[[]],0,0,0,[[49,49],49],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],[52,[51]]]],[[[50,[[0,[1,2,21]]]]],[[4,[[0,[1,2,21]],[11,[[52,[51]]]]]]]],[[[47,[2]],[47,[2]]]],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]],[47,[[0,[1,2,21]]]]]],[47,4],[47,4],[[]],[[]],[[]],[[]],[[]],[[]],[[[50,[1]]],[[50,[1]]]],[[[47,[1]]],[[47,[1]]]],[49,49],[[]],[[]],[[]],0,[[],50],[[],47],[[],49],[[],[[15,[47]]]],[[],[[15,[49]]]],[[[47,[19]],47],20],[[49,49],20],[[[50,[21]],22],23],[[[47,[21]],22],23],[[49,22],23],[[49,22],23],[[]],[[]],[[]],0,[[[50,[[0,[1,2,21]]]],27],14],[[[50,[[0,[1,2,21]]]],28]],[[[50,[[0,[1,2,21]]]],29,30]],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]]],3],[[]],[[]],[[]],[[[47,[2]]],20],[[[50,[[0,[1,2,21]]]],28],20],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],20],[[[50,[[0,[1,2,21]]]]],35],[[[50,[[0,[1,2,21]]]],[34,[16]]],35],[[[50,[[0,[1,2,21]]]]],4],[[[50,[[0,[1,2,21]]]]],[[14,[16]]]],[[[50,[[0,[1,2,21]]]]],4],[[[50,[[0,[1,2,21]]]]],[[14,[16]]]],[[[50,[[0,[1,2,21]]]]],[[4,[[0,[1,2,21]],16]]]],[[[50,[[0,[1,2,21]]]]],16],[[[50,[[0,[1,2,21]]]],16]],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],20],[[[50,[[0,[1,2,21]]]],28],32],[16,50],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]]],33],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]],16]],[[[50,[[0,[1,2,21]]]],4]],[[[50,[[0,[1,2,21]]]]],[[0,[35,1]]]],[[[50,[[0,[1,2,21]]]]],[[0,[35,1]]]],[[[50,[[0,[1,2,21]]]],28]],[47,15],[49,15],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],[[14,[27]]]],[[]],[[]],[[]],[[],53],[49,18],0,[49,18],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[[50,[[0,[1,2,21]]]],29],14],[[[50,[[0,[1,2,21]]]]],[[0,[35,37]]]],[[[50,[[0,[1,2,21]]]],38],35],[[],39],[[],39],[[],39],[[[50,[[0,[1,2,21]]]]],[[11,[[52,[51]]]]]],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],20],0,[[[50,[[0,[1,2,21]]]]],[[0,[35,1]]]],[[[50,[[0,[1,2,21]]]]],[[0,[35,1]]]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,[[54,55],[[15,[56]]]],[[54,57,16],[[15,[55,58]]]],[[54,57,16,5],[[15,[55,59]]]],[[54,60],[[15,[55,58]]]],[61,5],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[61,61],[60,60],[54,54],[56,56],[62,62],[58,58],[59,59],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[54,5],[[15,[55,56]]]],[[61,61],20],[[60,60],20],[[54,54],20],[[56,56],20],[[62,62],20],[[58,58],20],[[59,59],20],[[61,45],[[15,[61,61]]]],[[61,22],23],[[60,22],23],[[54,22],23],[[56,22],23],[[56,22],23],[[62,22],23],[[62,22],23],[[58,22],23],[[58,22],23],[[59,22],23],[[59,22],23],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[45,[[15,[61,[14,[61]]]]]],[[[4,[16,63]]],[[15,[54,56]]]],[55,[[15,[54,56]]]],[63],[[57,16],61],[61,[[15,[54,56]]]],[54,63],[[61,16],[[14,[61]]]],[[54,16],[[14,[61]]]],[54,[[15,[5]]]],[61,63],[61,16],0,[54,55],[[54,5],[[15,[55,62]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[61],[[61,20],60],0,[[54,5,5],[[15,[[14,[20]]]]]],[61,64],[54,64],[5,61],[64,14],0,[61,[[14,[61]]]],[65],[65],[65],[65],[[61,5],[[15,[61,61]]]],[61,66],[54,66],[54,61],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],53],[[],53],[[],53],[[],53],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],0,[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,[44,33],[44,66],[48,66],0,0,[[[48,[2]],[48,[2]]]],[[[44,[[0,[1,2]]]],[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],[44,[[0,[1,2]]]]],[[48,[[0,[1,2]]]]]],[44,44],[[[44,[17]],5,45,67],49],[[[44,[[0,[1,2]]]],45],[[48,[[0,[1,2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[44,28],[[15,[18,68]]]],0,[[],[[14,[69]]]],[[],[[14,[70]]]],[[],[[14,[69]]]],[[],[[14,[70]]]],[[[44,[1]]],[[44,[1]]]],[[[71,[1,1]]],[[71,[1,1]]]],[[[72,[1,1]]],[[72,[1,1]]]],[[[48,[1]]],[[48,[1]]]],[[]],[[]],[[]],[[]],[[[71,[2,2]],71],12],[[[72,[2,2]],72],12],[[],44],[[],48],[71],[[],[[15,[48]]]],[[44,28],66],[[[44,[19]],44],20],[[[71,[19,19]],71],20],[[[72,[19,19]],72],20],[[68,68],20],[[[48,[19]],48],20],[[[44,[17]],5,45],66],[[[44,[17]],5,45],66],[44,66],[[[44,[21]],22],23],[[[71,[21,21]],22],23],[[[72,[21,21]],22],23],[[68,22],23],[[68,22],23],[[[48,[21]],22],23],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[44,66],[[[44,[17]],5,38],[[14,[8]]]],[[[44,[17]],5,29],14],[[44,38],[[14,[[73,[28]]]]]],[[44,38],[[14,[[71,[[73,[28]]]]]]]],[[44,29],[[14,[30]]]],[[[44,[[0,[1,2]]]]],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],38,[0,[1,2]]],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],38,18],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],28],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],29,30],[[48,[[0,[1,2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[44,20],[[[48,[2]]],20],0,0,[[[44,[17]],5],66],[[[44,[[0,[1,2]]]]],[[44,[[0,[1,2]]]]]],[[[48,[2]]],[[48,[2]]]],[[[44,[17]],54],66],[[48,54],66],[45,[[44,[[0,[1,2]]]]]],[74,14],[75,14],[[44,29],76],[[[71,[36,36]],71],[[14,[12]]]],[[[72,[36,36]],72],[[14,[12]]]],[65],[48,15],[[]],[[]],[[]],[[]],[[],53],[[[44,[17]],5,45,67],[[15,[49]]]],[[[44,[17]],5,45],66],[[[44,[17]],5,45],66],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[[44,[17]],5,38],[[15,[[14,[8]]]]]],[[[44,[17]],5,29],[[15,[14]]]],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[[44,[17]],5],66],0,0,[[44,38],[[14,[[4,[16,30]]]]]],[[44,38],35],0,[48,66],0,0,[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[[44,[[0,[1,2]]]],18],[[48,[[0,[1,2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[44,[[0,[1,2]]]]],[[74,[[0,[1,2]]]]]],[[44,28],75],[[[44,[[0,[1,2]]]],38],[[75,[[0,[1,2]]]]]]],"p":[[8,"Clone"],[8,"Ord"],[3,"SpkTxOutIndex"],[3,"BTreeMap"],[3,"BlockId"],[3,"ConfirmationHeightAnchor"],[3,"ConfirmationTimeHeightAnchor"],[4,"ChainPosition"],[4,"ConfirmationTime"],[3,"FullTxOut"],[3,"SpkIterator"],[4,"Ordering"],[3,"Persist"],[4,"Option"],[4,"Result"],[15,"u32"],[8,"Anchor"],[15,"u64"],[8,"PartialEq"],[15,"bool"],[8,"Debug"],[3,"Formatter"],[6,"Result"],[3,"Block"],[15,"usize"],[8,"Hash"],[3,"Script"],[3,"Transaction"],[3,"OutPoint"],[3,"TxOut"],[3,"ScriptBuf"],[15,"i64"],[3,"BTreeSet"],[8,"RangeBounds"],[8,"DoubleEndedIterator"],[8,"PartialOrd"],[8,"ExactSizeIterator"],[3,"Txid"],[3,"TypeId"],[8,"Append"],[3,"ChangeSet"],[8,"Indexer"],[3,"IndexedTxGraph"],[3,"TxGraph"],[8,"IntoIterator"],[8,"Default"],[3,"ChangeSet"],[3,"ChangeSet"],[3,"Balance"],[3,"KeychainTxOutIndex"],[4,"DescriptorPublicKey"],[4,"Descriptor"],[3,"String"],[3,"LocalChain"],[6,"ChangeSet"],[3,"MissingGenesisError"],[3,"Header"],[3,"CannotConnectError"],[4,"ApplyHeaderError"],[3,"Update"],[3,"CheckPoint"],[3,"AlterCheckPointError"],[3,"BlockHash"],[3,"CheckPointIter"],[3,"Demand"],[8,"Iterator"],[8,"FnMut"],[4,"CalculateFeeError"],[3,"Amount"],[3,"SignedAmount"],[3,"TxNode"],[3,"CanonicalTx"],[3,"Arc"],[3,"TxAncestors"],[3,"TxDescendants"],[3,"HashSet"],[8,"ChainOracle"],[8,"PersistBackend"],[8,"DescriptorExt"],[8,"AnchorFromBlockPosition"],[13,"Confirmed"],[13,"Unconfirmed"]]},\ +"bdk_chain":{"doc":"This crate is a collection of core structures for Bitcoin …","t":[8,8,8,17,3,17,8,4,3,4,3,13,13,8,16,3,2,16,3,8,3,3,2,13,13,16,11,10,11,11,11,12,12,10,11,2,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,10,11,11,11,11,11,12,12,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,10,11,12,11,11,11,0,10,0,11,2,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,12,12,12,3,16,3,8,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,10,10,12,10,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,3,4,13,3,6,3,3,13,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,4,3,3,13,13,3,3,3,3,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,12,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Anchor","AnchorFromBlockPosition","Append","BIP32_MAX_INDEX","BlockId","COINBASE_MATURITY","ChainOracle","ChainPosition","ConfirmationHeightAnchor","ConfirmationTime","ConfirmationTimeHeightAnchor","Confirmed","Confirmed","DescriptorExt","Error","FullTxOut","IndexedTxGraph","LoadError","Persist","PersistBackend","SpkIterator","SpkTxOutIndex","TxGraph","Unconfirmed","Unconfirmed","WriteError","all_spks","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","append","apply_changeset","bitcoin","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","chain_position","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cloned","cmp","cmp","cmp","cmp","cmp","cmp","commit","confirmation_height","confirmation_height","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_height_upper_bound","confirmation_time","default","default","default","default","descriptor","deserialize","deserialize","deserialize","deserialize","dust_value","eq","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from_block_position","from_block_position","from_block_position","from_block_position","get_chain_tip","hash","hash","hash","hash","hash","hash","height","index_of_spk","index_tx","index_txout","indexed_tx_graph","initial_changeset","insert_spk","into","into","into","into","into","into","into","into","into","into_iter","is_block_in_chain","is_confirmed","is_confirmed","is_confirmed_and_spendable","is_empty","is_mature","is_on_coinbase","is_relevant","is_tx_relevant","is_used","keychain","load_from_persistence","local_chain","mark_used","miniscript","net_value","new","new","new_with_range","next","nth","outpoint","outpoints","outputs_in_range","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","scan","scan_txout","sent_and_received","serialize","serialize","serialize","serialize","spent_by","spk_at_index","stage","stage_and_commit","staged","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","tx_graph","txout","txout","txouts","txouts_in_tx","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unconfirmed","unmark_used","unused_spks","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","write_changes","height","last_seen","time","ChangeSet","ChangeSet","IndexedTxGraph","Indexer","append","apply_block","apply_block_relevant","apply_changeset","apply_changeset","apply_update","batch_insert_relevant","batch_insert_relevant_unconfirmed","batch_insert_unconfirmed","borrow","borrow","borrow_mut","borrow_mut","clone","clone_into","default","default","deserialize","eq","fmt","fmt","from","from","from","from","graph","graph","index","index_tx","index_txout","indexer","initial_changeset","initial_changeset","insert_anchor","insert_seen_at","insert_tx","insert_txout","into","into","is_empty","is_tx_relevant","new","serialize","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","Balance","ChangeSet","KeychainTxOutIndex","add","add_keychain","all_unbounded_spk_iters","append","apply_changeset","apply_changeset","as_inner","as_ref","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","confirmed","default","default","default","deserialize","deserialize","eq","eq","fmt","fmt","fmt","fmt","from","from","from","immature","index_of_spk","index_tx","index_txout","initial_changeset","inner","into","into","into","is_empty","is_tx_relevant","is_used","keychain_outpoints","keychain_outpoints_in_range","keychains","last_revealed_index","last_revealed_indices","last_used_index","last_used_indices","lookahead","lookahead_to_target","mark_used","net_value","new","next_index","next_unused_spk","outpoints","reveal_next_spk","reveal_to_target","reveal_to_target_multi","revealed_keychain_spks","revealed_spks","sent_and_received","serialize","serialize","spk_at_index","to_owned","to_owned","to_owned","to_string","total","trusted_pending","trusted_spendable","try_from","try_from","try_from","try_into","try_into","try_into","txout","txouts","txouts_in_tx","type_id","type_id","type_id","unbounded_spk_iter","unmark_used","untrusted_pending","unused_keychain_spks","unused_spks","vzip","vzip","vzip","AlterCheckPointError","ApplyHeaderError","CannotConnect","CannotConnectError","ChangeSet","CheckPoint","CheckPointIter","InconsistentBlocks","LocalChain","MissingGenesisError","Update","apply_changeset","apply_header","apply_header_connected_to","apply_update","block_id","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","disconnect_from","eq","eq","eq","eq","eq","eq","eq","extend","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from_block_ids","from_blocks","from_changeset","from_genesis_hash","from_header","from_tip","genesis_hash","get","get","get_chain_tip","hash","height","height","initial_changeset","insert_block","into","into","into","into","into","into","into","into","into_iter","into_iter","into_update","introduce_older_blocks","is_block_in_chain","iter","iter_checkpoints","new","next","original_hash","prev","provide","provide","provide","provide","push","range","range","tip","tip","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_include_height","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","update_hash","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","CalculateFeeError","CanonicalTx","ChangeSet","MissingTxOut","NegativeFee","TxAncestors","TxDescendants","TxGraph","TxNode","all_anchors","all_txouts","anchor_heights","anchors","anchors","append","apply_changeset","apply_update","as_ref","balance","batch_insert_unconfirmed","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","calculate_fee","chain_position","checked_sum","checked_sum","checked_sum","checked_sum","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","cmp","default","default","deref","deserialize","direct_conflicts","eq","eq","eq","eq","eq","filter_chain_txouts","filter_chain_unspents","floating_txouts","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","full_txs","get_chain_position","get_chain_spend","get_tx","get_tx_node","get_txout","initial_changeset","insert_anchor","insert_seen_at","insert_tx","insert_txout","into","into","into","into","into","into","into","into_iter","into_iter","is_empty","is_empty","last_seen","last_seen_unconfirmed","list_chain_txs","map_anchors","map_anchors","missing_heights","missing_heights_from","new","next","next","outspends","partial_cmp","partial_cmp","provide","serialize","to_owned","to_owned","to_owned","to_owned","to_string","try_balance","try_filter_chain_txouts","try_filter_chain_unspents","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_get_chain_position","try_get_chain_spend","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_list_chain_txs","tx","tx_node","tx_outputs","tx_spends","txid","txouts","txouts","txs","type_id","type_id","type_id","type_id","type_id","type_id","type_id","update_last_seen_unconfirmed","vzip","vzip","vzip","vzip","vzip","vzip","vzip","walk_ancestors","walk_conflicts","walk_descendants"],"q":["bdk_chain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::ConfirmationTime","","","bdk_chain::indexed_tx_graph","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::keychain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::local_chain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk_chain::tx_graph","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Trait that “anchors” blockchain data to a specific …","An Anchor that can be constructed from a given block, …","Trait that makes an object appendable.","Maximum BIP32 derivation index.","A reference to a block in the canonical chain.","How many confirmations are needed f or a coinbase output …","Represents a service that tracks the blockchain.","Represents the observed position of some chain data.","An Anchor implementation that also records the exact …","Block height and timestamp at which a transaction is …","An Anchor implementation that also records the exact …","The chain data is seen as confirmed, and in anchored by A.","The transaction is confirmed","A trait to extend the functionality of a miniscript …","Error type.","A TxOut with as much data as we can retrieve about it","","The error the backend returns when it fails to load …","Persist wraps a PersistBackend (B) to create a convenient …","A persistence backend for Persist.","An iterator for derived script pubkeys.","An index storing TxOuts that have a script pubkey that …","","The chain data is not confirmed and last seen in the …","The transaction is unconfirmed","The error the backend returns when it fails to write.","The script pubkeys that are being tracked by the index.","Returns the BlockId that the associated blockchain data is …","","","","The anchor block.","The anchor block.","Append another object of the same type onto self.","","","","","","","","","","","","","","","","","","","","","The position of the transaction in outpoint in the overall …","","","","","","","","","","","","","","","","","Maps a ChainPosition<&A> into a ChainPosition<A> by …","","","","","","","Commit the staged changes to the underlying persistence …","The exact confirmation height of the transaction.","The confirmation height of the transaction being anchored.","Get the upper bound of the chain data’s confirmation …","Get the upper bound of the chain data’s confirmation …","Determines the upper bound of the confirmation height.","","","The confirmation time of the transaction being anchored.","","","","","Get a reference to the internal descriptor.","","","","","Returns the minimum value (in satoshis) at which an output …","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Construct the anchor from a given block, block height and …","","","","Get the best chain’s chain tip.","","","","","","The hash of the block.","The height of the block.","Returns the index associated with the script pubkey.","","","Contains the IndexedTxGraph and associated types. Refer to …","","Adds a script pubkey to scan for. Returns false and does …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","Determines whether block of BlockId exists as an ancestor …","Returns whether ChainPosition is confirmed or not.","Returns whether ConfirmationTime is the confirmed variant.","Whether the utxo is/was/will be spendable with chain tip.","Returns whether the structure is considered empty.","Whether the txout is considered mature.","Whether this output is on a coinbase transaction.","Whether any of the inputs of this transaction spend a …","","Returns whether the script pubkey at index has been used …","Module for keychain related structures.","Return the aggregate changeset C from persistence.","The LocalChain is a local implementation of ChainOracle.","Marks the script pubkey at index as used even though it …","","Computes the net value transfer effect of tx on the script …","Create a new Persist from PersistBackend.","Create a new script pubkey iterator from descriptor.","Create a new script pubkey iterator from descriptor and a …","","","The location of the TxOut.","Get a reference to the set of indexed outpoints.","Iterates over all the outputs with script pubkeys in an …","","","","","","","Scans a transaction’s outputs for matching script …","Scan a single TxOut for a matching script pubkey and …","Computes the total value transfer effect tx has on the …","","","","","The txid and chain position of the transaction (if any) …","Returns the script that has been inserted at the index.","Stage a changeset to be committed later with commit.","Stages a new changeset and commits it (along with any …","Get the changes that have not been committed yet.","","","","","","","","","","","","","","","","","","","","","","","","","","","Module for structures that store and traverse transactions.","Returns the txout and script pubkey index of the TxOut at …","The TxOut.","Iterate over all known txouts that spend to tracked script …","Finds all txouts on a transaction that has previously been …","","","","","","","","","","Construct an unconfirmed variant using the given last_seen …","Undoes the effect of mark_used. Returns whether the index …","Iterates over all unused script pubkeys in an index range.","","","","","","","","","","Writes a changeset to the persistence backend.","Confirmation height.","The last-seen timestamp in unix seconds.","Confirmation time in unix seconds.","Represents changes to an IndexedTxGraph.","The resultant “changeset” when new transaction data is …","The IndexedTxGraph combines a TxGraph and an Indexer …","Utilities for indexing transaction data.","","Batch insert all transactions of the given block of height.","Batch insert all transactions of the given block of height…","Apply changeset to itself.","Applies the ChangeSet to the IndexedTxGraph.","Apply an update directly.","Batch insert transactions, filtering out those that are …","Batch insert unconfirmed transactions, filtering out those …","Batch insert unconfirmed transactions.","","","","","","","","","","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","Get a reference of the internal transaction graph.","TxGraph changeset.","Transaction index.","Scans a transaction for relevant outpoints, which are …","Scan and index the given outpoint and txout.","Indexer changeset.","Determines the ChangeSet between self and an empty Indexer.","Determines the ChangeSet between self and an empty …","Insert an anchor for a given transaction.","Insert a unix timestamp of when a transaction is seen in …","Insert and index a transaction into the graph.","Insert a floating txout of given outpoint.","Calls U::from(self).","Calls U::from(self).","","Determines whether the transaction should be included in …","Construct a new IndexedTxGraph with a given index.","","","","","","","","","","","Balance, differentiated into various categories.","Represents updates to the derivation index of a …","KeychainTxOutIndex controls how script pubkeys are …","","Add a keychain to the tracker’s txout_index with a …","Get unbounded spk iterators for all keychains.","Append another ChangeSet into self.","","Applies the derivation changeset to the KeychainTxOutIndex…","Get the inner map of the keychain to its new derivation …","","","","","","","","","","","","","","Confirmed and immediately spendable balance","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","All coinbase outputs not yet matured","Returns the keychain and keychain index associated with …","","","","Return a reference to the internal SpkTxOutIndex.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Returns whether the changeset are empty.","","Returns whether the spk under the keychain’s index has …","Iterate over all OutPoints that have TxOuts with script …","Iterate over OutPoints that have script pubkeys derived …","Return a reference to the internal map of keychain to …","Get the last derivation index revealed for keychain.","Get the last derivation index that is revealed for each …","Returns the highest derivation index of the keychain where …","Returns the highest derivation index of each keychain that …","Get the lookahead setting.","Store lookahead scripts until target_index (inclusive).","Marks the script pubkey at index as used even though the …","Computes the net value that this transaction gives to the …","Construct a KeychainTxOutIndex with the given lookahead.","Get the next derivation index for keychain. The next index …","Gets the next unused script pubkey in the keychain. I.e., …","Get a reference to the set of indexed outpoints.","Attempts to reveal the next script pubkey for keychain.","Reveals script pubkeys of the keychain’s descriptor up …","Convenience method to call Self::reveal_to_target on …","Iterate over revealed spks of the given keychain.","Iterate over revealed spks of keychains in range","Computes the total value transfer effect tx has on the …","","","Return the script that exists under the given keychain’s …","","","","","Get the whole balance visible to the wallet.","Unconfirmed UTXOs generated by a wallet tx","Get sum of trusted_pending and confirmed coins.","","","","","","","Return the TxOut of outpoint if it has been indexed.","Iterate over known txouts that spend to tracked script …","Finds all txouts on a transaction that has previously been …","","","","Get an unbounded spk iterator over a given keychain.","Undoes the effect of mark_used. Returns whether the index …","Unconfirmed UTXOs received from an external wallet","Iterate over revealed, but unused, spks of the given …","Iterate over revealed, but unused, spks of all keychains.","","","","Represents a failure when trying to insert/remove a …","The error type for LocalChain::apply_header_connected_to.","Occurs when the update cannot connect with the original …","Occurs when an update does not have a common checkpoint …","The ChangeSet represents changes to LocalChain.","A LocalChain checkpoint is used to find the agreement …","Iterates over checkpoints backwards.","Occurs when connected_to block conflicts with either the …","This is a local implementation of ChainOracle.","An error which occurs when a LocalChain is constructed …","Used to update LocalChain.","Apply the given changeset.","Update the chain with a given Header connecting it with …","Update the chain with a given Header at height which you …","Applies the given update to the chain.","Get the BlockId of the checkpoint.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Removes blocks from (and inclusive of) the given block_id.","","","","","","","","Extends the checkpoint linked list by a iterator of block …","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Construct a checkpoint from a list of BlockIds in …","Constructs a LocalChain from a BTreeMap of height to …","Construct a LocalChain from an initial changeset.","Construct LocalChain from genesis hash.","Construct a checkpoint from the given header and block …","Construct a LocalChain from a given checkpoint tip.","Get the genesis hash.","Get checkpoint at height.","Get checkpoint at given height (if it exists).","","Get the block hash of the checkpoint.","Get the height of the checkpoint.","The checkpoint’s height.","Derives an initial ChangeSet, meaning that it can be …","Insert a BlockId.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","Convenience method to convert the CheckPoint into an Update…","Whether the update allows for introducing older blocks.","","Iterate from this checkpoint in descending height.","Iterate over checkpoints in descending height order.","Construct a new base block at the front of a linked list.","","The original checkpoint’s block hash which cannot be …","Get the previous checkpoint in the chain","","","","","Puts another checkpoint onto the linked list representing …","Iterate checkpoints over a height range.","Iterate checkpoints over a height range.","Get the highest checkpoint.","The update chain’s new tip.","","","","","","","","","","","","","","","","","","","","The suggested checkpoint to include to connect the two …","","","","","","","","","","","","","","","","","The attempted update to the original_block hash.","","","","","","","","","Errors returned by TxGraph::calculate_fee.","A transaction that is included in the chain, or is still …","The ChangeSet represents changes to a TxGraph.","Missing TxOut for one or more of the inputs of the tx","When the transaction is invalid according to the graph it …","An iterator that traverses ancestors of a given root …","An iterator that traverses transaction descendants.","A graph of transactions and spends.","A transaction node in the TxGraph.","Get all transaction anchors known by TxGraph.","Iterate over all tx outputs known by TxGraph.","Iterates over the heights of that the new transaction …","The blocks that the transaction is “anchored” in.","Added anchors.","","Applies ChangeSet to TxGraph.","Extends this graph with another so that self becomes the …","","Get the total balance of outpoints that are in chain of …","Batch insert unconfirmed transactions.","","","","","","","","","","","","","","","Calculates the fee of a given transaction. Returns 0 if tx …","How the transaction is observed as (confirmed or …","","","","","","","","","","","","","","","","","","","Given a transaction, return an iterator of txids that …","","","","","","Get a filtered list of outputs from the given outpoints …","Get a filtered list of unspent outputs (UTXOs) from the …","Iterate over floating txouts known by TxGraph.","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Iterate over all full transactions in the graph.","Get the position of the transaction in chain with tip …","Get the txid of the spending transaction and where the …","Get a transaction by txid. This only returns Some for full …","Get a transaction node by txid. This only returns Some for …","Obtains a single tx output (if any) at the specified …","Determines the ChangeSet between self and an empty TxGraph.","Inserts the given anchor into TxGraph.","Inserts the given seen_at for txid into TxGraph.","Inserts the given transaction into TxGraph.","Inserts the given TxOut at OutPoint.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","Whether the graph has any transactions or outputs in it.","","Added last-seen unix timestamps of transactions.","The last-seen unix timestamp of the transaction as …","List graph transactions that are in chain with chain_tip.","Transform the TxGraph to have Anchors of another type.","Transform the ChangeSet to have Anchors of another type.","Find missing block heights of chain.","Returns an iterator for the anchor_heights in this …","Construct a new TxGraph from a list of transactions.","","","The transactions spending from this output.","","","","","","","","","","Get the total balance of outpoints that are in chain of …","Get a filtered list of outputs from the given outpoints …","Get a filtered list of unspent outputs (UTXOs) from the …","","","","","","","","Get the position of the transaction in chain with tip …","Get the txid of the spending transaction and where the …","","","","","","","","List graph transactions that are in chain with chain_tip.","A partial or full representation of the transaction.","The transaction node (as part of the graph).","Returns known outputs of a given txid.","Iterates over the transactions spending from txid.","Txid of the transaction.","Iterates over all outpoints contained within ChangeSet.","Added txouts.","Added transactions.","","","","","","","","Update the last seen time for all unconfirmed transactions.","","","","","","","","Creates an iterator that filters and maps ancestor …","Creates an iterator that both filters and maps conflicting …","Creates an iterator that filters and maps descendants from …"],"i":[0,0,0,0,0,0,0,0,0,0,0,8,9,0,77,0,0,78,0,0,0,0,0,8,9,78,3,17,5,6,7,6,7,40,3,0,3,8,9,5,6,7,10,13,11,3,8,9,5,6,7,10,13,11,10,3,8,9,5,6,7,10,11,3,8,9,5,6,7,10,11,8,8,9,5,6,7,10,13,6,7,17,17,8,6,7,7,3,5,6,7,11,9,5,6,7,79,8,9,5,6,7,10,3,8,9,5,6,7,10,13,3,8,9,9,5,5,5,6,7,10,13,11,80,5,6,7,77,8,9,5,6,7,5,5,3,3,3,0,3,3,3,8,9,5,6,7,10,13,11,11,77,8,9,10,40,10,10,3,3,3,0,78,0,3,0,3,13,11,11,11,11,10,3,3,8,9,5,6,7,10,3,3,3,9,5,6,7,10,3,13,13,13,3,8,9,5,6,7,10,11,3,8,9,5,6,7,10,13,11,3,8,9,5,6,7,10,13,11,0,3,10,3,3,3,8,9,5,6,7,10,13,11,9,3,3,3,8,9,5,6,7,10,13,11,78,81,82,81,0,42,0,0,41,43,43,42,43,43,43,43,43,43,41,43,41,41,41,43,41,41,41,43,41,43,41,41,41,43,41,43,42,42,41,42,43,43,43,43,43,43,41,41,42,43,41,41,43,41,43,41,43,41,43,41,0,0,0,49,50,50,47,50,50,47,47,50,47,49,50,47,49,50,47,49,50,47,49,49,50,47,49,47,49,47,49,50,47,49,49,50,47,49,49,50,50,50,50,50,50,47,49,47,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,47,49,50,50,47,49,49,49,49,49,50,47,49,50,47,49,50,50,50,50,47,49,50,50,49,50,50,50,47,49,0,0,59,0,0,0,0,59,0,0,0,54,54,54,54,61,64,61,60,54,56,62,58,59,64,61,60,54,56,62,58,59,61,60,54,56,62,58,59,61,60,54,56,62,58,59,54,61,60,54,56,62,58,59,61,61,60,54,56,56,62,62,58,58,59,59,64,61,60,54,56,62,58,59,61,54,54,54,61,54,54,61,54,54,61,61,62,54,54,64,61,60,54,56,62,58,59,64,61,61,60,54,61,54,61,64,62,61,56,62,58,59,61,61,54,54,60,61,60,54,56,62,58,59,56,62,58,59,64,61,60,54,56,62,58,59,58,64,61,60,54,56,62,58,59,64,61,60,54,56,62,58,59,62,64,61,60,54,56,62,58,59,0,0,0,68,68,0,0,0,0,44,44,48,71,48,48,44,44,44,44,44,74,75,44,71,72,68,48,74,75,44,71,72,68,48,44,72,74,74,75,75,44,71,72,48,44,71,72,48,71,72,44,48,71,48,44,44,71,72,68,48,44,44,44,44,71,72,68,68,48,74,75,44,71,72,68,48,44,44,44,44,44,44,44,44,44,44,44,74,75,44,71,72,68,48,74,75,44,48,48,71,44,44,48,44,48,44,74,75,44,71,72,68,48,44,71,72,48,68,44,44,44,74,75,44,71,72,68,48,44,44,74,75,44,71,72,68,48,44,71,72,44,44,71,48,48,48,74,75,44,71,72,68,48,44,74,75,44,71,72,68,48,44,44,44],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[[3,[[0,[1,2]]]]],4],[[],5],[5,5],[6,5],[7,5],0,0,[[]],[[[3,[[0,[1,2]]]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[[3,[1]]],[[3,[1]]]],[[[8,[1]]],[[8,[1]]]],[9,9],[5,5],[6,6],[7,7],[[[10,[1]]],[[10,[1]]]],[[[11,[1]]],[[11,[1]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[8,[[8,[1]]]],[[[8,[2]],8],12],[[9,9],12],[[5,5],12],[[6,6],12],[[7,7],12],[[[10,[2]],10],12],[13,[[15,[14]]]],0,0,[[],16],[[],16],[[[8,[17]]],[[14,[16]]]],[6,16],[7,16],0,[[],3],[[],5],[[],6],[[],7],[11],[[],[[15,[9]]]],[[],[[15,[5]]]],[[],[[15,[6]]]],[[],[[15,[7]]]],[[],18],[[[8,[19]],8],20],[[9,9],20],[[5,5],20],[[6,6],20],[[7,7],20],[[[10,[19]],10],20],[[[3,[21]],22],23],[[[8,[21]],22],23],[[9,22],23],[[5,22],23],[[6,22],23],[[7,22],23],[[[10,[21]],22],23],[[[13,[21,21]],22],23],[[]],[[]],[[[8,[7]]],9],[[]],[[],5],[[]],[[],5],[[]],[[]],[[]],[[]],[[]],[[24,5,25]],[[24,5,25],5],[[24,5,25],6],[[24,5,25],7],[[],[[15,[5]]]],[[[8,[26]]]],[9],[5],[6],[7],0,0,[[[3,[[0,[1,2]]]],27],14],[[[3,[[0,[1,2]]]],28]],[[[3,[[0,[1,2]]]],29,30]],0,[[[3,[[0,[1,2]]]]]],[[[3,[[0,[1,2]]]],[0,[1,2]],31],20],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[5,5],[[15,[[14,[20]]]]]],[8,20],[9,20],[[[10,[17]],16],20],[[],20],[[[10,[17]],16],20],0,[[[3,[[0,[1,2]]]],28],20],[[[3,[[0,[1,2]]]],28],20],[[[3,[[0,[1,2]]]]],20],0,[[],[[15,[14]]]],0,[[[3,[[0,[1,2]]]]],20],0,[[[3,[[0,[1,2]]]],28,[32,[[0,[1,2]]]]],33],[[],13],[[],11],[[],11],[11,14],[[11,25],14],0,[[[3,[[0,[1,2]]]]],34],[[[3,[[0,[1,2]]]],[32,[[0,[1,2]]]]],35],[[[8,[36]],8],[[14,[12]]]],[[9,9],[[14,[12]]]],[[5,5],[[14,[12]]]],[[6,6],[[14,[12]]]],[[7,7],[[14,[12]]]],[[[10,[36]],10],[[14,[12]]]],[[[3,[[0,[1,2]]]],28],[[34,[[0,[1,2]]]]]],[[[3,[[0,[1,2]]]],29,30],14],[[[3,[[0,[1,2]]]],28,[32,[[0,[1,2]]]]]],[9,15],[5,15],[6,15],[7,15],0,[[[3,[[0,[1,2]]]]],[[14,[27]]]],[13],[13,[[15,[14]]]],[13],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],0,[[[3,[[0,[1,2]]]],29],14],0,[[[3,[[0,[1,2]]]]],[[0,[35,37]]]],[[[3,[[0,[1,2]]]],38],35],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[18,9],[[[3,[[0,[1,2]]]]],20],[[[3,[[0,[1,2]]]]],[[0,[35,1]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],15],0,0,0,0,0,0,0,[[[41,[17,40]],[41,[17,40]]]],[[[43,[42]],24,16],41],[[[43,[42]],24,16],41],[[]],[[[43,[17,42]],[41,[17]]]],[[[43,[17,42]],[44,[17]]],[[41,[17]]]],[[[43,[17,42]],45],[[41,[17]]]],[[[43,[17,42]],45],[[41,[17]]]],[[[43,[17,42]],45],[[41,[17]]]],[[]],[[]],[[]],[[]],[[[41,[1,1]]],[[41,[1,1]]]],[[]],[[],[[43,[46]]]],[[],[[41,[46]]]],[[],[[15,[41]]]],[[[41,[19,19]],41],20],[[[43,[21,21]],22],23],[[[41,[21,21]],22],23],[[]],[47,[[41,[47]]]],[48,[[41,[46]]]],[[]],[43,44],0,0,[28],[[29,30]],0,[[]],[[[43,[17,42]]],[[41,[17]]]],[[[43,[17,42]],38,17],[[41,[17]]]],[[[43,[17,42]],38,18],[[41,[17]]]],[[[43,[17,42]],28],[[41,[17]]]],[[[43,[17,42]],29,30],[[41,[17]]]],[[]],[[]],[[[41,[17,40]]],20],[28,20],[[],43],[41,15],[[]],[[],15],[[],15],[[],15],[[],15],[[],39],[[],39],[[]],[[]],0,0,0,[[49,49],49],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],[52,[51]]]],[[[50,[[0,[1,2,21]]]]],[[4,[[0,[1,2,21]],[11,[[52,[51]]]]]]]],[[[47,[2]],[47,[2]]]],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]],[47,[[0,[1,2,21]]]]]],[47,4],[47,4],[[]],[[]],[[]],[[]],[[]],[[]],[[[50,[1]]],[[50,[1]]]],[[[47,[1]]],[[47,[1]]]],[49,49],[[]],[[]],[[]],0,[[],50],[[],47],[[],49],[[],[[15,[47]]]],[[],[[15,[49]]]],[[[47,[19]],47],20],[[49,49],20],[[[50,[21]],22],23],[[[47,[21]],22],23],[[49,22],23],[[49,22],23],[[]],[[]],[[]],0,[[[50,[[0,[1,2,21]]]],27],14],[[[50,[[0,[1,2,21]]]],28]],[[[50,[[0,[1,2,21]]]],29,30]],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]]],3],[[]],[[]],[[]],[[[47,[2]]],20],[[[50,[[0,[1,2,21]]]],28],20],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],20],[[[50,[[0,[1,2,21]]]]],35],[[[50,[[0,[1,2,21]]]],[32,[[0,[1,2,21]]]]],35],[[[50,[[0,[1,2,21]]]]],4],[[[50,[[0,[1,2,21]]]]],[[14,[16]]]],[[[50,[[0,[1,2,21]]]]],4],[[[50,[[0,[1,2,21]]]]],[[14,[16]]]],[[[50,[[0,[1,2,21]]]]],[[4,[[0,[1,2,21]],16]]]],[[[50,[[0,[1,2,21]]]]],16],[[[50,[[0,[1,2,21]]]],16]],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],20],[[[50,[[0,[1,2,21]]]],28,[32,[[0,[1,2,21]]]]],33],[16,50],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]]],34],[[[50,[[0,[1,2,21]]]]]],[[[50,[[0,[1,2,21]]]],16]],[[[50,[[0,[1,2,21]]]],4]],[[[50,[[0,[1,2,21]]]]],35],[[[50,[[0,[1,2,21]]]],[32,[[0,[1,2,21]]]]],[[0,[35,1]]]],[[[50,[[0,[1,2,21]]]],28,[32,[[0,[1,2,21]]]]]],[47,15],[49,15],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],[[14,[27]]]],[[]],[[]],[[]],[[],53],[49,18],0,[49,18],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[[50,[[0,[1,2,21]]]],29],14],[[[50,[[0,[1,2,21]]]]],[[0,[35,37]]]],[[[50,[[0,[1,2,21]]]],38],35],[[],39],[[],39],[[],39],[[[50,[[0,[1,2,21]]]]],[[11,[[52,[51]]]]]],[[[50,[[0,[1,2,21]]]],[0,[1,2,21]],16],20],0,[[[50,[[0,[1,2,21]]]]],[[0,[35,1]]]],[[[50,[[0,[1,2,21]]]]],[[0,[35,1]]]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,[[54,55],[[15,[56]]]],[[54,57,16],[[15,[55,58]]]],[[54,57,16,5],[[15,[55,59]]]],[[54,60],[[15,[55,58]]]],[61,5],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[61,61],[60,60],[54,54],[56,56],[62,62],[58,58],[59,59],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[54,5],[[15,[55,56]]]],[[61,61],20],[[60,60],20],[[54,54],20],[[56,56],20],[[62,62],20],[[58,58],20],[[59,59],20],[[61,45],[[15,[61,61]]]],[[61,22],23],[[60,22],23],[[54,22],23],[[56,22],23],[[56,22],23],[[62,22],23],[[62,22],23],[[58,22],23],[[58,22],23],[[59,22],23],[[59,22],23],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[45,[[15,[61,[14,[61]]]]]],[[[4,[16,63]]],[[15,[54,56]]]],[55,[[15,[54,56]]]],[63],[[57,16],61],[61,[[15,[54,56]]]],[54,63],[[61,16],[[14,[61]]]],[[54,16],[[14,[61]]]],[54,[[15,[5]]]],[61,63],[61,16],0,[54,55],[[54,5],[[15,[55,62]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[61],[[61,20],60],0,[[54,5,5],[[15,[[14,[20]]]]]],[61,64],[54,64],[5,61],[64,14],0,[61,[[14,[61]]]],[65],[65],[65],[65],[[61,5],[[15,[61,61]]]],[61,66],[54,66],[54,61],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],53],[[],53],[[],53],[[],53],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],0,[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,[44,34],[44,66],[48,66],0,0,[[[48,[2]],[48,[2]]]],[[[44,[[0,[1,2]]]],[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],[44,[[0,[1,2]]]]],[[48,[[0,[1,2]]]]]],[44,44],[[[44,[17]],5,45,67],49],[[[44,[[0,[1,2]]]],45],[[48,[[0,[1,2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[44,28],[[15,[18,68]]]],0,[[],[[14,[69]]]],[[],[[14,[70]]]],[[],[[14,[69]]]],[[],[[14,[70]]]],[[[44,[1]]],[[44,[1]]]],[[[71,[1,1]]],[[71,[1,1]]]],[[[72,[1,1]]],[[72,[1,1]]]],[[[48,[1]]],[[48,[1]]]],[[]],[[]],[[]],[[]],[[[71,[2,2]],71],12],[[[72,[2,2]],72],12],[[],44],[[],48],[71],[[],[[15,[48]]]],[[44,28],66],[[[44,[19]],44],20],[[[71,[19,19]],71],20],[[[72,[19,19]],72],20],[[68,68],20],[[[48,[19]],48],20],[[[44,[17]],5,45],66],[[[44,[17]],5,45],66],[44,66],[[[44,[21]],22],23],[[[71,[21,21]],22],23],[[[72,[21,21]],22],23],[[68,22],23],[[68,22],23],[[[48,[21]],22],23],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[44,66],[[[44,[17]],5,38],[[14,[8]]]],[[[44,[17]],5,29],14],[[44,38],[[14,[[73,[28]]]]]],[[44,38],[[14,[[71,[[73,[28]]]]]]]],[[44,29],[[14,[30]]]],[[[44,[[0,[1,2]]]]],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],38,[0,[1,2]]],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],38,18],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],28],[[48,[[0,[1,2]]]]]],[[[44,[[0,[1,2]]]],29,30],[[48,[[0,[1,2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[44,20],[[[48,[2]]],20],0,0,[[[44,[17]],5],66],[[[44,[[0,[1,2]]]]],[[44,[[0,[1,2]]]]]],[[[48,[2]]],[[48,[2]]]],[[[44,[17]],54],66],[[48,54],66],[45,[[44,[[0,[1,2]]]]]],[74,14],[75,14],[[44,29],76],[[[71,[36,36]],71],[[14,[12]]]],[[[72,[36,36]],72],[[14,[12]]]],[65],[48,15],[[]],[[]],[[]],[[]],[[],53],[[[44,[17]],5,45,67],[[15,[49]]]],[[[44,[17]],5,45],66],[[[44,[17]],5,45],66],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[[44,[17]],5,38],[[15,[[14,[8]]]]]],[[[44,[17]],5,29],[[15,[14]]]],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[[44,[17]],5],66],0,0,[[44,38],[[14,[[4,[16,30]]]]]],[[44,38],35],0,[48,66],0,0,[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[[44,[[0,[1,2]]]],18],[[48,[[0,[1,2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[44,[[0,[1,2]]]]],[[74,[[0,[1,2]]]]]],[[44,28],75],[[[44,[[0,[1,2]]]],38],[[75,[[0,[1,2]]]]]]],"p":[[8,"Clone"],[8,"Ord"],[3,"SpkTxOutIndex"],[3,"BTreeMap"],[3,"BlockId"],[3,"ConfirmationHeightAnchor"],[3,"ConfirmationTimeHeightAnchor"],[4,"ChainPosition"],[4,"ConfirmationTime"],[3,"FullTxOut"],[3,"SpkIterator"],[4,"Ordering"],[3,"Persist"],[4,"Option"],[4,"Result"],[15,"u32"],[8,"Anchor"],[15,"u64"],[8,"PartialEq"],[15,"bool"],[8,"Debug"],[3,"Formatter"],[6,"Result"],[3,"Block"],[15,"usize"],[8,"Hash"],[3,"Script"],[3,"Transaction"],[3,"OutPoint"],[3,"TxOut"],[3,"ScriptBuf"],[8,"RangeBounds"],[15,"i64"],[3,"BTreeSet"],[8,"DoubleEndedIterator"],[8,"PartialOrd"],[8,"ExactSizeIterator"],[3,"Txid"],[3,"TypeId"],[8,"Append"],[3,"ChangeSet"],[8,"Indexer"],[3,"IndexedTxGraph"],[3,"TxGraph"],[8,"IntoIterator"],[8,"Default"],[3,"ChangeSet"],[3,"ChangeSet"],[3,"Balance"],[3,"KeychainTxOutIndex"],[4,"DescriptorPublicKey"],[4,"Descriptor"],[3,"String"],[3,"LocalChain"],[6,"ChangeSet"],[3,"MissingGenesisError"],[3,"Header"],[3,"CannotConnectError"],[4,"ApplyHeaderError"],[3,"Update"],[3,"CheckPoint"],[3,"AlterCheckPointError"],[3,"BlockHash"],[3,"CheckPointIter"],[3,"Demand"],[8,"Iterator"],[8,"FnMut"],[4,"CalculateFeeError"],[3,"SignedAmount"],[3,"Amount"],[3,"TxNode"],[3,"CanonicalTx"],[3,"Arc"],[3,"TxAncestors"],[3,"TxDescendants"],[3,"HashSet"],[8,"ChainOracle"],[8,"PersistBackend"],[8,"DescriptorExt"],[8,"AnchorFromBlockPosition"],[13,"Confirmed"],[13,"Unconfirmed"]]},\ "bdk_coin_select":{"doc":"","t":[3,3,4,4,3,3,13,6,13,3,4,13,13,13,3,4,3,13,13,17,13,13,13,13,13,3,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11,11,11,12,11,12,11,11,11,11,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,12,12,12,12,11,11,11,11,12,11,12,12,11,12,12,12,11,11,11,11,12,11,11,11,11,11,11,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,11],"n":["Bnb","BnbIter","BnbLimit","BranchStrategy","CoinSelector","CoinSelectorOpt","Continue","DecideStrategy","Duration","ExcessStrategy","ExcessStrategyKind","MinAbsoluteFee","MinDrainValue","Rounds","Selection","SelectionConstraint","SelectionError","SkipBoth","SkipInclusion","TXIN_BASE_WEIGHT","TargetFee","TargetValue","ToDrain","ToFee","ToRecipient","WeightedValue","advertise_new_score","all_selected","apply_selection","backtrack","base_weight","best_score","best_strategy","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","candidate","candidates","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","coin_select_bnb","current_excess","current_weight","deselect","drain_value","drain_waste","drain_weight","effective_target","effective_value","eq","eq","excess","excess_strategies","fee","feerate","finish","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","forward","from","from","from","from","from","from","from","from","from","from","from","from","from","from","fund_outputs","hash","input_count","into","into","into","into","into","into","into","into","into","into","into","into","into_iter","into_iter","is_empty","is_segwit","is_selected","long_term_feerate","long_term_feerate","max_extra_target","min_absolute_fee","min_drain_value","new","new","new","next","opts","partial_cmp","pool","pool_pos","provide","recipient_value","rem_abs","rem_eff","select","select_all","select_until_finished","selected","selected","selected_absolute_value","selected_count","selected_effective_value","selected_indexes","selected_waste","selected_weight","selection","spend_drain_weight","target_feerate","target_value","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unselected","unselected_indexes","value","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","waste","weight","weight","will_continue"],"q":["bdk_coin_select","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Bnb represents the current state of the BnB algorithm.","","Determines how we should limit rounds of branch and bound.","Strategy in which we should branch.","CoinSelector selects and deselects from a set of …","","We continue exploring subtrees of this node, starting with …","Closure to decide the branching strategy, alongside a …","","","","Min absolute fee is not met","Min drain value is not met","","","","","We skip both the inclusion and omission branches of this …","We continue exploring ONLY the omission branch of this …","Txin “base” fields include outpoint (32+4) and …","The target fee (given the feerate) is not met","The target is not met","","","","A WeightedValue represents an input candidate for …","Compare the advertised score with the current best. The …","","","Attempt to backtrack to the previously selected node’s …","The weight of the template transaction, including fixed …","","Returns the ExcessStrategy that results in the least waste.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","This is a variation of the Branch and Bound Coin Selection …","Current excess.","Current weight of template tx + selected inputs.","","","","Additional weight if we include the drain (change) output.","This is the effective target value.","Effective value of this input candidate: …","","","","","","Returns feerate in sats/wu.","","","","","","","","","","","","","Continue down this branch and skip the inclusion branch if …","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","The total number of inputs; so we can calculate extra …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Turns our Bnb state into an iterator.","","","Whether this WeightedValue contains at least one segwit …","","","The feerate","Additional leeway for the target value.","The minimum absolute fee. I.e., needed for RBF.","Minimum value allowed for a drain (change) output.","Creates a new Bnb.","Create a new WeightedValue that represents a single input.","","","","","","","","","","","","","","","","Absolute value sum of all selected inputs.","","Effective value sum of all selected inputs.","","Waste sum of all selected inputs.","Weight sum of all selected inputs.","","Weight of spending the drain (change) output in the future.","The feerate we should try and achieve in sats per weight …","The value we need to select. If the value is None, then …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Total value of the UTXO(s) that this WeightedValue …","","","","","","","","","","","","","","Total weight of including this/these UTXO(s). txin fields: …","",""],"i":[0,0,0,0,0,0,34,0,22,0,0,11,11,22,0,0,0,34,34,0,11,11,12,12,12,0,2,4,5,2,9,2,5,34,2,26,22,8,9,4,10,11,5,12,13,34,2,26,22,8,9,4,10,11,5,12,13,4,4,8,9,4,10,11,5,12,13,8,9,4,10,11,5,12,13,12,0,4,4,4,13,9,9,4,8,11,12,5,5,13,13,4,8,9,4,10,10,11,11,5,12,12,13,2,34,2,26,22,22,22,8,9,4,10,11,5,12,13,9,12,8,34,2,26,22,8,9,4,10,11,5,12,13,2,26,4,8,4,9,9,9,9,9,2,8,4,26,4,12,2,2,10,13,2,2,4,4,4,4,5,4,4,4,4,4,4,2,9,9,9,8,9,4,10,11,5,12,13,10,11,12,34,2,26,22,8,9,4,10,11,5,12,13,34,2,26,22,8,9,4,10,11,5,12,13,34,2,26,22,8,9,4,10,11,5,12,13,4,4,8,34,2,26,22,8,9,4,10,11,5,12,13,13,8,13,34],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[[2,[1]],1],3],[4,3],[5,6],[[[2,[1]]],3],0,0,[5],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[4,7],8],0,[8,8],[9,9],[4,4],[10,10],[11,11],[5,5],[12,12],[13,13],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[12,12],14],[4,[[15,[4]]]],[4,16],[4,17],[[4,7],3],0,[9,16],0,[4,16],[[8,18],16],[[11,11],3],[[12,12],3],0,0,0,[13,18],[4,[[19,[5,10]]]],[[8,20],21],[[9,20],21],[[4,20],21],[[10,20],21],[[10,20],21],[[11,20],21],[[11,20],21],[[5,20],21],[[12,20],21],[[12,20],21],[[13,20],21],[[[2,[1]],3]],[[]],[[]],[[]],[[]],[7,22],[23,22],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[24,17],9],[12],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[2,[1]],25],[[26,[1]]]],[[]],[4,3],0,[[4,7],3],[9,18],0,0,0,0,[[4,27,1],[[2,[1]]]],[[28,17,3],8],[[27,9],4],[[[26,[[0,[1,29,30]]]]],15],0,[[12,12],[[15,[14]]]],0,0,[31],0,0,0,[[4,7],3],[4],[4,[[19,[5,10]]]],[4,6],0,[4,28],[4,7],[4,16],[4,6],[4,16],[4,17],0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],32],[[],32],[[],32],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[4,6],[4,6],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,[34,3]],"p":[[8,"Ord"],[3,"Bnb"],[15,"bool"],[3,"CoinSelector"],[3,"Selection"],[8,"Iterator"],[15,"usize"],[3,"WeightedValue"],[3,"CoinSelectorOpt"],[3,"SelectionError"],[4,"SelectionConstraint"],[4,"ExcessStrategyKind"],[3,"ExcessStrategy"],[4,"Ordering"],[4,"Option"],[15,"i64"],[15,"u32"],[15,"f32"],[4,"Result"],[3,"Formatter"],[6,"Result"],[4,"BnbLimit"],[3,"Duration"],[3,"TxOut"],[6,"DecideStrategy"],[3,"BnbIter"],[3,"Vec"],[15,"u64"],[8,"Copy"],[8,"Display"],[3,"Demand"],[3,"String"],[3,"TypeId"],[4,"BranchStrategy"]]},\ "bdk_electrum":{"doc":"This crate is used for updating structures of bdk_chain …","t":[8,3,3,2,11,11,11,11,12,11,11,11,2,11,11,11,11,10,11,11,11,11,11,12,10,11,11,11,11,11,11,11,11,11],"n":["ElectrumExt","ElectrumUpdate","RelevantTxids","bdk_chain","borrow","borrow","borrow_mut","borrow_mut","chain_update","clone","clone_into","default","electrum_client","fmt","fmt","from","from","full_scan","into","into","into_confirmation_time_tx_graph","into_tx_graph","missing_full_txs","relevant_txids","sync","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip"],"q":["bdk_electrum","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Trait to extend Client functionality.","Combination of chain and transactions updates from electrum","Represents updates fetched from an Electrum server, but …","","","","","","Chain update","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Full scan the keychain scripts specified with the …","Calls U::from(self).","Calls U::from(self).","Finalizes the update by fetching missing txids from the …","Finalizes the TxGraph update by fetching missing txids …","Determine the full transactions that are missing from graph…","Transaction updates from electrum","Sync a set of scripts with the blockchain (via an Electrum …","","","","","","","","",""],"i":[0,0,0,0,1,4,1,4,4,1,1,1,0,1,4,1,4,20,1,4,1,1,1,4,20,1,1,4,1,4,1,4,1,4],"f":[0,0,0,0,[[]],[[]],[[]],[[]],0,[1,1],[[]],[[],1],0,[[1,2],3],[[4,2],3],[[]],[[]],[[5,[9,[[0,[6,7]],8]],10,10],[[12,[11]]]],[[]],[[]],[[1,13,[15,[14]]],[[12,[[17,[16]],11]]]],[[1,13,[15,[14]]],[[12,[[17,[18]],11]]]],[[1,17],[[15,[14]]]],0,[[5,8,8,8,10],[[12,[4,11]]]],[[]],[[],12],[[],12],[[],12],[[],12],[[],19],[[],19],[[]],[[]]],"p":[[3,"RelevantTxids"],[3,"Formatter"],[6,"Result"],[3,"ElectrumUpdate"],[3,"CheckPoint"],[8,"Ord"],[8,"Clone"],[8,"IntoIterator"],[3,"BTreeMap"],[15,"usize"],[4,"Error"],[4,"Result"],[3,"Client"],[3,"Txid"],[3,"Vec"],[3,"ConfirmationTimeHeightAnchor"],[3,"TxGraph"],[3,"ConfirmationHeightAnchor"],[3,"TypeId"],[8,"ElectrumExt"]]},\ "bdk_esplora":{"doc":"BDK Esplora","t":[8,8,2,10,10,10,10,10,10],"n":["EsploraAsyncExt","EsploraExt","esplora_client","full_scan","full_scan","sync","sync","update_local_chain","update_local_chain"],"q":["bdk_esplora","","","","","","","",""],"d":["Trait to extend the functionality of …","Trait to extend the functionality of …","","Full scan the keychain scripts specified with the …","Full scan the keychain scripts specified with the …","Sync a set of scripts with the blockchain (via an Esplora …","Sync a set of scripts with the blockchain (via an Esplora …","Prepare a LocalChain update with blocks fetched from …","Prepare a LocalChain update with blocks fetched from …"],"i":[0,0,0,16,17,16,17,16,17],"f":[0,0,0,[[[4,[[0,[1,2]],3]],5,5],[[8,[[7,[6]]]]]],[[[4,[[0,[3,9]]]],5,5],[[11,[[7,[10]]]]]],[[3,3,3,5],[[8,[[13,[12]],[7,[6]]]]]],[[[0,[3,9]],[0,[3,9]],[0,[3,9]],5],[[11,[[7,[10]]]]]],[[14,3],[[8,[15,[7,[6]]]]]],[[14,[0,[3,9]]],[[11,[[7,[10]]]]]]],"p":[[8,"Ord"],[8,"Clone"],[8,"IntoIterator"],[3,"BTreeMap"],[15,"usize"],[4,"Error"],[3,"Box"],[4,"Result"],[8,"Send"],[8,"Future"],[3,"Pin"],[3,"ConfirmationTimeHeightAnchor"],[3,"TxGraph"],[3,"CheckPoint"],[3,"Update"],[8,"EsploraExt"],[8,"EsploraAsyncExt"]]},\ diff --git a/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html b/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html index c87c12d338..5d854caab9 100644 --- a/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html +++ b/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html @@ -3619,7 +3619,7 @@ /// let (sent, received) = wallet.sent_and_received(tx); /// ``` pub fn sent_and_received(&self, tx: &Transaction) -> (u64, u64) { - self.indexed_graph.index.sent_and_received(tx) + self.indexed_graph.index.sent_and_received(tx, ..) } /// Get a single transaction from the wallet as a [`CanonicalTx`] (if the transaction exists). diff --git a/docs-rs/bdk/nightly/latest/src/bdk_chain/keychain/txout_index.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_chain/keychain/txout_index.rs.html index 8030c54013..697b205d2d 100644 --- a/docs-rs/bdk/nightly/latest/src/bdk_chain/keychain/txout_index.rs.html +++ b/docs-rs/bdk/nightly/latest/src/bdk_chain/keychain/txout_index.rs.html @@ -675,6 +675,15 @@ 675 676 677 +678 +679 +680 +681 +682 +683 +684 +685 +686
    use crate::{
         collections::*,
         indexed_tx_graph::Indexer,
    @@ -945,15 +954,14 @@
             self.inner.unmark_used(&(keychain, index))
         }
     
    -    /// Computes total input value going from script pubkeys in the index (sent) and the total output
    -    /// value going to script pubkeys in the index (received) in `tx`. For the `sent` to be computed
    -    /// correctly, the output being spent must have already been scanned by the index. Calculating
    -    /// received just uses the [`Transaction`] outputs directly, so it will be correct even if it has
    -    /// not been scanned.
    -    ///
    -    /// This calls [`SpkTxOutIndex::sent_and_received`] internally.
    -    pub fn sent_and_received(&self, tx: &Transaction) -> (u64, u64) {
    -        self.inner.sent_and_received(tx)
    +    /// Computes the total value transfer effect `tx` has on the script pubkeys belonging to the
    +    /// keychains in `range`. Value is *sent* when a script pubkey in the `range` is on an input and
    +    /// *received* when it is on an output. For `sent` to be computed correctly, the output being
    +    /// spent must have already been scanned by the index. Calculating received just uses the
    +    /// [`Transaction`] outputs directly, so it will be correct even if it has not been scanned.
    +    pub fn sent_and_received(&self, tx: &Transaction, range: impl RangeBounds<K>) -> (u64, u64) {
    +        self.inner
    +            .sent_and_received(tx, Self::map_to_inner_bounds(range))
         }
     
         /// Computes the net value that this transaction gives to the script pubkeys in the index and
    @@ -963,8 +971,8 @@
         /// This calls [`SpkTxOutIndex::net_value`] internally.
         ///
         /// [`sent_and_received`]: Self::sent_and_received
    -    pub fn net_value(&self, tx: &Transaction) -> i64 {
    -        self.inner.net_value(tx)
    +    pub fn net_value(&self, tx: &Transaction, range: impl RangeBounds<K>) -> i64 {
    +        self.inner.net_value(tx, Self::map_to_inner_bounds(range))
         }
     }
     
    @@ -1067,24 +1075,32 @@
                 .collect()
         }
     
    -    /// Iterate over revealed spks of all keychains.
    -    pub fn revealed_spks(&self) -> impl DoubleEndedIterator<Item = (K, u32, &Script)> + Clone {
    -        self.keychains.keys().flat_map(|keychain| {
    -            self.revealed_keychain_spks(keychain)
    -                .map(|(i, spk)| (keychain.clone(), i, spk))
    +    /// Iterate over revealed spks of keychains in `range`
    +    pub fn revealed_spks(
    +        &self,
    +        range: impl RangeBounds<K>,
    +    ) -> impl DoubleEndedIterator<Item = (&K, u32, &Script)> + Clone {
    +        self.keychains.range(range).flat_map(|(keychain, _)| {
    +            let start = Bound::Included((keychain.clone(), u32::MIN));
    +            let end = match self.last_revealed.get(keychain) {
    +                Some(last_revealed) => Bound::Included((keychain.clone(), *last_revealed)),
    +                None => Bound::Excluded((keychain.clone(), u32::MIN)),
    +            };
    +
    +            self.inner
    +                .all_spks()
    +                .range((start, end))
    +                .map(|((keychain, i), spk)| (keychain, *i, spk.as_script()))
             })
         }
     
         /// Iterate over revealed spks of the given `keychain`.
    -    pub fn revealed_keychain_spks(
    -        &self,
    -        keychain: &K,
    -    ) -> impl DoubleEndedIterator<Item = (u32, &Script)> + Clone {
    -        let next_i = self.last_revealed.get(keychain).map_or(0, |&i| i + 1);
    -        self.inner
    -            .all_spks()
    -            .range((keychain.clone(), u32::MIN)..(keychain.clone(), next_i))
    -            .map(|((_, i), spk)| (*i, spk.as_script()))
    +    pub fn revealed_keychain_spks<'a>(
    +        &'a self,
    +        keychain: &'a K,
    +    ) -> impl DoubleEndedIterator<Item = (u32, &Script)> + 'a {
    +        self.revealed_spks(keychain..=keychain)
    +            .map(|(_, i, spk)| (i, spk))
         }
     
         /// Iterate over revealed, but unused, spks of all keychains.
    @@ -1294,38 +1310,40 @@
             }
         }
     
    -    /// Iterate over all [`OutPoint`]s that point to `TxOut`s with script pubkeys derived from
    +    /// Iterate over all [`OutPoint`]s that have `TxOut`s with script pubkeys derived from
         /// `keychain`.
    -    ///
    -    /// Use [`keychain_outpoints_in_range`](KeychainTxOutIndex::keychain_outpoints_in_range) to
    -    /// iterate over a specific derivation range.
    -    pub fn keychain_outpoints(
    -        &self,
    -        keychain: &K,
    -    ) -> impl DoubleEndedIterator<Item = (u32, OutPoint)> + '_ {
    -        self.keychain_outpoints_in_range(keychain, ..)
    +    pub fn keychain_outpoints<'a>(
    +        &'a self,
    +        keychain: &'a K,
    +    ) -> impl DoubleEndedIterator<Item = (u32, OutPoint)> + 'a {
    +        self.keychain_outpoints_in_range(keychain..=keychain)
    +            .map(move |(_, i, op)| (i, op))
         }
     
    -    /// Iterate over [`OutPoint`]s that point to `TxOut`s with script pubkeys derived from
    -    /// `keychain` in a given derivation `range`.
    -    pub fn keychain_outpoints_in_range(
    -        &self,
    -        keychain: &K,
    -        range: impl RangeBounds<u32>,
    -    ) -> impl DoubleEndedIterator<Item = (u32, OutPoint)> + '_ {
    -        let start = match range.start_bound() {
    -            Bound::Included(i) => Bound::Included((keychain.clone(), *i)),
    -            Bound::Excluded(i) => Bound::Excluded((keychain.clone(), *i)),
    +    /// Iterate over [`OutPoint`]s that have script pubkeys derived from keychains in `range`.
    +    pub fn keychain_outpoints_in_range<'a>(
    +        &'a self,
    +        range: impl RangeBounds<K> + 'a,
    +    ) -> impl DoubleEndedIterator<Item = (&'a K, u32, OutPoint)> + 'a {
    +        let bounds = Self::map_to_inner_bounds(range);
    +        self.inner
    +            .outputs_in_range(bounds)
    +            .map(move |((keychain, i), op)| (keychain, *i, op))
    +    }
    +
    +    fn map_to_inner_bounds(bound: impl RangeBounds<K>) -> impl RangeBounds<(K, u32)> {
    +        let start = match bound.start_bound() {
    +            Bound::Included(keychain) => Bound::Included((keychain.clone(), u32::MIN)),
    +            Bound::Excluded(keychain) => Bound::Excluded((keychain.clone(), u32::MAX)),
                 Bound::Unbounded => Bound::Unbounded,
             };
    -        let end = match range.end_bound() {
    -            Bound::Included(i) => Bound::Included((keychain.clone(), *i)),
    -            Bound::Excluded(i) => Bound::Excluded((keychain.clone(), *i)),
    +        let end = match bound.end_bound() {
    +            Bound::Included(keychain) => Bound::Included((keychain.clone(), u32::MAX)),
    +            Bound::Excluded(keychain) => Bound::Excluded((keychain.clone(), u32::MIN)),
                 Bound::Unbounded => Bound::Unbounded,
             };
    -        self.inner
    -            .outputs_in_range((start, end))
    -            .map(|((_, i), op)| (*i, op))
    +
    +        (start, end)
         }
     
         /// Returns the highest derivation index of the `keychain` where [`KeychainTxOutIndex`] has
    diff --git a/docs-rs/bdk/nightly/latest/src/bdk_chain/spk_txout_index.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_chain/spk_txout_index.rs.html
    index 646799aea2..e9be613665 100644
    --- a/docs-rs/bdk/nightly/latest/src/bdk_chain/spk_txout_index.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/bdk_chain/spk_txout_index.rs.html
    @@ -322,6 +322,9 @@
     322
     323
     324
    +325
    +326
    +327
     
    use core::ops::RangeBounds;
     
     use crate::{
    @@ -594,36 +597,39 @@
             self.spk_indices.get(script)
         }
     
    -    /// Computes total input value going from script pubkeys in the index (sent) and the total output
    -    /// value going to script pubkeys in the index (received) in `tx`. For the `sent` to be computed
    -    /// correctly, the output being spent must have already been scanned by the index. Calculating
    -    /// received just uses the [`Transaction`] outputs directly, so it will be correct even if it has
    -    /// not been scanned.
    -    pub fn sent_and_received(&self, tx: &Transaction) -> (u64, u64) {
    +    /// Computes the total value transfer effect `tx` has on the script pubkeys in `range`. Value is
    +    /// *sent* when a script pubkey in the `range` is on an input and *received* when it is on an
    +    /// output. For `sent` to be computed correctly, the output being spent must have already been
    +    /// scanned by the index. Calculating received just uses the [`Transaction`] outputs directly,
    +    /// so it will be correct even if it has not been scanned.
    +    pub fn sent_and_received(&self, tx: &Transaction, range: impl RangeBounds<I>) -> (u64, u64) {
             let mut sent = 0;
             let mut received = 0;
     
             for txin in &tx.input {
    -            if let Some((_, txout)) = self.txout(txin.previous_output) {
    -                sent += txout.value.to_sat();
    +            if let Some((index, txout)) = self.txout(txin.previous_output) {
    +                if range.contains(index) {
    +                    sent += txout.value.to_sat();
    +                }
                 }
             }
             for txout in &tx.output {
    -            if self.index_of_spk(&txout.script_pubkey).is_some() {
    -                received += txout.value.to_sat();
    +            if let Some(index) = self.index_of_spk(&txout.script_pubkey) {
    +                if range.contains(index) {
    +                    received += txout.value.to_sat();
    +                }
                 }
             }
     
             (sent, received)
         }
     
    -    /// Computes the net value that this transaction gives to the script pubkeys in the index and
    -    /// *takes* from the transaction outputs in the index. Shorthand for calling
    -    /// [`sent_and_received`] and subtracting sent from received.
    +    /// Computes the net value transfer effect of `tx` on the script pubkeys in `range`. Shorthand
    +    /// for calling [`sent_and_received`] and subtracting sent from received.
         ///
         /// [`sent_and_received`]: Self::sent_and_received
    -    pub fn net_value(&self, tx: &Transaction) -> i64 {
    -        let (sent, received) = self.sent_and_received(tx);
    +    pub fn net_value(&self, tx: &Transaction, range: impl RangeBounds<I>) -> i64 {
    +        let (sent, received) = self.sent_and_received(tx, range);
             received as i64 - sent as i64
         }
     
    diff --git a/docs-rs/bdk/nightly/latest/src/example_electrum/main.rs.html b/docs-rs/bdk/nightly/latest/src/example_electrum/main.rs.html
    index d1310628d4..842c5754ac 100644
    --- a/docs-rs/bdk/nightly/latest/src/example_electrum/main.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/example_electrum/main.rs.html
    @@ -544,8 +544,8 @@
                 if all_spks {
                     let all_spks = graph
                         .index
    -                    .revealed_spks()
    -                    .map(|(k, i, spk)| (k, i, spk.to_owned()))
    +                    .revealed_spks(..)
    +                    .map(|(k, i, spk)| (k.to_owned(), i, spk.to_owned()))
                         .collect::<Vec<_>>();
                     spks = Box::new(spks.chain(all_spks.into_iter().map(|(k, i, spk)| {
                         eprintln!("scanning {}:{}", k, i);
    diff --git a/docs-rs/bdk/nightly/latest/src/example_esplora/main.rs.html b/docs-rs/bdk/nightly/latest/src/example_esplora/main.rs.html
    index 22643e6ee4..cd798db9bc 100644
    --- a/docs-rs/bdk/nightly/latest/src/example_esplora/main.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/example_esplora/main.rs.html
    @@ -599,8 +599,8 @@
                     if *all_spks {
                         let all_spks = graph
                             .index
    -                        .revealed_spks()
    -                        .map(|(k, i, spk)| (k, i, spk.to_owned()))
    +                        .revealed_spks(..)
    +                        .map(|(k, i, spk)| (k.to_owned(), i, spk.to_owned()))
                             .collect::<Vec<_>>();
                         spks = Box::new(spks.chain(all_spks.into_iter().map(|(k, i, spk)| {
                             eprintln!("scanning {}:{}", k, i);
    diff --git a/examples/index.html b/examples/index.html
    index d55135ff53..65ce0a08a7 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.

    - + diff --git a/foundation/index.html b/foundation/index.html index 61b3bfc58d..b39ff2e1f0 100644 --- a/foundation/index.html +++ b/foundation/index.html @@ -29,7 +29,7 @@ - + @@ -74,6 +74,6 @@
    - + diff --git a/getting-started/index.html b/getting-started/index.html index 8b8738bf55..1382d7e251 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).

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

    BDK Foundation
    - + diff --git a/index.html b/index.html index c9b159f5be..bab3ea2887 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 d4507be938..8bdb2a5235 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://bitcoindevkit.org/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q4-update/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics-multisig-2of3/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/bdk-core-pt1/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/bitcoin-core-rpc-demo/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/bdk-rn-making-of/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/bdk-with-tor/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/bindings-scope/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/compact-filters-demo/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/descriptors-in-the-wild/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/descriptor-based-paper-wallet/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-flutter/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-rn/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/getting-started-with-rust-hwi/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/hidden-power-of-bitcoin/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/hello-world/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/improving-coin-selection-in-bdk/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/miniscript-vulnerability/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/release-v0.2.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/release-v0.3.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/02/release-v0.4.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/03/release-v0.5.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/05/release-v0.7.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/07/release-v0.9.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/road-to-bdk-1/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/04/release-v0.6.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/2021/06/release-v0.8.0/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/spending-policy-demo/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/blog/using-bdk-with-hardware-wallets/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/compiler/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/concept/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/installation/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/interface/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/introduction/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/playground/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/bdk-cli/regtest/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/case-studies/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/descriptors/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/examples/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/getting-started/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/foundation/2024-04-15T20:13:59.000Zdailyhttps://bitcoindevkit.org/supporters/2024-04-15T20:13:59.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/tutorial/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/Bitcoin%20Core/dailyhttps://bitcoindevkit.org/blog/tags/RPC/dailyhttps://bitcoindevkit.org/blog/tags/Wallet/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/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/waterst0ne/dailyhttps://bitcoindevkit.org/blog/author/Lloyd%20Fournier/dailyhttps://bitcoindevkit.org/blog/author/Rajarshi%20Maitra/dailyhttps://bitcoindevkit.org/blog/author/Bitcoin%20Zavior/dailyhttps://bitcoindevkit.org/blog/author/rorp/dailyhttps://bitcoindevkit.org/blog/author/thunderbiscuit/dailyhttps://bitcoindevkit.org/blog/author/Gabriele%20Domenichini/dailyhttps://bitcoindevkit.org/blog/author/Riccardo%20Casatta/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/author/Alekos%20Filini/page/2/daily \ No newline at end of file +https://bitcoindevkit.org/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q4-update/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/bitcoin-core-rpc-demo/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics-multisig-2of3/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/bdk-core-pt1/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/bdk-rn-making-of/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/bdk-with-tor/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/bindings-scope/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/descriptor-based-paper-wallet/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/compact-filters-demo/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/descriptors-in-the-wild/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-flutter/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-rn/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/getting-started-with-rust-hwi/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/hello-world/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/hidden-power-of-bitcoin/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/improving-coin-selection-in-bdk/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/miniscript-vulnerability/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/release-v0.2.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/release-v0.3.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/02/release-v0.4.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/05/release-v0.7.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/03/release-v0.5.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/04/release-v0.6.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/06/release-v0.8.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/2021/07/release-v0.9.0/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/road-to-bdk-1/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/spending-policy-demo/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/blog/using-bdk-with-hardware-wallets/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/installation/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/compiler/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/concept/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/interface/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/introduction/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/playground/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/bdk-cli/regtest/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/descriptors/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/case-studies/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/examples/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/foundation/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/getting-started/2024-04-18T07:43:52.000Zdailyhttps://bitcoindevkit.org/supporters/2024-04-18T07:43:52.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/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/basics/dailyhttps://bitcoindevkit.org/blog/tags/novice/dailyhttps://bitcoindevkit.org/blog/tags/multi-sig/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/guide/dailyhttps://bitcoindevkit.org/blog/tags/descriptor/dailyhttps://bitcoindevkit.org/blog/tags/paper%20wallets/dailyhttps://bitcoindevkit.org/blog/tags/compact_filters/dailyhttps://bitcoindevkit.org/blog/tags/BIP157/dailyhttps://bitcoindevkit.org/blog/tags/Neutrino/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/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/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/thunderbiscuit/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/author/Alekos%20Filini/page/2/daily \ No newline at end of file diff --git a/supporters/index.html b/supporters/index.html index 9d8cebf79d..74803148da 100644 --- a/supporters/index.html +++ b/supporters/index.html @@ -29,7 +29,7 @@ - + @@ -63,7 +63,7 @@ Brink Sponsor Kraken Kraken -